mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'master' of git.labs.intellij.net:idea/community
This commit is contained in:
@@ -246,8 +246,8 @@ public class ExceptionUtil {
|
||||
unhandledExceptions = unhandled;
|
||||
}
|
||||
|
||||
if (element instanceof PsiResource) {
|
||||
final List<PsiClassType> unhandled = getUnhandledCloserExceptions((PsiResource)element, topElement);
|
||||
if (element instanceof PsiResourceVariable) {
|
||||
final List<PsiClassType> unhandled = getUnhandledCloserExceptions((PsiResourceVariable)element, topElement);
|
||||
if (unhandledExceptions == null) {
|
||||
unhandledExceptions = unhandled;
|
||||
}
|
||||
@@ -331,7 +331,7 @@ public class ExceptionUtil {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<PsiClassType> getUnhandledCloserExceptions(final PsiResource resource, final PsiElement topElement) {
|
||||
public static List<PsiClassType> getUnhandledCloserExceptions(final PsiResourceVariable resource, final PsiElement topElement) {
|
||||
final PsiType resourceType = resource.getType();
|
||||
if (resourceType instanceof PsiClassType) {
|
||||
final PsiClass resourceClass = ((PsiClassType)resourceType).resolve();
|
||||
|
||||
+2
-2
@@ -675,8 +675,8 @@ public class HighlightControlFlowUtil {
|
||||
@Nullable
|
||||
public static PsiClass getInnerClassVariableReferencedFrom(PsiVariable variable, PsiElement context) {
|
||||
PsiElement[] scope;
|
||||
if (variable instanceof PsiScopedLocalVariable) {
|
||||
scope = ((PsiScopedLocalVariable)variable).getDeclarationScope();
|
||||
if (variable instanceof PsiResourceVariable) {
|
||||
scope = ((PsiResourceVariable)variable).getDeclarationScope();
|
||||
}
|
||||
else if (variable instanceof PsiLocalVariable) {
|
||||
scope = new PsiElement[]{variable.getParent().getParent()}; // code block or for statement
|
||||
|
||||
@@ -435,7 +435,7 @@ public class HighlightUtil {
|
||||
@Nullable
|
||||
static HighlightInfo checkVariableInitializerType(PsiVariable variable) {
|
||||
PsiExpression initializer = variable.getInitializer();
|
||||
// array initalizer checked in checkArrayInitializerApplicable
|
||||
// array initializer checked in checkArrayInitializerApplicable
|
||||
if (initializer == null || initializer instanceof PsiArrayInitializerExpression) return null;
|
||||
PsiType lType = variable.getType();
|
||||
PsiType rType = initializer.getType();
|
||||
@@ -608,7 +608,9 @@ public class HighlightUtil {
|
||||
if (isIncorrect) {
|
||||
String description = JavaErrorMessages.message("variable.already.defined", name);
|
||||
HighlightInfo highlightInfo = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, identifier, description);
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, new ReuseVariableDeclarationFix(variable, identifier));
|
||||
if (!(variable instanceof PsiResourceVariable)) {
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, new ReuseVariableDeclarationFix(variable, identifier));
|
||||
}
|
||||
return highlightInfo;
|
||||
}
|
||||
return null;
|
||||
@@ -655,7 +657,7 @@ public class HighlightUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkUnhandledCloserExceptions(final PsiResource resource) {
|
||||
public static HighlightInfo checkUnhandledCloserExceptions(final PsiResourceVariable resource) {
|
||||
final List<PsiClassType> unhandled = ExceptionUtil.getUnhandledCloserExceptions(resource, null);
|
||||
if (unhandled.isEmpty()) return null;
|
||||
|
||||
@@ -1148,7 +1150,7 @@ public class HighlightUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkTryResourceIsAutoCloseable(@NotNull final PsiResource resource) {
|
||||
public static HighlightInfo checkTryResourceIsAutoCloseable(@NotNull final PsiResourceVariable resource) {
|
||||
final PsiType type = resource.getType();
|
||||
if (type == null) return null;
|
||||
|
||||
|
||||
+4
-5
@@ -906,11 +906,10 @@ 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));
|
||||
}
|
||||
public void visitResourceVariable(final PsiResourceVariable resourceVariable) {
|
||||
visitVariable(resourceVariable);
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkTryResourceIsAutoCloseable(resourceVariable));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkUnhandledCloserExceptions(resourceVariable));
|
||||
}
|
||||
|
||||
@Override public void visitTypeElement(PsiTypeElement type) {
|
||||
|
||||
+2
-11
@@ -57,7 +57,6 @@ public class ReuseVariableDeclarationFix implements IntentionAction {
|
||||
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 &&
|
||||
@@ -78,17 +77,9 @@ public class ReuseVariableDeclarationFix implements IntentionAction {
|
||||
}
|
||||
|
||||
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);
|
||||
final PsiElement statement = factory.createStatementFromText(myVariable.getName() + " = " + initializer.getText() + ";", null);
|
||||
myVariable.getParent().replace(statement);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -97,7 +97,7 @@ public class DefUseInspection extends BaseLocalInspectionTool {
|
||||
PsiElement context = info.getContext();
|
||||
PsiVariable psiVariable = info.getVariable();
|
||||
|
||||
if (context instanceof PsiDeclarationStatement || context instanceof PsiResource) {
|
||||
if (context instanceof PsiDeclarationStatement || context instanceof PsiResourceVariable) {
|
||||
if (!info.isRead()) {
|
||||
if (!isOnTheFly) {
|
||||
holder.registerProblem(psiVariable.getNameIdentifier(),
|
||||
|
||||
@@ -36,7 +36,7 @@ import static com.intellij.lang.java.parser.JavaParserUtil.exprType;
|
||||
|
||||
public class DeclarationParser {
|
||||
public enum Context {
|
||||
FILE, CLASS, CODE_BLOCK, ANNOTATION_INTERFACE, RESOURCE_LIST
|
||||
FILE, CLASS, CODE_BLOCK, ANNOTATION_INTERFACE
|
||||
}
|
||||
|
||||
private static final TokenSet AFTER_END_DECLARATION_SET = TokenSet.create(JavaElementType.FIELD, JavaElementType.METHOD);
|
||||
@@ -223,7 +223,7 @@ public class DeclarationParser {
|
||||
if (tokenType == null) return null;
|
||||
|
||||
if (tokenType == JavaTokenType.LBRACE) {
|
||||
if (context == Context.FILE || context == Context.CODE_BLOCK || context == Context.RESOURCE_LIST) return null;
|
||||
if (context == Context.FILE || context == Context.CODE_BLOCK) return null;
|
||||
}
|
||||
else if (tokenType == JavaTokenType.IDENTIFIER || ElementType.PRIMITIVE_TYPE_BIT_SET.contains(tokenType)) {
|
||||
if (context == Context.FILE) return null;
|
||||
@@ -235,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 || context == Context.RESOURCE_LIST || tokenType != JavaTokenType.LT)) {
|
||||
(context == Context.CODE_BLOCK || tokenType != JavaTokenType.LT)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -279,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 || context == Context.RESOURCE_LIST) {
|
||||
if (context == Context.CODE_BLOCK) {
|
||||
declaration.rollbackTo();
|
||||
return null;
|
||||
}
|
||||
@@ -302,10 +302,6 @@ 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();
|
||||
@@ -331,7 +327,7 @@ public class DeclarationParser {
|
||||
}
|
||||
|
||||
if (!expect(builder, JavaTokenType.IDENTIFIER)) {
|
||||
if ((context == Context.CODE_BLOCK || context == Context.RESOURCE_LIST) && modListInfo.second) {
|
||||
if ((context == Context.CODE_BLOCK) && modListInfo.second) {
|
||||
declaration.rollbackTo();
|
||||
return null;
|
||||
}
|
||||
@@ -473,11 +469,11 @@ public class DeclarationParser {
|
||||
PsiBuilder.Marker invalidElements = null;
|
||||
String errorMessage = null;
|
||||
boolean delimiterExpected = false;
|
||||
int elementCount = 0;
|
||||
boolean noElements = true;
|
||||
while (true) {
|
||||
final IElementType tokenType = builder.getTokenType();
|
||||
if (tokenType == null || tokenType == JavaTokenType.RPARENTH || tokenType == JavaTokenType.LBRACE) {
|
||||
boolean noLastElement = !delimiterExpected && elementCount > 0;
|
||||
final boolean noLastElement = !delimiterExpected && (!noElements && !resources || noElements && resources);
|
||||
if (noLastElement) {
|
||||
error(builder, JavaErrorMessages.message("expected.identifier.or.type"));
|
||||
}
|
||||
@@ -486,13 +482,10 @@ public class DeclarationParser {
|
||||
invalidElements.error(errorMessage);
|
||||
invalidElements = null;
|
||||
}
|
||||
else if (resources && elementCount == 0) {
|
||||
error(builder, JavaErrorMessages.message("expected.resource"));
|
||||
}
|
||||
builder.advanceLexer();
|
||||
}
|
||||
else {
|
||||
if (!noLastElement) {
|
||||
if (!noLastElement || resources) {
|
||||
if (invalidElements != null) {
|
||||
invalidElements.error(errorMessage);
|
||||
}
|
||||
@@ -522,7 +515,7 @@ public class DeclarationParser {
|
||||
invalidElements.errorBefore(errorMessage, listElement);
|
||||
invalidElements = null;
|
||||
}
|
||||
elementCount++;
|
||||
noElements= false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -531,6 +524,9 @@ public class DeclarationParser {
|
||||
if (builder.getTokenType() == delimiter) {
|
||||
error(builder, noElementMsg);
|
||||
builder.advanceLexer();
|
||||
if (noElements && resources) {
|
||||
noElements = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
@@ -556,6 +552,19 @@ public class DeclarationParser {
|
||||
|
||||
@Nullable
|
||||
public static PsiBuilder.Marker parseParameter(final PsiBuilder builder, final boolean ellipsis, final boolean disjunctiveType) {
|
||||
return parseListElement(builder, ellipsis, disjunctiveType, false);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiBuilder.Marker parseResource(final PsiBuilder builder) {
|
||||
return parseListElement(builder, false, false, true);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiBuilder.Marker parseListElement(final PsiBuilder builder,
|
||||
final boolean ellipsis,
|
||||
final boolean disjunctiveType,
|
||||
final boolean resource) {
|
||||
final PsiBuilder.Marker param = builder.mark();
|
||||
|
||||
final Pair<PsiBuilder.Marker, Boolean> modListInfo = parseModifierList(builder);
|
||||
@@ -577,34 +586,26 @@ public class DeclarationParser {
|
||||
}
|
||||
|
||||
if (expect(builder, JavaTokenType.IDENTIFIER)) {
|
||||
eatBrackets(builder, typeInfo != null && typeInfo.isVarArg, JavaErrorMessages.message("expected.rparen"));
|
||||
done(param, JavaElementType.PARAMETER);
|
||||
return param;
|
||||
if (!resource) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@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 (expectOrError(builder, JavaTokenType.EQ, JavaErrorMessages.message("expected.eq"))) {
|
||||
if (ExpressionParser.parse(builder) == null) {
|
||||
error(builder, JavaErrorMessages.message("expected.expression"));
|
||||
}
|
||||
}
|
||||
|
||||
if (element != null) {
|
||||
final PsiBuilder.Marker resource = element.precede();
|
||||
done(resource, JavaElementType.RESOURCE);
|
||||
return resource;
|
||||
}
|
||||
|
||||
return null;
|
||||
done(param, JavaElementType.RESOURCE_VARIABLE);
|
||||
return param;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -614,7 +615,7 @@ public class DeclarationParser {
|
||||
if (context == Context.CLASS || context == Context.ANNOTATION_INTERFACE) {
|
||||
varType = JavaElementType.FIELD;
|
||||
}
|
||||
else if (context == Context.CODE_BLOCK || context == Context.RESOURCE_LIST) {
|
||||
else if (context == Context.CODE_BLOCK) {
|
||||
varType = JavaElementType.LOCAL_VARIABLE;
|
||||
}
|
||||
else {
|
||||
@@ -645,11 +646,6 @@ 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;
|
||||
@@ -668,28 +664,26 @@ public class DeclarationParser {
|
||||
builder.advanceLexer();
|
||||
}
|
||||
|
||||
if (context != Context.RESOURCE_LIST) {
|
||||
if (builder.getTokenType() == JavaTokenType.SEMICOLON && eatSemicolon) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
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 (!unclosed) {
|
||||
error(builder, JavaErrorMessages.message("expected.semicolon"));
|
||||
}
|
||||
if (!unclosed) {
|
||||
error(builder, JavaErrorMessages.message("expected.semicolon"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1166,30 +1166,15 @@ class ControlFlowAnalyzer extends JavaJspElementVisitor {
|
||||
public void visitResourceList(final PsiResourceList resourceList) {
|
||||
startElement(resourceList);
|
||||
|
||||
final List<PsiResource> resources = resourceList.getResources();
|
||||
for (PsiResource resource : resources) {
|
||||
final List<PsiResourceVariable> resources = resourceList.getResourceVariables();
|
||||
for (PsiResourceVariable resource : resources) {
|
||||
ProgressManager.checkCanceled();
|
||||
resource.accept(this);
|
||||
processVariable(resource);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@@ -230,11 +230,10 @@ public class DefUseUtil {
|
||||
if (!defsArmed[i]) {
|
||||
PsiElement context = PsiTreeUtil.getNonStrictParentOfType(flow.getElement(i),
|
||||
PsiStatement.class, PsiAssignmentExpression.class,
|
||||
PsiPostfixExpression.class, PsiPrefixExpression.class,
|
||||
PsiResource.class);
|
||||
PsiPostfixExpression.class, PsiPrefixExpression.class);
|
||||
PsiVariable psiVariable = writeInstruction.variable;
|
||||
if (context != null && !(context instanceof PsiTryStatement)) {
|
||||
if (isDeclaration(context) && psiVariable.getInitializer() == null) {
|
||||
if (context instanceof PsiDeclarationStatement && psiVariable.getInitializer() == null) {
|
||||
if (!assignedVariables.contains(psiVariable)) {
|
||||
unusedDefs.add(new Info(psiVariable, context, false));
|
||||
}
|
||||
@@ -250,11 +249,6 @@ 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
|
||||
public static PsiElement[] getDefs(PsiCodeBlock body, final PsiVariable def, PsiElement ref) {
|
||||
try {
|
||||
|
||||
@@ -198,12 +198,9 @@ public class PsiImplUtil {
|
||||
@NotNull final PsiScopeProcessor processor,
|
||||
@NotNull final ResolveState state,
|
||||
final PsiElement lastParent) {
|
||||
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;
|
||||
final List<PsiResourceVariable> resources = resourceList.getResourceVariables();
|
||||
for (PsiResourceVariable resource : resources) {
|
||||
if (!resource.equals(lastParent) && !processor.execute(resource, state)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -259,13 +259,13 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiResource createResourceFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
public PsiResourceVariable 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)) {
|
||||
if (!(element instanceof PsiResourceVariable)) {
|
||||
throw new IncorrectOperationException("Incorrect resource \"" + text + "\".");
|
||||
}
|
||||
return (PsiResource)element;
|
||||
return (PsiResourceVariable)element;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -78,12 +78,6 @@ public class JavaModifierListElementType extends JavaStubElementType<PsiModifier
|
||||
return node.getTreeParent().getElementType() != JavaElementType.LOCAL_VARIABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldCreateStub(final LighterAST tree, final LighterASTNode node, final StubElement parentStub) {
|
||||
final LighterASTNode parent = tree.getParent(node);
|
||||
return parent != null && parent.getTokenType() != JavaElementType.LOCAL_VARIABLE;
|
||||
}
|
||||
|
||||
public PsiModifierListStub deserialize(final StubInputStream dataStream, final StubElement parentStub) throws IOException {
|
||||
return new PsiModifierListStubImpl(parentStub, dataStream.readVarInt());
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ public class JavaLightStubBuilder extends LightStubBuilder {
|
||||
|
||||
@Override
|
||||
public boolean skipChildProcessingWhenBuildingStubs(final IElementType nodeType, final IElementType childType) {
|
||||
return childType == JavaElementType.PARAMETER_LIST && nodeType != JavaElementType.METHOD && nodeType != JavaElementType.ANNOTATION_METHOD ||
|
||||
childType == JavaElementType.PARAMETER && nodeType != JavaElementType.PARAMETER_LIST;
|
||||
return childType == JavaElementType.PARAMETER && nodeType != JavaElementType.PARAMETER_LIST ||
|
||||
childType == JavaElementType.MODIFIER_LIST && (nodeType == JavaElementType.LOCAL_VARIABLE || nodeType == JavaElementType.RESOURCE_VARIABLE);
|
||||
}
|
||||
}
|
||||
@@ -177,9 +177,8 @@ 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;
|
||||
else if (parent instanceof PsiResourceVariable) {
|
||||
if (type == JavaTokenType.FINAL_KEYWORD) return true;
|
||||
}
|
||||
|
||||
if (type == null) { // package local
|
||||
|
||||
@@ -128,7 +128,7 @@ public interface JavaElementType {
|
||||
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 RESOURCE_VARIABLE = new JavaCompositeElementType("RESOURCE_VARIABLE", PsiResourceVariableImpl.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);
|
||||
|
||||
+8
-19
@@ -49,13 +49,17 @@ import org.jetbrains.annotations.NotNull;
|
||||
import javax.swing.*;
|
||||
import java.util.Set;
|
||||
|
||||
public class PsiLocalVariableImpl extends CompositePsiElement implements PsiScopedLocalVariable, PsiVariableEx, Constants {
|
||||
public class PsiLocalVariableImpl extends CompositePsiElement implements PsiLocalVariable, PsiVariableEx, Constants {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiLocalVariableImpl");
|
||||
|
||||
private volatile String myCachedName = null;
|
||||
|
||||
public PsiLocalVariableImpl() {
|
||||
super(LOCAL_VARIABLE);
|
||||
this(LOCAL_VARIABLE);
|
||||
}
|
||||
|
||||
protected PsiLocalVariableImpl(final IElementType type) {
|
||||
super(type);
|
||||
}
|
||||
|
||||
public void clearCaches() {
|
||||
@@ -279,21 +283,6 @@ public class PsiLocalVariableImpl extends CompositePsiElement implements PsiScop
|
||||
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)) {
|
||||
@@ -321,8 +310,8 @@ public class PsiLocalVariableImpl extends CompositePsiElement implements PsiScop
|
||||
}
|
||||
|
||||
final PsiElement parentElement = getParent();
|
||||
if (parentElement instanceof PsiDeclarationStatement || parentElement instanceof PsiResource) {
|
||||
return new LocalSearchScope(getDeclarationScope());
|
||||
if (parentElement instanceof PsiDeclarationStatement) {
|
||||
return new LocalSearchScope(parentElement.getParent());
|
||||
}
|
||||
else {
|
||||
return getManager().getFileManager().getUseScope(this);
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
@@ -32,8 +32,8 @@ public class PsiResourceListImpl extends CompositePsiElement implements PsiResou
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<PsiResource> getResources() {
|
||||
return PsiTreeUtil.getChildrenOfTypeAsList(this, PsiResource.class);
|
||||
public List<PsiResourceVariable> getResourceVariables() {
|
||||
return PsiTreeUtil.getChildrenOfTypeAsList(this, PsiResourceVariable.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.source.tree.JavaElementType;
|
||||
import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class PsiResourceVariableImpl extends PsiLocalVariableImpl implements PsiResourceVariable {
|
||||
public PsiResourceVariableImpl() {
|
||||
super(JavaElementType.RESOURCE_VARIABLE);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiElement[] getDeclarationScope() {
|
||||
final PsiResourceList resourceList = (PsiResourceList)getParent();
|
||||
final PsiTryStatement tryStatement = (PsiTryStatement)resourceList.getParent();
|
||||
final PsiCodeBlock tryBlock = tryStatement.getTryBlock();
|
||||
return tryBlock != null ? new PsiElement[]{resourceList, tryBlock} : new PsiElement[]{resourceList};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiTypeElement getTypeElement() {
|
||||
return PsiTreeUtil.getRequiredChildOfType(this, PsiTypeElement.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiModifierList getModifierList() {
|
||||
return PsiTreeUtil.getChildOfType(this, PsiModifierList.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(@NotNull final PsiElementVisitor visitor) {
|
||||
if (visitor instanceof JavaElementVisitor) {
|
||||
((JavaElementVisitor)visitor).visitResourceVariable(this);
|
||||
}
|
||||
else {
|
||||
visitor.visitElement(this);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public SearchScope getUseScope() {
|
||||
return new LocalSearchScope(getDeclarationScope());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PsiResourceVariable:" + getName();
|
||||
}
|
||||
}
|
||||
@@ -15,9 +15,11 @@
|
||||
*/
|
||||
package com.intellij.unscramble;
|
||||
|
||||
import com.intellij.Patches;
|
||||
import com.intellij.openapi.application.ApplicationAdapter;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.wm.IdeFrame;
|
||||
import com.intellij.util.Alarm;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -29,16 +31,29 @@ public class UnscrambleListener extends ApplicationAdapter {
|
||||
private String stacktrace = null;
|
||||
|
||||
@Override
|
||||
public void applicationActivated(IdeFrame ideFrame) {
|
||||
final String clipboard = AnalyzeStacktraceUtil.getTextInClipboard();
|
||||
if (clipboard != null && clipboard.length() < MAX_STACKTRACE_SIZE && !clipboard.equals(stacktrace)) {
|
||||
stacktrace = clipboard;
|
||||
final Project project = ideFrame.getProject();
|
||||
if (project != null && isStacktrace(stacktrace)) {
|
||||
final UnscrambleDialog dialog = new UnscrambleDialog(project);
|
||||
dialog.createNormalizeTextAction().actionPerformed(null);
|
||||
dialog.doOKAction();
|
||||
public void applicationActivated(final IdeFrame ideFrame) {
|
||||
final Runnable processClipboard = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final String clipboard = AnalyzeStacktraceUtil.getTextInClipboard();
|
||||
if (clipboard != null && clipboard.length() < MAX_STACKTRACE_SIZE && !clipboard.equals(stacktrace)) {
|
||||
stacktrace = clipboard;
|
||||
final Project project = ideFrame.getProject();
|
||||
if (project != null && isStacktrace(stacktrace)) {
|
||||
final UnscrambleDialog dialog = new UnscrambleDialog(project);
|
||||
dialog.createNormalizeTextAction().actionPerformed(null);
|
||||
dialog.doOKAction();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (Patches.SLOW_GETTING_CLIPBOARD_CONTENTS) {
|
||||
//IDEA's clipboard is synchronized with the system clipboard on frame activation so we need to postpone clipboard processing
|
||||
new Alarm().addRequest(processClipboard, 300);
|
||||
}
|
||||
else {
|
||||
processClipboard.run();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-8
@@ -14,24 +14,22 @@ class C {
|
||||
try (MyResource r = new MyResource()) { r.doSomething(); }
|
||||
catch (E1 | E2 | E3 ignore) { }
|
||||
|
||||
try (new MyResource()) { }
|
||||
try (MyResource r = new MyResource()) { }
|
||||
catch (E1 | E3 ignore) { }
|
||||
|
||||
MyResource r;
|
||||
|
||||
try (<error descr="Unhandled exception from auto-closeable resource: C.E3">r = new MyResource()</error>) { }
|
||||
try (<error descr="Unhandled exception from auto-closeable resource: C.E3">MyResource r = new MyResource()</error>) { }
|
||||
catch (E1 e) { }
|
||||
|
||||
try (r = <error descr="Unhandled exception: C.E1">new MyResource()</error>) { }
|
||||
try (MyResource r = <error descr="Unhandled exception: C.E1">new MyResource()</error>) { }
|
||||
catch (E3 e) { }
|
||||
|
||||
try (r = <error descr="Unhandled exception: C.E1">new MyResource()</error>) { }
|
||||
try (MyResource r = <error descr="Unhandled exception: C.E1">new MyResource()</error>) { }
|
||||
}
|
||||
|
||||
void m2() throws Exception {
|
||||
try (<error descr="Incompatible types. Found: 'java.lang.Object', required: 'java.lang.AutoCloseable'">Object r = new MyResource()</error>) { }
|
||||
|
||||
try (<error descr="Incompatible types. Found: 'java.lang.String', required: 'java.lang.AutoCloseable'">"resource"</error>) { }
|
||||
try (<error descr="Incompatible types. Found: 'java.lang.String', required: 'java.lang.AutoCloseable'">AutoCloseable r = "resource"</error>) { }
|
||||
}
|
||||
|
||||
void m3(int p) throws Exception {
|
||||
@@ -56,7 +54,7 @@ class C {
|
||||
|
||||
MyResource r = null;
|
||||
try (MyResource <error descr="Variable 'r' is already defined in the scope">r</error> = new MyResource()) { }
|
||||
try (r = new MyResource()) { }
|
||||
try (MyResource rr = r) { }
|
||||
|
||||
try (MyResource <error descr="Variable 'p' is already defined in the scope">p</error> = new MyResource()) { }
|
||||
new Runnable() {
|
||||
|
||||
+12
-19
@@ -6,35 +6,28 @@ class C {
|
||||
}
|
||||
|
||||
void m1() throws Exception {
|
||||
MyResource r1;
|
||||
try (r1 = new MyResource()) {
|
||||
try (MyResource r1 = new MyResource()) {
|
||||
System.out.println(r1);
|
||||
}
|
||||
|
||||
try (MyResource r2 = new MyResource()) {
|
||||
System.out.println(r2);
|
||||
}
|
||||
|
||||
MyResource r3 = new MyResource();
|
||||
try (MyResource r = r3) {
|
||||
MyResource r2 = new MyResource();
|
||||
try (MyResource r = r2) {
|
||||
System.out.println(r);
|
||||
System.out.println(r2);
|
||||
}
|
||||
}
|
||||
|
||||
void m2() throws Exception {
|
||||
MyResource r1 = <warning descr="Variable 'r1' initializer 'null' is redundant">null</warning>;
|
||||
try (r1 = new MyResource()) {
|
||||
System.out.println(r1);
|
||||
}
|
||||
// todo: test in IG
|
||||
//MyResource < warning descr="Local variable 'r1' is redundant">r1</warning> = null;
|
||||
//try (MyResource r = r1) {
|
||||
// System.out.println(r);
|
||||
//}
|
||||
|
||||
MyResource r2 = null;
|
||||
System.out.println(r2);
|
||||
try (r2 = <warning descr="The value 'new MyResource()' assigned to r2 is never used">new MyResource()</warning>) { }
|
||||
try (MyResource <warning descr="Variable 'r2' is never used">r2</warning> = new MyResource()) { }
|
||||
|
||||
try (MyResource <warning descr="Variable 'r3' is never used">r3</warning> = new MyResource()) { }
|
||||
|
||||
MyResource <warning descr="Variable 'r4' is never assigned">r4</warning>;
|
||||
try (MyResource r = <error descr="Variable 'r4' might not have been initialized">r4</error>) {
|
||||
MyResource <warning descr="Variable 'r3' is never assigned">r3</warning>;
|
||||
try (MyResource r = <error descr="Variable 'r3' might not have been initialized">r3</error>) {
|
||||
System.out.println(r);
|
||||
}
|
||||
}
|
||||
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
// "Reuse previous variable 'r' declaration" "true"
|
||||
import java.io.*;
|
||||
|
||||
class a {
|
||||
static class MyResource implements AutoCloseable {
|
||||
public void close() { }
|
||||
}
|
||||
|
||||
void m() {
|
||||
MyResource r;
|
||||
try (r = new MyResource()) {
|
||||
}
|
||||
}
|
||||
}
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
// "Reuse previous variable 'r' declaration" "true"
|
||||
import java.io.*;
|
||||
|
||||
class a {
|
||||
static class MyResource implements AutoCloseable {
|
||||
public void close() { }
|
||||
}
|
||||
|
||||
void m() {
|
||||
MyResource r;
|
||||
try (MyResource <caret>r = new MyResource()) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,8 @@ PsiJavaFile:TryIncomplete10.java
|
||||
PsiKeyword:try('try')
|
||||
PsiResourceList:(
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiErrorElement:Identifier or type expected
|
||||
<empty list>
|
||||
PsiErrorElement:')' expected
|
||||
<empty list>
|
||||
PsiCodeBlock
|
||||
|
||||
@@ -3,7 +3,7 @@ PsiJavaFile:TryIncomplete11.java
|
||||
PsiKeyword:try('try')
|
||||
PsiResourceList:()
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiErrorElement:Resource definition expected
|
||||
PsiErrorElement:Identifier or type expected
|
||||
<empty list>
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiCodeBlock
|
||||
|
||||
@@ -6,8 +6,6 @@ PsiJavaFile:TryIncomplete12.java
|
||||
PsiErrorElement:Resource definition expected
|
||||
<empty list>
|
||||
PsiJavaToken:SEMICOLON(';')
|
||||
PsiErrorElement:Resource definition expected
|
||||
<empty list>
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiCodeBlock
|
||||
PsiJavaToken:LBRACE('{')
|
||||
|
||||
@@ -5,9 +5,13 @@ PsiJavaFile:TryIncomplete13.java
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiModifierList:final
|
||||
PsiKeyword:final('final')
|
||||
PsiErrorElement:Identifier or type expected
|
||||
PsiErrorElement:Type expected
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiTypeElement:
|
||||
<empty list>
|
||||
PsiErrorElement:Identifier expected
|
||||
<empty list>
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiCodeBlock
|
||||
PsiJavaToken:LBRACE('{')
|
||||
|
||||
@@ -3,8 +3,12 @@ PsiJavaFile:TryIncomplete14.java
|
||||
PsiKeyword:try('try')
|
||||
PsiResourceList:(int)
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiErrorElement:Resource definition expected
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeElement:int
|
||||
PsiKeyword:int('int')
|
||||
PsiErrorElement:Identifier expected
|
||||
<empty list>
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiCodeBlock
|
||||
PsiJavaToken:LBRACE('{')
|
||||
|
||||
@@ -3,19 +3,18 @@ PsiJavaFile:TryIncomplete15.java
|
||||
PsiKeyword:try('try')
|
||||
PsiResourceList:(R r)
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiResource:r
|
||||
PsiLocalVariable:r
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeElement:R
|
||||
PsiJavaCodeReferenceElement:R
|
||||
PsiIdentifier:R('R')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:r('r')
|
||||
PsiErrorElement:'=' expected
|
||||
<empty list>
|
||||
PsiResourceVariable:r
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeElement:R
|
||||
PsiJavaCodeReferenceElement:R
|
||||
PsiIdentifier:R('R')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:r('r')
|
||||
PsiErrorElement:'=' expected
|
||||
<empty list>
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiCodeBlock
|
||||
PsiJavaToken:LBRACE('{')
|
||||
|
||||
@@ -3,21 +3,20 @@ PsiJavaFile:TryIncomplete16.java
|
||||
PsiKeyword:try('try')
|
||||
PsiResourceList:(R r =)
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiResource:r
|
||||
PsiLocalVariable:r
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeElement:R
|
||||
PsiJavaCodeReferenceElement:R
|
||||
PsiIdentifier:R('R')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:r('r')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:EQ('=')
|
||||
PsiErrorElement:Expression expected
|
||||
<empty list>
|
||||
PsiResourceVariable:r
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeElement:R
|
||||
PsiJavaCodeReferenceElement:R
|
||||
PsiIdentifier:R('R')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:r('r')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:EQ('=')
|
||||
PsiErrorElement:Expression expected
|
||||
<empty list>
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiCodeBlock
|
||||
PsiJavaToken:LBRACE('{')
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
PsiJavaFile:TryIncomplete17.java
|
||||
PsiTryStatement
|
||||
PsiKeyword:try('try')
|
||||
PsiResourceList:(R r = 0;)
|
||||
PsiResourceList:(R r = 0;;)
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiResource:r
|
||||
PsiLocalVariable:r
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeElement:R
|
||||
PsiJavaCodeReferenceElement:R
|
||||
PsiIdentifier:R('R')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:r('r')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:EQ('=')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiLiteralExpression:0
|
||||
PsiJavaToken:INTEGER_LITERAL('0')
|
||||
PsiResourceVariable:r
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeElement:R
|
||||
PsiJavaCodeReferenceElement:R
|
||||
PsiIdentifier:R('R')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:r('r')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:EQ('=')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiLiteralExpression:0
|
||||
PsiJavaToken:INTEGER_LITERAL('0')
|
||||
PsiJavaToken:SEMICOLON(';')
|
||||
PsiErrorElement:Identifier or type expected
|
||||
PsiErrorElement:Resource definition expected
|
||||
<empty list>
|
||||
PsiJavaToken:SEMICOLON(';')
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiCodeBlock
|
||||
PsiJavaToken:LBRACE('{')
|
||||
|
||||
@@ -3,22 +3,21 @@ PsiJavaFile:TryNormal4.java
|
||||
PsiKeyword:try('try')
|
||||
PsiResourceList:(R r = 0)
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiResource:r
|
||||
PsiLocalVariable:r
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeElement:R
|
||||
PsiJavaCodeReferenceElement:R
|
||||
PsiIdentifier:R('R')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:r('r')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:EQ('=')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiLiteralExpression:0
|
||||
PsiJavaToken:INTEGER_LITERAL('0')
|
||||
PsiResourceVariable:r
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeElement:R
|
||||
PsiJavaCodeReferenceElement:R
|
||||
PsiIdentifier:R('R')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:r('r')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:EQ('=')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiLiteralExpression:0
|
||||
PsiJavaToken:INTEGER_LITERAL('0')
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiCodeBlock
|
||||
PsiJavaToken:LBRACE('{')
|
||||
|
||||
@@ -3,40 +3,38 @@ PsiJavaFile:TryNormal5.java
|
||||
PsiKeyword:try('try')
|
||||
PsiResourceList:(R1 r1 = 1; R2 r2 = 2)
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiResource:r1
|
||||
PsiLocalVariable:r1
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeElement:R1
|
||||
PsiJavaCodeReferenceElement:R1
|
||||
PsiIdentifier:R1('R1')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:r1('r1')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:EQ('=')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiLiteralExpression:1
|
||||
PsiJavaToken:INTEGER_LITERAL('1')
|
||||
PsiResourceVariable:r1
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeElement:R1
|
||||
PsiJavaCodeReferenceElement:R1
|
||||
PsiIdentifier:R1('R1')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:r1('r1')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:EQ('=')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiLiteralExpression:1
|
||||
PsiJavaToken:INTEGER_LITERAL('1')
|
||||
PsiJavaToken:SEMICOLON(';')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiResource:r2
|
||||
PsiLocalVariable:r2
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeElement:R2
|
||||
PsiJavaCodeReferenceElement:R2
|
||||
PsiIdentifier:R2('R2')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:r2('r2')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:EQ('=')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiLiteralExpression:2
|
||||
PsiJavaToken:INTEGER_LITERAL('2')
|
||||
PsiResourceVariable:r2
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeElement:R2
|
||||
PsiJavaCodeReferenceElement:R2
|
||||
PsiIdentifier:R2('R2')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:r2('r2')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:EQ('=')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiLiteralExpression:2
|
||||
PsiJavaToken:INTEGER_LITERAL('2')
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiCodeBlock
|
||||
PsiJavaToken:LBRACE('{')
|
||||
|
||||
@@ -1,13 +1,24 @@
|
||||
PsiJavaFile:TryNormal6.java
|
||||
PsiTryStatement
|
||||
PsiKeyword:try('try')
|
||||
PsiResourceList:(r)
|
||||
PsiResourceList:(R r = 0;)
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiResource:
|
||||
PsiReferenceExpression:r
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiIdentifier:r('r')
|
||||
PsiResourceVariable:r
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeElement:R
|
||||
PsiJavaCodeReferenceElement:R
|
||||
PsiIdentifier:R('R')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:r('r')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:EQ('=')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiLiteralExpression:0
|
||||
PsiJavaToken:INTEGER_LITERAL('0')
|
||||
PsiJavaToken:SEMICOLON(';')
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiCodeBlock
|
||||
PsiJavaToken:LBRACE('{')
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
PsiJavaFile:TryNormal7.java
|
||||
PsiTryStatement
|
||||
PsiKeyword:try('try')
|
||||
PsiResourceList:(r; null)
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiResource:
|
||||
PsiReferenceExpression:r
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiIdentifier:r('r')
|
||||
PsiJavaToken:SEMICOLON(';')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiResource:
|
||||
PsiLiteralExpression:null
|
||||
PsiJavaToken:NULL_KEYWORD('null')
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiCodeBlock
|
||||
PsiJavaToken:LBRACE('{')
|
||||
PsiJavaToken:RBRACE('}')
|
||||
+2
-1
@@ -32,7 +32,7 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase {
|
||||
|
||||
@Override
|
||||
protected LocalInspectionTool[] configureLocalInspectionTools() {
|
||||
return new LocalInspectionTool[]{new UnusedSymbolLocalInspection(), new UncheckedWarningLocalInspection(), new DefUseInspection()};
|
||||
return new LocalInspectionTool[]{new UnusedSymbolLocalInspection(), new UncheckedWarningLocalInspection()};
|
||||
}
|
||||
|
||||
public void testDuplicateAnnotations() throws Exception {
|
||||
@@ -194,6 +194,7 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase {
|
||||
}
|
||||
|
||||
public void testTryWithResourcesWarn() throws Exception {
|
||||
enableInspectionTool(new DefUseInspection());
|
||||
doTest(true, false);
|
||||
}
|
||||
|
||||
|
||||
+2
-3
@@ -122,8 +122,7 @@ public class StatementParserTest extends JavaParsingTestCase {
|
||||
public void testTryNormal3() { doParserTestJDK7("try{}catch(A|B e){}"); }
|
||||
public void testTryNormal4() { doParserTestJDK7("try(R r = 0){}"); }
|
||||
public void testTryNormal5() { doParserTestJDK7("try(R1 r1 = 1; R2 r2 = 2){}"); }
|
||||
public void testTryNormal6() { doParserTestJDK7("try(r){}"); }
|
||||
public void testTryNormal7() { doParserTestJDK7("try(r; null){}"); }
|
||||
public void testTryNormal6() { doParserTestJDK7("try(R r = 0;){}"); }
|
||||
public void testTryIncomplete0() { doParserTest("try"); }
|
||||
public void testTryIncomplete1() { doParserTest("try{}"); }
|
||||
public void testTryIncomplete2() { doParserTest("try{}catch"); }
|
||||
@@ -141,7 +140,7 @@ public class StatementParserTest extends JavaParsingTestCase {
|
||||
public void testTryIncomplete14() { doParserTestJDK7("try(int){}"); }
|
||||
public void testTryIncomplete15() { doParserTestJDK7("try(R r){}"); }
|
||||
public void testTryIncomplete16() { doParserTestJDK7("try(R r =){}"); }
|
||||
public void testTryIncomplete17() { doParserTestJDK7("try(R r = 0;){}"); }
|
||||
public void testTryIncomplete17() { doParserTestJDK7("try(R r = 0;;){}"); }
|
||||
|
||||
public void testWhileNormal() { doParserTest("while (true) foo();"); }
|
||||
public void testWhileIncomplete0() { doParserTest("while"); }
|
||||
|
||||
@@ -17,6 +17,9 @@ package com.intellij.psi;
|
||||
|
||||
import com.intellij.lang.FileASTNode;
|
||||
import com.intellij.openapi.application.ex.PathManagerEx;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.projectRoots.impl.JavaSdkImpl;
|
||||
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.impl.DebugUtil;
|
||||
@@ -39,6 +42,12 @@ public class JavaStubBuilderTest extends LightIdeaTestCase {
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
doTest("@interface A { int i() default 42; }\n class C { void m(int p) throws E { } }", null); // warm up
|
||||
LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.JDK_1_7);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Sdk getProjectJDK() {
|
||||
return JavaSdkImpl.getMockJdk17();
|
||||
}
|
||||
|
||||
public void testEmpty() {
|
||||
@@ -255,6 +264,9 @@ public class JavaStubBuilderTest extends LightIdeaTestCase {
|
||||
" int local = 0;\n" +
|
||||
" for (int loop = 0; loop < 10; loop++) ;\n" +
|
||||
" try (Resource r = new Resource()) { }\n" +
|
||||
" try (Resource r = new Resource() {\n" +
|
||||
" public void close() { }\n" +
|
||||
" }) { }\n" +
|
||||
" }\n" +
|
||||
"}",
|
||||
|
||||
@@ -269,32 +281,34 @@ public class JavaStubBuilderTest extends LightIdeaTestCase {
|
||||
" MODIFIER_LIST:PsiModifierListStub[mask=4096]\n" +
|
||||
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
|
||||
" PARAMETER_LIST:PsiParameterListStub\n" +
|
||||
" THROWS_LIST:PsiRefListStub[THROWS_LIST:]\n");
|
||||
" THROWS_LIST:PsiRefListStub[THROWS_LIST:]\n" +
|
||||
" ANONYMOUS_CLASS:PsiClassStub[anonymous name=null fqn=null baseref=Resource]\n" +
|
||||
" METHOD:PsiMethodStub[close:void]\n" +
|
||||
" MODIFIER_LIST:PsiModifierListStub[mask=1]\n" +
|
||||
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
|
||||
" PARAMETER_LIST:PsiParameterListStub\n" +
|
||||
" THROWS_LIST:PsiRefListStub[THROWS_LIST:]\n");
|
||||
}
|
||||
|
||||
public void testNonListParameters() {
|
||||
withLevel(LanguageLevel.JDK_1_7, new Runnable() {
|
||||
@Override public void run() {
|
||||
doTest("class C {\n" +
|
||||
" {\n" +
|
||||
" for (int i : arr) ;\n" +
|
||||
" try { }\n" +
|
||||
" catch (Throwable t) { }\n" +
|
||||
" catch (E1|E2 e) { }\n" +
|
||||
" }\n" +
|
||||
"}",
|
||||
doTest("class C {\n" +
|
||||
" {\n" +
|
||||
" for (int i : arr) ;\n" +
|
||||
" try { }\n" +
|
||||
" catch (Throwable t) { }\n" +
|
||||
" catch (E1|E2 e) { }\n" +
|
||||
" }\n" +
|
||||
"}",
|
||||
|
||||
"PsiJavaFileStub []\n" +
|
||||
" IMPORT_LIST:PsiImportListStub\n" +
|
||||
" CLASS:PsiClassStub[name=C fqn=C]\n" +
|
||||
" MODIFIER_LIST:PsiModifierListStub[mask=4096]\n" +
|
||||
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
|
||||
" EXTENDS_LIST:PsiRefListStub[EXTENDS_LIST:]\n" +
|
||||
" IMPLEMENTS_LIST:PsiRefListStub[IMPLEMENTS_LIST:]\n" +
|
||||
" CLASS_INITIALIZER:PsiClassInitializerStub\n" +
|
||||
" MODIFIER_LIST:PsiModifierListStub[mask=4096]\n");
|
||||
}
|
||||
});
|
||||
"PsiJavaFileStub []\n" +
|
||||
" IMPORT_LIST:PsiImportListStub\n" +
|
||||
" CLASS:PsiClassStub[name=C fqn=C]\n" +
|
||||
" MODIFIER_LIST:PsiModifierListStub[mask=4096]\n" +
|
||||
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
|
||||
" EXTENDS_LIST:PsiRefListStub[EXTENDS_LIST:]\n" +
|
||||
" IMPLEMENTS_LIST:PsiRefListStub[IMPLEMENTS_LIST:]\n" +
|
||||
" CLASS_INITIALIZER:PsiClassInitializerStub\n" +
|
||||
" MODIFIER_LIST:PsiModifierListStub[mask=4096]\n");
|
||||
}
|
||||
|
||||
public void testSOEProof() {
|
||||
|
||||
@@ -300,8 +300,8 @@ public abstract class JavaElementVisitor extends PsiElementVisitor {
|
||||
visitElement(resourceList);
|
||||
}
|
||||
|
||||
public void visitResource(PsiResource resource) {
|
||||
visitElement(resource);
|
||||
public void visitResourceVariable(PsiResourceVariable resourceVariable) {
|
||||
visitLocalVariable(resourceVariable);
|
||||
}
|
||||
|
||||
public void visitTypeElement(PsiTypeElement type) {
|
||||
|
||||
@@ -125,7 +125,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade {
|
||||
* @throws com.intellij.util.IncorrectOperationException if the text is not a valid resource definition.
|
||||
*/
|
||||
@NotNull
|
||||
PsiResource createResourceFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException;
|
||||
PsiResourceVariable createResourceFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException;
|
||||
|
||||
/**
|
||||
* Creates a Java type from the specified text.
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Represents a resource list of try-with-resources statement (automatic resource management) introduced in JDK 7.
|
||||
*
|
||||
* @see PsiResourceList#getResources()
|
||||
* @since 10.5.
|
||||
*/
|
||||
public interface PsiResource extends PsiElement {
|
||||
/**
|
||||
* Returns main element of the resource.
|
||||
* It may be PsiLocalVariable, PsiAssignmentExpression, or other instance of PsiExpression.
|
||||
*
|
||||
* @return resource element.
|
||||
*/
|
||||
@NotNull
|
||||
PsiElement getResourceElement();
|
||||
|
||||
@Nullable
|
||||
PsiType getType();
|
||||
}
|
||||
@@ -27,5 +27,5 @@ import java.util.List;
|
||||
*/
|
||||
public interface PsiResourceList extends PsiElement {
|
||||
@NotNull
|
||||
List<PsiResource> getResources();
|
||||
List<PsiResourceVariable> getResourceVariables();
|
||||
}
|
||||
|
||||
+7
-6
@@ -17,12 +17,13 @@ package com.intellij.psi;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface PsiScopedLocalVariable extends PsiLocalVariable {
|
||||
/**
|
||||
* Returns the element or elements (method, "for" statement or try block) in which the variable is declared.
|
||||
*
|
||||
* @return the declaration scope for the variable.
|
||||
*/
|
||||
/**
|
||||
* Represents a resource variable of try-with-resources statement (automatic resource management) introduced in JDK 7.
|
||||
*
|
||||
* @see PsiResourceList#getResourceVariables()
|
||||
* @since 10.5.
|
||||
*/
|
||||
public interface PsiResourceVariable extends PsiLocalVariable {
|
||||
@NotNull
|
||||
PsiElement[] getDeclarationScope();
|
||||
}
|
||||
@@ -29,8 +29,6 @@ import com.intellij.ide.ui.UISettings;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
import com.intellij.openapi.editor.SelectionModel;
|
||||
import com.intellij.openapi.editor.colors.EditorFontType;
|
||||
import com.intellij.openapi.editor.event.SelectionEvent;
|
||||
import com.intellij.openapi.editor.event.SelectionListener;
|
||||
@@ -108,7 +106,6 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
|
||||
|
||||
private boolean myIsReplace;
|
||||
private boolean myListeningSelection = false;
|
||||
private boolean myToChangeSelection = true;
|
||||
private SearchResults mySearchResults;
|
||||
private Balloon myOptionsBalloon;
|
||||
|
||||
@@ -129,59 +126,40 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
|
||||
int count = sr.getActualFound();
|
||||
if (mySearchField.getText().isEmpty()) {
|
||||
nothingToSearchFor();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (count <= mySearchResults.getMatchesLimit()) {
|
||||
myClickToHighlightLabel.setVisible(false);
|
||||
|
||||
if (count <= mySearchResults.getMatchesLimit()) {
|
||||
myClickToHighlightLabel.setVisible(false);
|
||||
|
||||
if (count > 0) {
|
||||
setRegularBackground();
|
||||
if (count > 1) {
|
||||
myMatchInfoLabel.setText(count + " matches");
|
||||
if (count > 0) {
|
||||
setRegularBackground();
|
||||
if (count > 1) {
|
||||
myMatchInfoLabel.setText(count + " matches");
|
||||
}
|
||||
else {
|
||||
myMatchInfoLabel.setText("1 match");
|
||||
}
|
||||
}
|
||||
else {
|
||||
myMatchInfoLabel.setText("1 match");
|
||||
setNotFoundBackground();
|
||||
myMatchInfoLabel.setText("No matches");
|
||||
}
|
||||
}
|
||||
else {
|
||||
setNotFoundBackground();
|
||||
myMatchInfoLabel.setText("No matches");
|
||||
setRegularBackground();
|
||||
myMatchInfoLabel.setText("More than " + mySearchResults.getMatchesLimit() + " matches");
|
||||
myClickToHighlightLabel.setVisible(true);
|
||||
boldMatchInfo();
|
||||
}
|
||||
}
|
||||
else {
|
||||
setRegularBackground();
|
||||
myMatchInfoLabel.setText("More than " + mySearchResults.getMatchesLimit() + " matches");
|
||||
myClickToHighlightLabel.setVisible(true);
|
||||
boldMatchInfo();
|
||||
}
|
||||
|
||||
updateSelection();
|
||||
updateExcludeStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cursorMoved() {
|
||||
updateSelection();
|
||||
updateExcludeStatus();
|
||||
}
|
||||
|
||||
private void updateSelection() {
|
||||
SelectionModel selection = myEditor.getSelectionModel();
|
||||
if (myToChangeSelection && (mySelectionOnly == null || !mySelectionOnly.isSelected())) {
|
||||
LiveOccurrence cursor = mySearchResults.getCursor();
|
||||
if (cursor != null) {
|
||||
TextRange range = cursor.getPrimaryRange();
|
||||
selection.setSelection(range.getStartOffset(), range.getEndOffset());
|
||||
|
||||
myEditor.getCaretModel().moveToOffset(range.getEndOffset());
|
||||
myEditor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
|
||||
|
||||
}
|
||||
myToChangeSelection = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void editorChanged(SearchResults sr, Editor oldEditor) { }
|
||||
|
||||
@@ -580,14 +558,13 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
|
||||
}
|
||||
|
||||
private void searchBackward() {
|
||||
moveCursor(false);
|
||||
moveCursor(SearchResults.Direction.UP);
|
||||
|
||||
addCurrentTextToRecents();
|
||||
}
|
||||
|
||||
private void searchForward() {
|
||||
moveCursor(true);
|
||||
|
||||
moveCursor(SearchResults.Direction.DOWN);
|
||||
addCurrentTextToRecents();
|
||||
}
|
||||
|
||||
@@ -603,13 +580,8 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
|
||||
updateResults(true);
|
||||
}
|
||||
|
||||
public void moveCursor(boolean forwardOrBackward) {
|
||||
myToChangeSelection = true;
|
||||
if (forwardOrBackward) {
|
||||
mySearchResults.nextOccurrence();
|
||||
} else {
|
||||
mySearchResults.prevOccurrence();
|
||||
}
|
||||
public void moveCursor(SearchResults.Direction direction) {
|
||||
myLivePreviewController.moveCursor(direction, true);
|
||||
}
|
||||
|
||||
public void replaceCurrent() {
|
||||
@@ -660,7 +632,7 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
|
||||
myEditor.getDocument().addDocumentListener(myDocumentListener);
|
||||
|
||||
if (myLivePreview != null) {
|
||||
myLivePreviewController.updateInBackground(mySearchResults.getFindModel());
|
||||
myLivePreviewController.updateInBackground(mySearchResults.getFindModel(), false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -727,11 +699,7 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
|
||||
model.setGlobal(!mySelectionOnly.isSelected());
|
||||
model.setPreserveCase(myPreserveCase.isEnabled() && myPreserveCase.isSelected());
|
||||
}
|
||||
if (!myToChangeSelection) {
|
||||
myToChangeSelection = allowedToChangedEditorSelection;
|
||||
}
|
||||
|
||||
myLivePreviewController.updateInBackground(model);
|
||||
myLivePreviewController.updateInBackground(model, allowedToChangedEditorSelection);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1006,13 +974,6 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
|
||||
mySearchField.requestFocus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextRange performReplace(LiveOccurrence occurrence, String replacement, Editor editor) {
|
||||
myToChangeSelection = true;
|
||||
return super
|
||||
.performReplace(occurrence, replacement, editor); //To change body of overridden methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
public void performReplace() {
|
||||
String replacement = getStringToReplace(myEditor, mySearchResults.getCursor());
|
||||
performReplace(mySearchResults.getCursor(), replacement, myEditor);
|
||||
|
||||
@@ -766,7 +766,7 @@ public class FindUtil {
|
||||
}
|
||||
});
|
||||
}
|
||||
}, null, document);
|
||||
}, null, null);
|
||||
return startOffset + converted.length();
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.intellij.codeInsight.hint.HintManagerImpl;
|
||||
import com.intellij.codeInsight.hint.HintUtil;
|
||||
import com.intellij.find.*;
|
||||
import com.intellij.find.findUsages.FindUsagesManager;
|
||||
import com.intellij.find.impl.livePreview.SearchResults;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.LanguageParserDefinitions;
|
||||
import com.intellij.lang.ParserDefinition;
|
||||
@@ -655,7 +656,7 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo
|
||||
}
|
||||
}
|
||||
|
||||
private boolean tryToFindNextUsageViaEditorSearchComponent(Editor editor, boolean forwardOrBackward) {
|
||||
private boolean tryToFindNextUsageViaEditorSearchComponent(Editor editor, SearchResults.Direction forwardOrBackward) {
|
||||
if (editor.getHeaderComponent() instanceof EditorSearchComponent) {
|
||||
EditorSearchComponent searchComponent = (EditorSearchComponent)editor.getHeaderComponent();
|
||||
if (searchComponent.hasMatches()) {
|
||||
@@ -670,7 +671,7 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo
|
||||
if (fileEditor instanceof TextEditor) {
|
||||
TextEditor textEditor = (TextEditor)fileEditor;
|
||||
Editor editor = textEditor.getEditor();
|
||||
if (tryToFindNextUsageViaEditorSearchComponent(editor, true)) {
|
||||
if (tryToFindNextUsageViaEditorSearchComponent(editor, SearchResults.Direction.DOWN)) {
|
||||
return true;
|
||||
}
|
||||
FindModel model = getFindNextModel(editor);
|
||||
@@ -689,7 +690,7 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo
|
||||
if (fileEditor instanceof TextEditor) {
|
||||
TextEditor textEditor = (TextEditor)fileEditor;
|
||||
Editor editor = textEditor.getEditor();
|
||||
if (tryToFindNextUsageViaEditorSearchComponent(editor, false)) {
|
||||
if (tryToFindNextUsageViaEditorSearchComponent(editor, SearchResults.Direction.UP)) {
|
||||
return true;
|
||||
}
|
||||
FindModel model = getFindNextModel(editor);
|
||||
|
||||
+51
-2
@@ -6,6 +6,8 @@ import com.intellij.find.FindUtil;
|
||||
import com.intellij.find.impl.FindResultImpl;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
import com.intellij.openapi.editor.SelectionModel;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.util.Alarm;
|
||||
@@ -13,7 +15,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class LivePreviewControllerBase implements LivePreview.Delegate, FindUtil.ReplaceDelegate {
|
||||
public class LivePreviewControllerBase implements LivePreview.Delegate, FindUtil.ReplaceDelegate, SearchResults.SearchResultsListener {
|
||||
|
||||
private static final String EMPTY_STRING_DISPLAY_TEXT = "<Empty string>";
|
||||
|
||||
@@ -26,6 +28,48 @@ public class LivePreviewControllerBase implements LivePreview.Delegate, FindUtil
|
||||
private SearchResults mySearchResults;
|
||||
private LivePreview myLivePreview;
|
||||
|
||||
private boolean myToChangeSelection = true;
|
||||
|
||||
private void updateSelection() {
|
||||
Editor editor = mySearchResults.getEditor();
|
||||
SelectionModel selection = editor.getSelectionModel();
|
||||
FindModel findModel = mySearchResults.getFindModel();
|
||||
if (myToChangeSelection && findModel.isGlobal()) {
|
||||
LiveOccurrence cursor = mySearchResults.getCursor();
|
||||
if (cursor != null) {
|
||||
TextRange range = cursor.getPrimaryRange();
|
||||
selection.setSelection(range.getStartOffset(), range.getEndOffset());
|
||||
|
||||
editor.getCaretModel().moveToOffset(range.getEndOffset());
|
||||
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
|
||||
|
||||
}
|
||||
myToChangeSelection = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void searchResultsUpdated(SearchResults sr) {
|
||||
updateSelection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void editorChanged(SearchResults sr, Editor oldEditor) {}
|
||||
|
||||
@Override
|
||||
public void cursorMoved() {
|
||||
updateSelection();
|
||||
}
|
||||
|
||||
public void moveCursor(SearchResults.Direction direction, boolean toChangeSelection) {
|
||||
myToChangeSelection = toChangeSelection;
|
||||
if (direction == SearchResults.Direction.UP) {
|
||||
mySearchResults.prevOccurrence();
|
||||
} else {
|
||||
mySearchResults.nextOccurrence();
|
||||
}
|
||||
}
|
||||
|
||||
public interface ReplaceListener {
|
||||
void replacePerformed(LiveOccurrence occurrence, final String replacement, final Editor editor);
|
||||
void replaceAllPerformed(Editor e);
|
||||
@@ -43,6 +87,7 @@ public class LivePreviewControllerBase implements LivePreview.Delegate, FindUtil
|
||||
|
||||
public LivePreviewControllerBase(SearchResults searchResults, LivePreview livePreview) {
|
||||
mySearchResults = searchResults;
|
||||
mySearchResults.addListener(this);
|
||||
myLivePreview = livePreview;
|
||||
myLivePreview.setDelegate(this);
|
||||
}
|
||||
@@ -55,7 +100,7 @@ public class LivePreviewControllerBase implements LivePreview.Delegate, FindUtil
|
||||
myUserActivityDelay = userActivityDelay;
|
||||
}
|
||||
|
||||
public void updateInBackground(final FindModel findModel) {
|
||||
public void updateInBackground(final FindModel findModel, boolean allowedToChangedEditorSelection) {
|
||||
myLivePreviewAlarm.cancelAllRequests();
|
||||
if (findModel == null) return;
|
||||
Runnable request = new Runnable() {
|
||||
@@ -69,6 +114,9 @@ public class LivePreviewControllerBase implements LivePreview.Delegate, FindUtil
|
||||
} else {
|
||||
myLivePreviewAlarm.addRequest(request, myUserActivityDelay);
|
||||
}
|
||||
if (allowedToChangedEditorSelection) {
|
||||
myToChangeSelection = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -99,6 +147,7 @@ public class LivePreviewControllerBase implements LivePreview.Delegate, FindUtil
|
||||
@Nullable
|
||||
@Override
|
||||
public TextRange performReplace(final LiveOccurrence occurrence, final String replacement, final Editor editor) {
|
||||
myToChangeSelection = true;
|
||||
TextRange range = occurrence.getPrimaryRange();
|
||||
FindModel findModel = mySearchResults.getFindModel();
|
||||
TextRange result = null;
|
||||
|
||||
@@ -19,6 +19,8 @@ import java.util.List;
|
||||
|
||||
public class SearchResults {
|
||||
|
||||
public enum Direction {UP, DOWN}
|
||||
|
||||
private int myActualFound = 0;
|
||||
|
||||
private List<SearchResultsListener> myListeners = new ArrayList<SearchResultsListener>();
|
||||
@@ -293,6 +295,8 @@ public class SearchResults {
|
||||
for (LiveOccurrence searchResult : getOccurrences()) {
|
||||
if (searchResult.getPrimaryRange().intersects(oldCursorRange)) {
|
||||
mayBeOldCursor = searchResult;
|
||||
}
|
||||
if (searchResult.getPrimaryRange().equals(oldCursorRange)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -658,7 +658,8 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
|
||||
return markupModel;
|
||||
}
|
||||
|
||||
if (project.isDisposed()) {
|
||||
final DocumentMarkupModelManager documentMarkupModelManager = project.isDisposed() ? null : DocumentMarkupModelManager.getInstance(project);
|
||||
if (documentMarkupModelManager == null || documentMarkupModelManager.isDisposed() || project.isDisposed()) {
|
||||
return new EmptyMarkupModel(this);
|
||||
}
|
||||
|
||||
@@ -669,15 +670,7 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
|
||||
if (model == null) {
|
||||
model = new MarkupModelImpl(this);
|
||||
myProjectToMarkupModelMap.put(project, model);
|
||||
Disposer.register(project, new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
MarkupModelImpl removed = myProjectToMarkupModelMap.remove(project);
|
||||
if (removed != null) {
|
||||
removed.dispose();
|
||||
}
|
||||
}
|
||||
});
|
||||
documentMarkupModelManager.registerDocument(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -685,6 +678,13 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
|
||||
return model;
|
||||
}
|
||||
|
||||
void removeMarkupModel(@NotNull Project project) {
|
||||
MarkupModelImpl removed = myProjectToMarkupModelMap.remove(project);
|
||||
if (removed != null) {
|
||||
removed.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public void setCyclicBufferSize(int bufferSize) {
|
||||
myText.setBufferSize(bufferSize);
|
||||
}
|
||||
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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.openapi.editor.impl;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.components.AbstractProjectComponent;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.util.containers.WeakList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
public class DocumentMarkupModelManager extends AbstractProjectComponent {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.DocumentMarkupModelManager");
|
||||
|
||||
private final WeakList<DocumentImpl> myDocumentSet = new WeakList<DocumentImpl>();
|
||||
private volatile boolean myDisposed;
|
||||
|
||||
public static DocumentMarkupModelManager getInstance(Project project) {
|
||||
return project.getComponent(DocumentMarkupModelManager.class);
|
||||
}
|
||||
|
||||
public DocumentMarkupModelManager(@NotNull Project project) {
|
||||
super(project);
|
||||
Disposer.register(project, new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
cleanupProjectMarkups();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void registerDocument(DocumentImpl document) {
|
||||
LOG.assertTrue(!myDisposed);
|
||||
myDocumentSet.add(document);
|
||||
}
|
||||
|
||||
public boolean isDisposed() {
|
||||
return myDisposed;
|
||||
}
|
||||
|
||||
private void cleanupProjectMarkups() {
|
||||
if (!myDisposed) {
|
||||
myDisposed = true;
|
||||
for (DocumentImpl document : myDocumentSet.toStrongList()) {
|
||||
document.removeMarkupModel(myProject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,9 @@
|
||||
<!--<component>-->
|
||||
<!--<implementation-class>com.intellij.jsp.impl.browserprofile.BrowserProfileProvider</implementation-class>-->
|
||||
<!--</component>-->
|
||||
<component>
|
||||
<implementation-class>com.intellij.openapi.editor.impl.DocumentMarkupModelManager</implementation-class>
|
||||
</component>
|
||||
<component>
|
||||
<implementation-class>com.intellij.openapi.fileEditor.impl.EditorHistoryManager</implementation-class>
|
||||
<option name="workspace" value="true"/>
|
||||
@@ -32,4 +35,4 @@
|
||||
</component>
|
||||
|
||||
</project-components>
|
||||
</components>
|
||||
</components>
|
||||
@@ -83,6 +83,17 @@ public class MostlySingularMultiMap<K, V> {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return myMap.size();
|
||||
}
|
||||
|
||||
public int valuesForKey(K key) {
|
||||
Object current = myMap.get(key);
|
||||
if (current == null) return 0;
|
||||
if (current instanceof Object[]) return ((Object[])current).length;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Iterable<V> get(K name) {
|
||||
final Object value = myMap.get(name);
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @author max
|
||||
*/
|
||||
package com.intellij.util.io;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class CompactDataInput implements DataInput {
|
||||
private final InputStream in;
|
||||
private final byte[] readBuffer = IOUtil.allocReadWriteUTFBuffer();
|
||||
|
||||
public CompactDataInput(InputStream in) {
|
||||
this.in = in;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFully(byte[] b) throws IOException {
|
||||
readFully(b, 0, b.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFully(byte[] b, int off, int len) throws IOException {
|
||||
if (len < 0)
|
||||
throw new IndexOutOfBoundsException();
|
||||
int n = 0;
|
||||
while (n < len) {
|
||||
int count = in.read(b, off + n, len - n);
|
||||
if (count < 0)
|
||||
throw new EOFException();
|
||||
n += count;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int skipBytes(int n) throws IOException {
|
||||
int total = 0;
|
||||
int cur = 0;
|
||||
|
||||
while ((total<n) && ((cur = (int) in.skip(n-total)) > 0)) {
|
||||
total += cur;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean readBoolean() throws IOException {
|
||||
int ch = in.read();
|
||||
if (ch < 0)
|
||||
throw new EOFException();
|
||||
return (ch != 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte readByte() throws IOException {
|
||||
int ch = in.read();
|
||||
if (ch < 0)
|
||||
throw new EOFException();
|
||||
return (byte)(ch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readUnsignedByte() throws IOException {
|
||||
int ch = in.read();
|
||||
if (ch < 0)
|
||||
throw new EOFException();
|
||||
return ch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public short readShort() throws IOException {
|
||||
int ch1 = in.read();
|
||||
int ch2 = in.read();
|
||||
if ((ch1 | ch2) < 0)
|
||||
throw new EOFException();
|
||||
return (short)((ch1 << 8) + (ch2 << 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readUnsignedShort() throws IOException {
|
||||
int ch1 = in.read();
|
||||
int ch2 = in.read();
|
||||
if ((ch1 | ch2) < 0)
|
||||
throw new EOFException();
|
||||
return (ch1 << 8) + (ch2 << 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public char readChar() throws IOException {
|
||||
int ch1 = in.read();
|
||||
int ch2 = in.read();
|
||||
if ((ch1 | ch2) < 0)
|
||||
throw new EOFException();
|
||||
return (char)((ch1 << 8) + (ch2 << 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readInt() throws IOException {
|
||||
return DataInputOutputUtil.readINT(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long readLong() throws IOException { // TODO: Make longs actually compact
|
||||
readFully(readBuffer, 0, 8);
|
||||
return (((long)readBuffer[0] << 56) +
|
||||
((long)(readBuffer[1] & 255) << 48) +
|
||||
((long)(readBuffer[2] & 255) << 40) +
|
||||
((long)(readBuffer[3] & 255) << 32) +
|
||||
((long)(readBuffer[4] & 255) << 24) +
|
||||
((readBuffer[5] & 255) << 16) +
|
||||
((readBuffer[6] & 255) << 8) +
|
||||
((readBuffer[7] & 255) << 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public float readFloat() throws IOException {
|
||||
return Float.intBitsToFloat(readInt());
|
||||
}
|
||||
|
||||
@Override
|
||||
public double readDouble() throws IOException {
|
||||
return Double.longBitsToDouble(readLong());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readLine() throws IOException {
|
||||
throw new UnsupportedOperationException("readLine is not implemented!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readUTF() throws IOException {
|
||||
return IOUtil.readUTFFast(readBuffer, this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @author max
|
||||
*/
|
||||
package com.intellij.util.io;
|
||||
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class CompactDataOutput implements DataOutput {
|
||||
private final OutputStream out;
|
||||
private final byte[] writeBuffer = IOUtil.allocReadWriteUTFBuffer();
|
||||
|
||||
public CompactDataOutput(OutputStream out) {
|
||||
this.out = out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
out.write(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] b) throws IOException {
|
||||
out.write(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
out.write(b, off, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBoolean(boolean v) throws IOException {
|
||||
out.write(v ? 1 : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeByte(int v) throws IOException {
|
||||
out.write(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeShort(int v) throws IOException {
|
||||
out.write((v >>> 8) & 0xFF);
|
||||
out.write(v & 0xFF);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeChar(int v) throws IOException {
|
||||
out.write((v >>> 8) & 0xFF);
|
||||
out.write(v & 0xFF);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeInt(int val) throws IOException {
|
||||
DataInputOutputUtil.writeINT(this, val);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeLong(long v) throws IOException { // TODO: Make longs actually compact
|
||||
writeBuffer[0] = (byte)(v >>> 56);
|
||||
writeBuffer[1] = (byte)(v >>> 48);
|
||||
writeBuffer[2] = (byte)(v >>> 40);
|
||||
writeBuffer[3] = (byte)(v >>> 32);
|
||||
writeBuffer[4] = (byte)(v >>> 24);
|
||||
writeBuffer[5] = (byte)(v >>> 16);
|
||||
writeBuffer[6] = (byte)(v >>> 8);
|
||||
writeBuffer[7] = (byte)(v >>> 0);
|
||||
out.write(writeBuffer, 0, 8);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeFloat(float v) throws IOException {
|
||||
writeInt(Float.floatToIntBits(v));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDouble(double v) throws IOException {
|
||||
writeLong(Double.doubleToLongBits(v));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBytes(String s) throws IOException {
|
||||
int len = s.length();
|
||||
for (int i = 0 ; i < len ; i++) {
|
||||
out.write((byte)s.charAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeChars(String s) throws IOException {
|
||||
int len = s.length();
|
||||
for (int i = 0 ; i < len ; i++) {
|
||||
int v = s.charAt(i);
|
||||
out.write((v >>> 8) & 0xFF);
|
||||
out.write((v >>> 0) & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeUTF(String s) throws IOException {
|
||||
IOUtil.writeUTFFast(writeBuffer, this, s);
|
||||
}
|
||||
}
|
||||
@@ -889,7 +889,7 @@ octal.literal.problem.descriptor=Octal integer <code>#ref</code> #loc
|
||||
implicit.call.to.super.problem.descriptor=Implicit call to super() <code>#ref</code> #loc
|
||||
negated.if.else.problem.descriptor=<code>#ref</code> statement with negated condition #loc
|
||||
negated.conditional.problem.descriptor=Conditional expression with negated condition #loc
|
||||
confusing.else.problem.descriptor=<code>#ref</code> branch may be unwrapped, as the if branch never completes #loc
|
||||
confusing.else.problem.descriptor=<code>#ref</code> branch may be unwrapped, as the 'if' branch never completes #loc
|
||||
switch.statement.with.confusing.declaration.problem.descriptor=Local variable <code>#ref</code> declared in one 'switch' branch and used in another #loc
|
||||
raw.use.of.parameterized.type.problem.descriptor=Raw use of parameterized class <code>#ref</code> #loc
|
||||
final.class.problem.descriptor=Class declared <code>#ref</code> #loc
|
||||
@@ -1856,3 +1856,4 @@ if.can.be.switch.enum.option=Suggest switch on enum
|
||||
unnecessarily.qualified.inner.class.access.option=Ignore references to foreign inner classes
|
||||
unqualified.inner.class.access.option=Ignore references to local inner classes
|
||||
try.with.identical.catches.quickfix=Collapse catch blocks into multi-catch
|
||||
confusing.else.option=<html>Also report when there are no more statements after the 'if' statement</html>
|
||||
|
||||
+52
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2007 Dave Griffith, Bas Leijdekkers
|
||||
* Copyright 2003-2011 Dave Griffith, Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.siyeh.ig.controlflow;
|
||||
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
@@ -29,28 +30,45 @@ import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class ConfusingElseInspection extends BaseInspection {
|
||||
|
||||
@SuppressWarnings({"PublicField"})
|
||||
public boolean reportWhenNoStatementFollow = false;
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getID() {
|
||||
return "ConfusingElseBranch";
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getDisplayName() {
|
||||
return InspectionGadgetsBundle.message("confusing.else.display.name");
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
protected String buildErrorString(Object... infos) {
|
||||
return InspectionGadgetsBundle.message(
|
||||
"confusing.else.problem.descriptor");
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent createOptionsPanel() {
|
||||
return new SingleCheckboxOptionsPanel(
|
||||
InspectionGadgetsBundle.message("confusing.else.option"),
|
||||
this, "reportWhenNoStatementFollow");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseInspectionVisitor buildVisitor() {
|
||||
return new ConfusingElseVisitor();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
protected InspectionGadgetsFix buildFix(Object... infos) {
|
||||
return new ConfusingElseFix();
|
||||
@@ -64,6 +82,7 @@ public class ConfusingElseInspection extends BaseInspection {
|
||||
"confusing.else.unwrap.quickfix");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFix(Project project, ProblemDescriptor descriptor)
|
||||
throws IncorrectOperationException {
|
||||
final PsiElement ifKeyword = descriptor.getPsiElement();
|
||||
@@ -108,10 +127,11 @@ public class ConfusingElseInspection extends BaseInspection {
|
||||
}
|
||||
}
|
||||
|
||||
private static class ConfusingElseVisitor
|
||||
private class ConfusingElseVisitor
|
||||
extends BaseInspectionVisitor {
|
||||
|
||||
@Override public void visitIfStatement(@NotNull PsiIfStatement statement) {
|
||||
@Override public void visitIfStatement(
|
||||
@NotNull PsiIfStatement statement) {
|
||||
super.visitIfStatement(statement);
|
||||
final PsiStatement thenBranch = statement.getThenBranch();
|
||||
if (thenBranch == null) {
|
||||
@@ -127,16 +147,17 @@ public class ConfusingElseInspection extends BaseInspection {
|
||||
if (ControlFlowUtils.statementMayCompleteNormally(thenBranch)) {
|
||||
return;
|
||||
}
|
||||
final PsiStatement nextStatement =
|
||||
PsiTreeUtil.getNextSiblingOfType(statement,
|
||||
PsiStatement.class);
|
||||
if (nextStatement == null) {
|
||||
return;
|
||||
}
|
||||
if (!ControlFlowUtils.statementMayCompleteNormally(elseBranch)) {
|
||||
return;
|
||||
//protecting against an edge case where both branches return
|
||||
// and are followed by a case label
|
||||
if (reportWhenNoStatementFollow) {
|
||||
final PsiStatement nextStatement = getNextStatement(statement);
|
||||
if (nextStatement == null) {
|
||||
return;
|
||||
}
|
||||
if (!ControlFlowUtils.statementMayCompleteNormally(
|
||||
elseBranch)) {
|
||||
return;
|
||||
// protecting against an edge case where both branches return
|
||||
// and are followed by a case label
|
||||
}
|
||||
}
|
||||
final PsiElement elseToken = statement.getElseElement();
|
||||
if (elseToken == null) {
|
||||
@@ -144,5 +165,23 @@ public class ConfusingElseInspection extends BaseInspection {
|
||||
}
|
||||
registerError(elseToken);
|
||||
}
|
||||
|
||||
private PsiStatement getNextStatement(PsiIfStatement statement) {
|
||||
while (true) {
|
||||
final PsiElement parent = statement.getParent();
|
||||
if (parent instanceof PsiIfStatement) {
|
||||
final PsiIfStatement parentIfStatement =
|
||||
(PsiIfStatement) parent;
|
||||
final PsiStatement elseBranch =
|
||||
parentIfStatement.getElseBranch();
|
||||
if (elseBranch == statement) {
|
||||
statement = parentIfStatement;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return PsiTreeUtil.getNextSiblingOfType(statement,
|
||||
PsiStatement.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-9
@@ -157,12 +157,10 @@ public class IfStatementWithIdenticalBranchesInspection
|
||||
private static class IfStatementWithIdenticalBranchesVisitor
|
||||
extends BaseInspectionVisitor{
|
||||
|
||||
private static final int LIMIT_DEPTH = 20; // Dirty fix for 'squared' algorithm.
|
||||
|
||||
@Override public void visitIfStatement(
|
||||
@NotNull PsiIfStatement ifStatement){
|
||||
super.visitIfStatement(ifStatement);
|
||||
PsiStatement elseBranch = ifStatement.getElseBranch();
|
||||
final PsiStatement elseBranch = ifStatement.getElseBranch();
|
||||
final PsiStatement thenBranch = ifStatement.getThenBranch();
|
||||
if (thenBranch == null) {
|
||||
return;
|
||||
@@ -175,11 +173,7 @@ public class IfStatementWithIdenticalBranchesInspection
|
||||
new DuplicatesFinder(new PsiElement[]{thenBranch},
|
||||
inputVariables, null,
|
||||
Collections.<PsiVariable>emptyList());
|
||||
int depth = 0;
|
||||
while (elseBranch instanceof PsiIfStatement) {
|
||||
if (depth++ > LIMIT_DEPTH) {
|
||||
break;
|
||||
}
|
||||
if (elseBranch instanceof PsiIfStatement) {
|
||||
final PsiIfStatement statement =
|
||||
(PsiIfStatement) elseBranch;
|
||||
final PsiStatement branch = statement.getThenBranch();
|
||||
@@ -191,7 +185,6 @@ public class IfStatementWithIdenticalBranchesInspection
|
||||
registerStatementError(ifStatement, statement);
|
||||
return;
|
||||
}
|
||||
elseBranch = statement.getElseBranch();
|
||||
}
|
||||
if (elseBranch == null) {
|
||||
checkIfStatementWithoutElseBranch(ifStatement);
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
<html>
|
||||
<body>
|
||||
This inspection reports confusing <b>else</b> branches. Confusing <b>else</b>
|
||||
branches are branches of <b>if</b> statements whose <b>if</b> branch cannot complete normally and
|
||||
which are followed by other statements. In these cases, the statements following the
|
||||
<b>if</b> statement may be moved into the <b>else</b> branch, for increased clarity.
|
||||
This inspection reports confusing <b>else</b> branches. <b>else</b> branches are confusing
|
||||
when the <b>if</b> statement is followed by other statements and the <b>if</b> branch
|
||||
cannot complete normally, for example because it ends with a <b>return</b> statement. In these
|
||||
cases the statements in the <b>else</b> can be moved after the <b>if</b> statement and
|
||||
the <b>else</b> branch removed.
|
||||
<p>
|
||||
Use the checkbox below to also report <b>else</b> branches of <b>if</b> statements whose
|
||||
<b>if</b> branch cannot complete normally and which are not followed by more statements,
|
||||
similar to the Redundant Else intention.
|
||||
<p>
|
||||
<small>Powered by InspectionGadgets</small>
|
||||
</body>
|
||||
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
package com.siyeh.igtest.confusing;
|
||||
|
||||
public class ConfusingElseInspection
|
||||
{
|
||||
public static void main(String[] args)
|
||||
{
|
||||
if(foo())
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.out.println("ConfusingElseInspection.main");
|
||||
}
|
||||
bar();
|
||||
}
|
||||
|
||||
private static void bar()
|
||||
{
|
||||
}
|
||||
|
||||
private static boolean foo()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package com.siyeh.igtest.controlflow.confusing_else;
|
||||
|
||||
public class ConfusingElse {
|
||||
|
||||
public static void main(String[] args) {
|
||||
if (foo()) {
|
||||
return;
|
||||
} else {
|
||||
System.out.println("ConfusingElseInspection.main");
|
||||
}
|
||||
bar();
|
||||
}
|
||||
|
||||
private static void bar() {
|
||||
}
|
||||
|
||||
private static boolean foo() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void two(boolean b) {
|
||||
if (foo()) {
|
||||
|
||||
} else if (b) {
|
||||
return;
|
||||
} else {
|
||||
|
||||
}
|
||||
bar();
|
||||
}
|
||||
|
||||
void three(boolean b) {
|
||||
switch (3) {
|
||||
case 2:
|
||||
if (foo()) {
|
||||
return;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
case 3:
|
||||
}
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
<problem>
|
||||
<file>ConfusingElse.java</file>
|
||||
<line>8</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Confusing 'else' branch</problem_class>
|
||||
<description><code>else</code> branch may be unwrapped, as the if branch never completes #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>ConfusingElse.java</file>
|
||||
<line>26</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Confusing 'else' branch</problem_class>
|
||||
<description><code>else</code> branch may be unwrapped, as the if branch never completes #loc</description>
|
||||
</problem>
|
||||
|
||||
</problems>
|
||||
-14
@@ -35,20 +35,6 @@
|
||||
<description><code>if</code> statement with identical branches #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>IfStatementWithIdenticalBranches.java</file>
|
||||
<line>71</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'if' statement with identical branches</problem_class>
|
||||
<description><code>if</code> statement with identical branches #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>IfStatementWithIdenticalBranches.java</file>
|
||||
<line>82</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'if' statement with identical branches</problem_class>
|
||||
<description><code>if</code> statement with identical branches #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>IfStatementWithIdenticalBranches.java</file>
|
||||
<line>92</line>
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.siyeh.ig.controlflow;
|
||||
|
||||
import com.IGInspectionTestCase;
|
||||
|
||||
public class ConfusingElseInspectionTest
|
||||
extends IGInspectionTestCase {
|
||||
|
||||
public void test() throws Exception {
|
||||
doTest("com/siyeh/igtest/controlflow/confusing_else",
|
||||
new ConfusingElseInspection());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user