Project Coin try-with-resource support, take 3

This commit is contained in:
Roman Shevchenko
2011-02-22 00:35:23 +01:00
parent 468db26a73
commit e4f24b084d
23 changed files with 327 additions and 194 deletions
@@ -22,7 +22,6 @@ import com.intellij.psi.*;
import com.intellij.psi.controlFlow.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
@@ -247,8 +246,8 @@ public class ExceptionUtil {
unhandledExceptions = unhandled;
}
if (PsiUtil.isResourceInTryStatement(element)) {
final PsiType resourceType = PsiUtil.getResourceType(element);
if (element instanceof PsiResource) {
final PsiType resourceType = ((PsiResource)element).getType();
if (resourceType instanceof PsiClassType) {
final PsiClass resourceClass = ((PsiClassType)resourceType).resolve();
if (resourceClass != null) {
@@ -13,15 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Created by IntelliJ IDEA.
* User: cdr
* Date: Aug 8, 2002
* Time: 5:55:01 PM
* To change template for new class use
* Code Style | Class Templates options (Tools | IDE Options).
*/
package com.intellij.codeInsight.daemon.impl.analysis;
import com.intellij.codeInsight.daemon.JavaErrorMessages;
@@ -43,9 +34,14 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
/**
* @author cdr
* Date: Aug 8, 2002
*/
public class HighlightControlFlowUtil {
private static final QuickFixFactory QUICK_FIX_FACTORY = QuickFixFactory.getInstance();
private HighlightControlFlowUtil() { }
@Nullable
public static HighlightInfo checkMissingReturnStatement(PsiMethod method) {
@@ -297,7 +293,7 @@ public class HighlightControlFlowUtil {
topBlock = JspPsiUtil.isInJspFile(scope) && scope instanceof PsiFile ? scope : PsiUtil.getTopLevelEnclosingCodeBlock(expression, scope);
if (variable instanceof PsiField) {
// non final field already initalized with default value
// non final field already initialized with default value
if (!variable.hasModifierProperty(PsiModifier.FINAL)) return null;
// final field may be initialized in ctor or class initializer only
// if we're inside non-ctr method, skip it
@@ -314,9 +310,9 @@ public class HighlightControlFlowUtil {
if (parent instanceof PsiMethod) {
PsiMethod constructor = (PsiMethod)parent;
if (!parent.getManager().areElementsEquivalent(constructor.getContainingClass(), ((PsiField)variable).getContainingClass())) return null;
// static variables already initalized in class initalizers
// static variables already initialized in class initializers
if (variable.hasModifierProperty(PsiModifier.STATIC)) return null;
// as a last chance, field may be initalized in this() call
// as a last chance, field may be initialized in this() call
final List<PsiMethod> redirectedConstructors = getChainedConstructors(constructor);
for (int j = 0; redirectedConstructors != null && j < redirectedConstructors.size(); j++) {
PsiMethod redirectedConstructor = redirectedConstructors.get(j);
@@ -338,7 +334,7 @@ public class HighlightControlFlowUtil {
aClass = classInitializer.getContainingClass();
}
else {
// field reference outside codeblock
// field reference outside code block
// check variable initialized before its usage
final PsiField field = (PsiField)variable;
@@ -356,7 +352,7 @@ public class HighlightControlFlowUtil {
&& variableDefinitelyAssignedIn(variable, constructor.getBody())) {
return null;
}
// as a last chance, field may be initalized in this() call
// as a last chance, field may be initialized in this() call
final List<PsiMethod> redirectedConstructors = getChainedConstructors(constructor);
for (int j = 0; redirectedConstructors != null && j < redirectedConstructors.size(); j++) {
PsiMethod redirectedConstructor = redirectedConstructors.get(j);
@@ -371,13 +367,13 @@ public class HighlightControlFlowUtil {
}
if (aClass != null) {
// field may be initialized in class initalizer
// field may be initialized in class initializer
final PsiClassInitializer[] initializers = aClass.getInitializers();
for (PsiClassInitializer initializer : initializers) {
PsiCodeBlock body = initializer.getBody();
if (body == block) break;
// variable referenced in initializer must be initialized in initializer preceding assignment
// varaibel refernced in field initializer or in class initializier
// variable referenced in field initializer or in class initializer
boolean shouldCheckInitializerOrder = block == null || block.getParent() instanceof PsiClassInitializer;
if (shouldCheckInitializerOrder && startOffset < initializer.getTextRange().getStartOffset()) continue;
if (initializer.hasModifierProperty(PsiModifier.STATIC)
@@ -449,6 +445,7 @@ public class HighlightControlFlowUtil {
}
@Nullable
public static HighlightInfo checkFinalVariableMightAlreadyHaveBeenAssignedTo(PsiVariable variable,
PsiReferenceExpression expression,
Map<PsiElement, Collection<ControlFlowUtil.VariableInfo>> finalVarProblems) {
@@ -473,7 +470,7 @@ public class HighlightControlFlowUtil {
final PsiField field = (PsiField)variable;
final PsiClass aClass = field.getContainingClass();
if (aClass == null) return null;
// field can get assigned in other field inititializers
// field can get assigned in other field initializers
final PsiField[] fields = aClass.getFields();
boolean isFieldStatic = field.hasModifierProperty(PsiModifier.STATIC);
for (PsiField psiField : fields) {
@@ -565,7 +562,8 @@ public class HighlightControlFlowUtil {
}
public static HighlightInfo checkFinalVariableInitalizedInLoop(PsiReferenceExpression expression, PsiElement resolved) {
@Nullable
public static HighlightInfo checkFinalVariableInitializedInLoop(PsiReferenceExpression expression, PsiElement resolved) {
if (ControlFlowUtil.isVariableAssignedInLoop(expression, resolved)) {
String description = JavaErrorMessages.message("variable.assigned.in.loop", ((PsiVariable)resolved).getName());
final HighlightInfo highlightInfo = HighlightInfo.createHighlightInfo(
@@ -580,6 +578,7 @@ public class HighlightControlFlowUtil {
}
@Nullable
public static HighlightInfo checkCannotWriteToFinal(PsiExpression expression) {
PsiReferenceExpression reference = null;
if (expression instanceof PsiAssignmentExpression) {
@@ -659,6 +658,7 @@ public class HighlightControlFlowUtil {
}
@Nullable
static HighlightInfo checkVariableMustBeFinal(PsiVariable variable, PsiJavaCodeReferenceElement context) {
if (variable.hasModifierProperty(PsiModifier.FINAL)) return null;
final PsiClass innerClass = getInnerClassVariableReferencedFrom(variable, context);
@@ -672,9 +672,13 @@ public class HighlightControlFlowUtil {
return null;
}
@Nullable
public static PsiClass getInnerClassVariableReferencedFrom(PsiVariable variable, PsiElement context) {
PsiElement scope;
if (variable instanceof PsiLocalVariable) {
if (variable instanceof PsiScopedLocalVariable) {
scope = ((PsiScopedLocalVariable)variable).getDeclarationScope();
}
else if (variable instanceof PsiLocalVariable) {
scope = variable.getParent().getParent(); // code block or for statement
}
else if (variable instanceof PsiParameter) {
@@ -699,6 +703,7 @@ public class HighlightControlFlowUtil {
}
@Nullable
public static HighlightInfo checkInitializerCompleteNormally(PsiClassInitializer initializer) {
final PsiCodeBlock body = initializer.getBody();
// unhandled exceptions already reported
@@ -563,7 +563,7 @@ public class HighlightUtil {
if (variable instanceof PsiLocalVariable ||
variable instanceof PsiParameter && ((PsiParameter)variable).getDeclarationScope() instanceof PsiCatchSection ||
variable instanceof PsiParameter && ((PsiParameter)variable).getDeclarationScope() instanceof PsiForeachStatement ||
PsiUtil.isResourceInTryStatement(variable)) {
variable instanceof PsiResource && ((PsiResource)variable).getResourceElement() instanceof PsiLocalVariable) {
PsiElement scope = PsiTreeUtil.getParentOfType(variable, PsiFile.class, PsiMethod.class, PsiClassInitializer.class);
VariablesNotProcessor proc = new VariablesNotProcessor(variable, false) {
protected boolean check(final PsiVariable var, final ResolveState state) {
@@ -1118,8 +1118,8 @@ public class HighlightUtil {
}
@Nullable
public static HighlightInfo checkTryResourceIsAutoCloseable(@NotNull final PsiElement resource) {
final PsiType type = PsiUtil.getResourceType(resource);
public static HighlightInfo checkTryResourceIsAutoCloseable(@NotNull final PsiResource resource) {
final PsiType type = resource.getType();
if (type == null) return null;
final PsiElementFactory factory = JavaPsiFacade.getInstance(resource.getProject()).getElementFactory();
@@ -820,7 +820,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
if (!myHolder.hasErrorResults()) {
myHolder.add(HighlightControlFlowUtil.checkFinalVariableMightAlreadyHaveBeenAssignedTo(variable, expression, myFinalVarProblems));
}
if (!myHolder.hasErrorResults()) myHolder.add(HighlightControlFlowUtil.checkFinalVariableInitalizedInLoop(expression, resolved));
if (!myHolder.hasErrorResults()) myHolder.add(HighlightControlFlowUtil.checkFinalVariableInitializedInLoop(expression, resolved));
}
}
@@ -905,7 +905,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
PsiResourceList resources = statement.getResourceList();
if (resources != null) {
for (PsiElement resource : resources.getResources()) {
for (PsiResource resource : resources.getResources()) {
myHolder.add(HighlightUtil.checkTryResourceIsAutoCloseable(resource));
}
}
@@ -31,6 +31,7 @@ import org.jetbrains.annotations.Nullable;
import static com.intellij.lang.PsiBuilderUtil.expect;
import static com.intellij.lang.PsiBuilderUtil.nextTokenType;
import static com.intellij.lang.java.parser.JavaParserUtil.*;
import static com.intellij.lang.java.parser.JavaParserUtil.exprType;
public class DeclarationParser {
@@ -588,12 +589,22 @@ public class DeclarationParser {
}
@Nullable
private static PsiBuilder.Marker parseResource(final PsiBuilder builder) {
PsiBuilder.Marker resource = parse(builder, Context.RESOURCE_LIST);
if (resource == null) {
resource = ExpressionParser.parse(builder);
public static PsiBuilder.Marker parseResource(final PsiBuilder builder) {
PsiBuilder.Marker element = parse(builder, Context.RESOURCE_LIST);
if (exprType(element) == JavaElementType.MODIFIER_LIST) {
return element;
}
return resource;
else if (element == null) {
element = ExpressionParser.parse(builder);
}
if (element != null) {
final PsiBuilder.Marker resource = element.precede();
done(resource, JavaElementType.RESOURCE);
return resource;
}
return null;
}
@Nullable
@@ -200,9 +200,10 @@ public class PsiImplUtil {
final PsiElement lastParent) {
final PsiResourceList resourceList = statement.getResourceList();
if (resourceList != null && lastParent instanceof PsiCodeBlock && lastParent == statement.getTryBlock()) {
final List<PsiLocalVariable> resources = resourceList.getNamedResources();
for (PsiLocalVariable resource : resources) {
if (!processor.execute(resource, state)) return false;
final List<PsiResource> resources = resourceList.getResources();
for (PsiResource resource : resources) {
final PsiElement resourceElement = resource.getResourceElement();
if (resourceElement instanceof PsiLocalVariable && !processor.execute(resourceElement, state)) return false;
}
}
@@ -128,6 +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 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);
@@ -49,7 +49,7 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.Set;
public class PsiLocalVariableImpl extends CompositePsiElement implements PsiLocalVariable, PsiVariableEx, Constants {
public class PsiLocalVariableImpl extends CompositePsiElement implements PsiScopedLocalVariable, PsiVariableEx, Constants {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiLocalVariableImpl");
private volatile String myCachedName = null;
@@ -279,6 +279,21 @@ public class PsiLocalVariableImpl extends CompositePsiElement implements PsiLoca
return "PsiLocalVariable:" + getName();
}
@NotNull
public PsiElement getDeclarationScope() {
final PsiElement parentElement = getParent();
if (parentElement instanceof PsiDeclarationStatement) {
return 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 ? tryBlock : resourceList;
}
return parentElement.getParent();
}
@NotNull
public SearchScope getUseScope() {
if (JspPsiUtil.isInJspFile(this)) {
@@ -306,13 +321,8 @@ public class PsiLocalVariableImpl extends CompositePsiElement implements PsiLoca
}
final PsiElement parentElement = getParent();
if (parentElement instanceof PsiDeclarationStatement) {
return new LocalSearchScope(parentElement.getParent());
}
else if (parentElement instanceof PsiResourceList) {
final PsiElement tryStatement = parentElement.getParent();
final PsiCodeBlock tryBlock = ((PsiTryStatement)tryStatement).getTryBlock();
return new LocalSearchScope(tryBlock != null ? tryBlock : tryStatement);
if (parentElement instanceof PsiDeclarationStatement || parentElement instanceof PsiResource) {
return new LocalSearchScope(getDeclarationScope());
}
else {
return getManager().getFileManager().getUseScope(this);
@@ -0,0 +1,74 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.psi.impl.source.tree.java;
import com.intellij.openapi.diagnostic.LogUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.tree.CompositePsiElement;
import com.intellij.psi.impl.source.tree.JavaElementType;
import org.jetbrains.annotations.NotNull;
public class PsiResourceImpl extends CompositePsiElement implements PsiResource {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiResourceImpl");
public PsiResourceImpl() {
super(JavaElementType.RESOURCE);
}
@NotNull
@Override
public PsiElement getResourceElement() {
final PsiElement element = getFirstChild();
assert element != null : this;
return element;
}
@Override
public PsiType getType() {
final PsiElement element = getResourceElement();
if (element instanceof PsiLocalVariable) {
return ((PsiLocalVariable)element).getType();
}
else if (element instanceof PsiExpression) {
return ((PsiExpression)element).getType();
}
LOG.error("Unexpected resource type: " + LogUtil.objectAndClass(element));
return null;
}
@Override
public void accept(@NotNull final PsiElementVisitor visitor) {
if (visitor instanceof JavaElementVisitor) {
((JavaElementVisitor)visitor).visitResource(this);
}
else {
visitor.visitElement(this);
}
}
public String getName() {
final PsiElement element = getResourceElement();
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();
}
}
@@ -15,7 +15,10 @@
*/
package com.intellij.psi.impl.source.tree.java;
import com.intellij.psi.*;
import com.intellij.psi.JavaElementVisitor;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiResource;
import com.intellij.psi.PsiResourceList;
import com.intellij.psi.impl.source.tree.CompositePsiElement;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.util.PsiTreeUtil;
@@ -30,15 +33,8 @@ public class PsiResourceListImpl extends CompositePsiElement implements PsiResou
@NotNull
@Override
public List<? extends PsiElement> getResources() {
//noinspection unchecked
return PsiTreeUtil.getChildrenOfAnyType(this, PsiExpression.class, PsiLocalVariable.class);
}
@NotNull
@Override
public List<PsiLocalVariable> getNamedResources() {
return PsiTreeUtil.getChildrenOfTypeAsList(this, PsiLocalVariable.class);
public List<PsiResource> getResources() {
return PsiTreeUtil.getChildrenOfTypeAsList(this, PsiResource.class);
}
@Override
@@ -3,18 +3,19 @@ PsiJavaFile:TryIncomplete15.java
PsiKeyword:try('try')
PsiResourceList:(R r)
PsiJavaToken:LPARENTH('(')
PsiLocalVariable:r
PsiModifierList:
<empty list>
PsiTypeElement:R
PsiJavaCodeReferenceElement:R
PsiIdentifier:R('R')
PsiReferenceParameterList
<empty list>
PsiWhiteSpace(' ')
PsiIdentifier:r('r')
PsiErrorElement:'=' expected
<empty list>
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>
PsiJavaToken:RPARENTH(')')
PsiCodeBlock
PsiJavaToken:LBRACE('{')
@@ -3,20 +3,21 @@ PsiJavaFile:TryIncomplete16.java
PsiKeyword:try('try')
PsiResourceList:(R r =)
PsiJavaToken:LPARENTH('(')
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>
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>
PsiJavaToken:RPARENTH(')')
PsiCodeBlock
PsiJavaToken:LBRACE('{')
@@ -3,21 +3,22 @@ PsiJavaFile:TryIncomplete17.java
PsiKeyword:try('try')
PsiResourceList:(R r = 0;)
PsiJavaToken:LPARENTH('(')
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')
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')
PsiJavaToken:SEMICOLON(';')
PsiErrorElement:Identifier or type expected
<empty list>
@@ -3,21 +3,22 @@ PsiJavaFile:TryNormal4.java
PsiKeyword:try('try')
PsiResourceList:(R r = 0)
PsiJavaToken:LPARENTH('(')
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')
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')
PsiJavaToken:RPARENTH(')')
PsiCodeBlock
PsiJavaToken:LBRACE('{')
@@ -3,38 +3,40 @@ PsiJavaFile:TryNormal5.java
PsiKeyword:try('try')
PsiResourceList:(R1 r1 = 1; R2 r2 = 2)
PsiJavaToken:LPARENTH('(')
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')
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')
PsiJavaToken:SEMICOLON(';')
PsiWhiteSpace(' ')
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')
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')
PsiJavaToken:RPARENTH(')')
PsiCodeBlock
PsiJavaToken:LBRACE('{')
@@ -3,10 +3,11 @@ PsiJavaFile:TryNormal6.java
PsiKeyword:try('try')
PsiResourceList:(r)
PsiJavaToken:LPARENTH('(')
PsiReferenceExpression:r
PsiReferenceParameterList
<empty list>
PsiIdentifier:r('r')
PsiResource:
PsiReferenceExpression:r
PsiReferenceParameterList
<empty list>
PsiIdentifier:r('r')
PsiJavaToken:RPARENTH(')')
PsiCodeBlock
PsiJavaToken:LBRACE('{')
@@ -3,14 +3,16 @@ PsiJavaFile:TryNormal7.java
PsiKeyword:try('try')
PsiResourceList:(r; null)
PsiJavaToken:LPARENTH('(')
PsiReferenceExpression:r
PsiReferenceParameterList
<empty list>
PsiIdentifier:r('r')
PsiResource:
PsiReferenceExpression:r
PsiReferenceParameterList
<empty list>
PsiIdentifier:r('r')
PsiJavaToken:SEMICOLON(';')
PsiWhiteSpace(' ')
PsiLiteralExpression:null
PsiJavaToken:NULL_KEYWORD('null')
PsiResource:
PsiLiteralExpression:null
PsiJavaToken:NULL_KEYWORD('null')
PsiJavaToken:RPARENTH(')')
PsiCodeBlock
PsiJavaToken:LBRACE('{')
@@ -300,6 +300,10 @@ public abstract class JavaElementVisitor extends PsiElementVisitor {
visitElement(resourceList);
}
public void visitResource(PsiResource resource) {
visitElement(resource);
}
public void visitTypeElement(PsiTypeElement type) {
visitElement(type);
}
@@ -0,0 +1,39 @@
/*
* 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();
}
@@ -26,19 +26,6 @@ import java.util.List;
* @since 10.5.
*/
public interface PsiResourceList extends PsiElement {
/**
* Returns list of resource elements. Each element is either {@link PsiLocalVariable} or {@link PsiExpression}.
*
* @return list of resource elements.
*/
@NotNull
List<? extends PsiElement> getResources();
/**
* Returns list of named resource elements only.
*
* @return list of named resource elements.
*/
@NotNull
List<PsiLocalVariable> getNamedResources();
List<PsiResource> getResources();
}
@@ -0,0 +1,28 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.psi;
import org.jetbrains.annotations.NotNull;
public interface PsiScopedLocalVariable extends PsiLocalVariable {
/**
* Returns the element (method, "for" statement or try block) in which the variable is declared.
*
* @return the declaration scope for the variable.
*/
@NotNull
PsiElement getDeclarationScope();
}
@@ -15,7 +15,6 @@
*/
package com.intellij.psi.util;
import com.intellij.openapi.diagnostic.LogUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
import com.intellij.openapi.util.Comparing;
@@ -636,20 +635,6 @@ public final class PsiUtil extends PsiUtilBase {
return PsiTreeUtil.getParentOfType(element, PsiDocComment.class, true) != null;
}
public static boolean isResourceInTryStatement(final PsiElement element) {
return (element instanceof PsiLocalVariable || element instanceof PsiExpression) &&
element.getParent() instanceof PsiResourceList;
}
@Nullable
public static PsiType getResourceType(final PsiElement element) {
if (element == null || !(element.getParent() instanceof PsiResourceList)) return null;
if (element instanceof PsiLocalVariable) return ((PsiLocalVariable)element).getType();
if (element instanceof PsiExpression) return ((PsiExpression)element).getType();
LOG.error("Unexpected resource type: " + LogUtil.objectAndClass(element));
return null;
}
private static class ParamWriteProcessor implements Processor<PsiReference> {
private volatile boolean myIsWriteRefFound = false;
public boolean process(PsiReference reference) {
@@ -312,22 +312,6 @@ public class PsiTreeUtil {
return null;
}
@NotNull
public static List<? extends PsiElement> getChildrenOfAnyType(@Nullable final PsiElement element,
@Nullable final Class<? extends PsiElement>... classes) {
if (element == null || classes == null || classes.length == 0) return Collections.emptyList();
final List<PsiElement> result = new SmartList<PsiElement>();
for (PsiElement child = element.getFirstChild(); child != null; child = child.getNextSibling()) {
for (Class<? extends PsiElement> aClass : classes) {
if (aClass.isInstance(child)) {
result.add(child);
}
}
}
return result;
}
@Nullable
public static <T extends PsiElement> T getNextSiblingOfType(@Nullable PsiElement sibling, @NotNull Class<T> aClass) {
if (sibling == null) return null;