mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-04 17:20:55 +07:00
Project Coin multi-catch support
This commit is contained in:
@@ -559,6 +559,10 @@ public class GenericsHighlightUtil {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rType instanceof PsiDisjunctionType || lType instanceof PsiDisjunctionType) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (lType instanceof PsiCapturedWildcardType || rType instanceof PsiCapturedWildcardType) {
|
if (lType instanceof PsiCapturedWildcardType || rType instanceof PsiCapturedWildcardType) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,9 +29,9 @@ import com.intellij.codeInsight.daemon.impl.quickfix.*;
|
|||||||
import com.intellij.codeInsight.highlighting.HighlightUsagesDescriptionLocation;
|
import com.intellij.codeInsight.highlighting.HighlightUsagesDescriptionLocation;
|
||||||
import com.intellij.codeInsight.intention.IntentionAction;
|
import com.intellij.codeInsight.intention.IntentionAction;
|
||||||
import com.intellij.codeInsight.intention.QuickFixFactory;
|
import com.intellij.codeInsight.intention.QuickFixFactory;
|
||||||
import com.intellij.codeInspection.IntentionProvider;
|
|
||||||
import com.intellij.codeInsight.quickfix.ChangeVariableTypeQuickFixProvider;
|
import com.intellij.codeInsight.quickfix.ChangeVariableTypeQuickFixProvider;
|
||||||
import com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider;
|
import com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider;
|
||||||
|
import com.intellij.codeInspection.IntentionProvider;
|
||||||
import com.intellij.lang.StdLanguages;
|
import com.intellij.lang.StdLanguages;
|
||||||
import com.intellij.lang.findUsages.LanguageFindUsages;
|
import com.intellij.lang.findUsages.LanguageFindUsages;
|
||||||
import com.intellij.openapi.diagnostic.Logger;
|
import com.intellij.openapi.diagnostic.Logger;
|
||||||
@@ -854,27 +854,66 @@ public class HighlightUtil {
|
|||||||
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
static HighlightInfo checkExceptionThrownInTry(PsiParameter parameter) {
|
static HighlightInfo checkExceptionThrownInTry(final PsiParameter parameter) {
|
||||||
PsiElement declarationScope = parameter.getDeclarationScope();
|
final PsiElement declarationScope = parameter.getDeclarationScope();
|
||||||
if (!(declarationScope instanceof PsiCatchSection)) return null;
|
if (!(declarationScope instanceof PsiCatchSection)) return null;
|
||||||
PsiTryStatement statement = ((PsiCatchSection)declarationScope).getTryStatement();
|
|
||||||
Collection<PsiClassType> classes = ExceptionUtil.collectUnhandledExceptions(statement.getTryBlock(), statement.getTryBlock());
|
|
||||||
|
|
||||||
PsiType caughtType = parameter.getType();
|
final PsiTryStatement statement = ((PsiCatchSection)declarationScope).getTryStatement();
|
||||||
if (!(caughtType instanceof PsiClassType)) return null;
|
final PsiCodeBlock tryBlock = statement.getTryBlock();
|
||||||
if (ExceptionUtil.isUncheckedExceptionOrSuperclass((PsiClassType)caughtType)) return null;
|
assert tryBlock != null : statement;
|
||||||
|
final Collection<PsiClassType> thrownTypes = ExceptionUtil.collectUnhandledExceptions(tryBlock, tryBlock);
|
||||||
|
|
||||||
for (PsiClassType exceptionType : classes) {
|
final PsiType caughtType = parameter.getType();
|
||||||
|
if (caughtType instanceof PsiClassType) {
|
||||||
|
return checkSimpleCatchParameter(parameter, thrownTypes, (PsiClassType)caughtType);
|
||||||
|
}
|
||||||
|
else if (caughtType instanceof PsiDisjunctionType) {
|
||||||
|
return checkMultiCatchParameter(parameter, thrownTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static HighlightInfo checkSimpleCatchParameter(final PsiParameter parameter,
|
||||||
|
final Collection<PsiClassType> thrownTypes,
|
||||||
|
final PsiClassType caughtType) {
|
||||||
|
if (ExceptionUtil.isUncheckedExceptionOrSuperclass(caughtType)) return null;
|
||||||
|
|
||||||
|
for (PsiClassType exceptionType : thrownTypes) {
|
||||||
if (exceptionType.isAssignableFrom(caughtType) || caughtType.isAssignableFrom(exceptionType)) return null;
|
if (exceptionType.isAssignableFrom(caughtType) || caughtType.isAssignableFrom(exceptionType)) return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
String description = JavaErrorMessages.message("exception.never.thrown.try", formatType(caughtType));
|
final String description = JavaErrorMessages.message("exception.never.thrown.try", formatType(caughtType));
|
||||||
HighlightInfo errorResult = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, parameter, description);
|
final HighlightInfo errorResult = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, parameter, description);
|
||||||
|
|
||||||
QuickFixAction.registerQuickFixAction(errorResult, new DeleteCatchFix(parameter));
|
QuickFixAction.registerQuickFixAction(errorResult, new DeleteCatchFix(parameter));
|
||||||
return errorResult;
|
return errorResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static HighlightInfo checkMultiCatchParameter(final PsiParameter parameter, final Collection<PsiClassType> thrownTypes) {
|
||||||
|
for (PsiTypeElement typeElement : PsiTreeUtil.getChildrenOfTypeAsList(parameter.getTypeElement(), PsiTypeElement.class)) {
|
||||||
|
final PsiType catchType = typeElement.getType();
|
||||||
|
if (catchType instanceof PsiClassType && ExceptionUtil.isUncheckedExceptionOrSuperclass((PsiClassType)catchType)) continue;
|
||||||
|
|
||||||
|
boolean used = false;
|
||||||
|
for (PsiClassType exceptionType : thrownTypes) {
|
||||||
|
if (exceptionType.isAssignableFrom(catchType) || catchType.isAssignableFrom(exceptionType)) {
|
||||||
|
used = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (used) continue;
|
||||||
|
|
||||||
|
final String description = JavaErrorMessages.message("exception.never.thrown.try", formatType(catchType));
|
||||||
|
final HighlightInfo errorResult = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, typeElement, description);
|
||||||
|
QuickFixAction.registerQuickFixAction(errorResult, new DeleteMultiCatchFix(typeElement));
|
||||||
|
return errorResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
static HighlightInfo checkNotAStatement(PsiStatement statement) {
|
static HighlightInfo checkNotAStatement(PsiStatement statement) {
|
||||||
@@ -1596,36 +1635,81 @@ public class HighlightUtil {
|
|||||||
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static HighlightInfo checkExceptionAlreadyCaught(PsiJavaCodeReferenceElement element, PsiElement resolved) {
|
public static HighlightInfo checkExceptionAlreadyCaught(final PsiJavaCodeReferenceElement element, final PsiElement resolved) {
|
||||||
if (!(resolved instanceof PsiClass)) return null;
|
if (!(resolved instanceof PsiClass)) return null;
|
||||||
PsiClass catchClass = (PsiClass)resolved;
|
|
||||||
if (!(element.getParent() instanceof PsiTypeElement)) return null;
|
if (!(element.getParent() instanceof PsiTypeElement)) return null;
|
||||||
|
|
||||||
PsiElement catchParameter = element.getParent().getParent();
|
PsiElement catchParameter = element.getParent().getParent();
|
||||||
|
boolean isInMultiCatch = false;
|
||||||
|
if (catchParameter instanceof PsiTypeElement && ((PsiTypeElement)catchParameter).getType() instanceof PsiDisjunctionType) {
|
||||||
|
isInMultiCatch = true;
|
||||||
|
catchParameter = catchParameter.getParent();
|
||||||
|
}
|
||||||
if (!(catchParameter instanceof PsiParameter) || !(((PsiParameter)catchParameter).getDeclarationScope() instanceof PsiCatchSection)) {
|
if (!(catchParameter instanceof PsiParameter) || !(((PsiParameter)catchParameter).getDeclarationScope() instanceof PsiCatchSection)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
PsiCatchSection catchSection = (PsiCatchSection)((PsiParameter)catchParameter).getDeclarationScope();
|
|
||||||
PsiTryStatement statement = catchSection.getTryStatement();
|
final PsiClass catchClass = (PsiClass)resolved;
|
||||||
PsiCatchSection[] catchSections = statement.getCatchSections();
|
final PsiCatchSection catchSection = (PsiCatchSection)((PsiParameter)catchParameter).getDeclarationScope();
|
||||||
int i = ArrayUtil.find(catchSections, catchSection);
|
final PsiCatchSection[] allCatchSections = catchSection.getTryStatement().getCatchSections();
|
||||||
for (i--; i >= 0; i--) {
|
final int startFrom = ArrayUtil.find(allCatchSections, catchSection) - (isInMultiCatch ? 0 : 1); // check the same multi-catch section
|
||||||
PsiCatchSection section = catchSections[i];
|
for (int i = startFrom; i >= 0; i--) {
|
||||||
PsiType type = section.getCatchType();
|
final PsiCatchSection upperCatchSection = allCatchSections[i];
|
||||||
PsiClass upCatchClass = PsiUtil.resolveClassInType(type);
|
final PsiType upperCatchType = upperCatchSection.getCatchType();
|
||||||
if (upCatchClass == null) continue;
|
final boolean highlight = upperCatchType instanceof PsiDisjunctionType
|
||||||
if (InheritanceUtil.isInheritorOrSelf(catchClass, upCatchClass, true)) {
|
? checkMultiCatchSection(catchSection, element.getParent(), catchClass, upperCatchSection)
|
||||||
String description = JavaErrorMessages
|
: checkSimpleCatchSection(catchClass, upperCatchType);
|
||||||
.message("exception.already.caught", PsiFormatUtil.formatClass(catchClass, PsiFormatUtilBase.SHOW_NAME |
|
if (highlight) {
|
||||||
PsiFormatUtilBase.SHOW_FQ_NAME));
|
final String className = PsiFormatUtil.formatClass(catchClass, PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_FQ_NAME);
|
||||||
HighlightInfo highlightInfo = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, element, description);
|
final String description = JavaErrorMessages.message("exception.already.caught", className);
|
||||||
QuickFixAction.registerQuickFixAction(highlightInfo, new MoveCatchUpFix(catchSection, section));
|
final HighlightInfo result = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, element, description);
|
||||||
QuickFixAction.registerQuickFixAction(highlightInfo, new DeleteCatchFix((PsiParameter)catchParameter));
|
|
||||||
return highlightInfo;
|
if (catchSection != upperCatchSection) {
|
||||||
|
QuickFixAction.registerQuickFixAction(result, new MoveCatchUpFix(catchSection, upperCatchSection));
|
||||||
|
}
|
||||||
|
if (isInMultiCatch) {
|
||||||
|
QuickFixAction.registerQuickFixAction(result, new DeleteMultiCatchFix((PsiTypeElement)element.getParent()));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
QuickFixAction.registerQuickFixAction(result, new DeleteCatchFix((PsiParameter)catchParameter));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean checkSimpleCatchSection(final PsiClass catchClass, final PsiType upperCatchType) {
|
||||||
|
final PsiClass upperCatchClass = PsiUtil.resolveClassInType(upperCatchType);
|
||||||
|
return upperCatchClass != null && InheritanceUtil.isInheritorOrSelf(catchClass, upperCatchClass, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean checkMultiCatchSection(final PsiCatchSection catchSection,
|
||||||
|
final PsiElement catchTypeElement,
|
||||||
|
final PsiClass catchClass,
|
||||||
|
final PsiCatchSection upperCatchSection) {
|
||||||
|
final PsiManager manager = upperCatchSection.getManager();
|
||||||
|
final PsiParameter parameter = upperCatchSection.getParameter();
|
||||||
|
assert parameter != null : upperCatchSection;
|
||||||
|
final List<PsiTypeElement> typeElements = PsiTreeUtil.getChildrenOfTypeAsList(parameter.getTypeElement(), PsiTypeElement.class);
|
||||||
|
boolean skipElements = manager.areElementsEquivalent(catchSection, upperCatchSection);
|
||||||
|
|
||||||
|
for (int i = typeElements.size() - 1; i >= 0; i--) {
|
||||||
|
final PsiTypeElement typeElement = typeElements.get(i);
|
||||||
|
if (skipElements) {
|
||||||
|
if (manager.areElementsEquivalent(typeElement, catchTypeElement)) skipElements = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final PsiClass upperCatchClass = PsiUtil.resolveClassInType(typeElement.getType());
|
||||||
|
if (upperCatchClass != null && InheritanceUtil.isInheritorOrSelf(catchClass, upperCatchClass, true)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static HighlightInfo checkTernaryOperatorConditionIsBoolean(PsiExpression expression) {
|
public static HighlightInfo checkTernaryOperatorConditionIsBoolean(PsiExpression expression) {
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2000-2011 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.intellij.codeInsight.daemon.impl.quickfix;
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.CodeInsightUtilBase;
|
||||||
|
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||||
|
import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
|
||||||
|
import com.intellij.codeInsight.intention.IntentionAction;
|
||||||
|
import com.intellij.openapi.editor.Editor;
|
||||||
|
import com.intellij.openapi.project.Project;
|
||||||
|
import com.intellij.psi.*;
|
||||||
|
import com.intellij.psi.tree.IElementType;
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
|
import com.intellij.util.IncorrectOperationException;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class DeleteMultiCatchFix implements IntentionAction {
|
||||||
|
private final PsiTypeElement myTypeElement;
|
||||||
|
|
||||||
|
public DeleteMultiCatchFix(final PsiTypeElement typeElement) {
|
||||||
|
myTypeElement = typeElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getText() {
|
||||||
|
return QuickFixBundle.message("delete.catch.text", HighlightUtil.formatType(myTypeElement.getType()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getFamilyName() {
|
||||||
|
return QuickFixBundle.message("delete.catch.family");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAvailable(@NotNull final Project project, final Editor editor, final PsiFile file) {
|
||||||
|
return myTypeElement != null &&
|
||||||
|
myTypeElement.isValid() &&
|
||||||
|
PsiManager.getInstance(project).isInProject(myTypeElement.getContainingFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file) throws IncorrectOperationException {
|
||||||
|
if (!CodeInsightUtilBase.prepareFileForWrite(myTypeElement.getContainingFile())) return;
|
||||||
|
|
||||||
|
final PsiElement parentType = myTypeElement.getParent();
|
||||||
|
if (!(parentType instanceof PsiTypeElement)) return;
|
||||||
|
|
||||||
|
final PsiElement first;
|
||||||
|
final PsiElement last;
|
||||||
|
final PsiElement right = PsiTreeUtil.skipSiblingsForward(myTypeElement, PsiWhiteSpace.class, PsiComment.class);
|
||||||
|
if (right instanceof PsiJavaToken && ((PsiJavaToken)right).getTokenType() == JavaTokenType.OR) {
|
||||||
|
first = myTypeElement;
|
||||||
|
last = right;
|
||||||
|
}
|
||||||
|
else if (right == null) {
|
||||||
|
final PsiElement left = PsiTreeUtil.skipSiblingsBackward(myTypeElement, PsiWhiteSpace.class, PsiComment.class);
|
||||||
|
if (!(left instanceof PsiJavaToken)) return;
|
||||||
|
final IElementType leftType = ((PsiJavaToken)left).getTokenType();
|
||||||
|
if (leftType != JavaTokenType.OR) return;
|
||||||
|
first = left;
|
||||||
|
last = myTypeElement;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
parentType.deleteChildRange(first, last);
|
||||||
|
|
||||||
|
final List<PsiTypeElement> typeElements = PsiTreeUtil.getChildrenOfTypeAsList(parentType, PsiTypeElement.class);
|
||||||
|
if (typeElements.size() == 1) {
|
||||||
|
final PsiElement parameter = parentType.getParent();
|
||||||
|
parameter.addRangeAfter(parentType.getFirstChild(), parentType.getLastChild(), parentType);
|
||||||
|
parentType.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean startInWriteAction() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -493,7 +493,7 @@ public class DeclarationParser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
final PsiBuilder.Marker param = parseParameter(builder, true);
|
final PsiBuilder.Marker param = parseParameter(builder, true, false);
|
||||||
if (param != null) {
|
if (param != null) {
|
||||||
commaExpected = true;
|
commaExpected = true;
|
||||||
if (invalidElements != null) {
|
if (invalidElements != null) {
|
||||||
@@ -533,23 +533,25 @@ public class DeclarationParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static PsiBuilder.Marker parseParameter(final PsiBuilder builder, final boolean ellipsis) {
|
public static PsiBuilder.Marker parseParameter(final PsiBuilder builder, final boolean ellipsis, final boolean disjunctiveType) {
|
||||||
final PsiBuilder.Marker param = builder.mark();
|
final PsiBuilder.Marker param = builder.mark();
|
||||||
|
|
||||||
final Pair<PsiBuilder.Marker, Boolean> modListInfo = parseModifierList(builder);
|
final Pair<PsiBuilder.Marker, Boolean> modListInfo = parseModifierList(builder);
|
||||||
|
|
||||||
int flags = ReferenceParser.EAT_LAST_DOT | ReferenceParser.WILDCARD;
|
int flags = ReferenceParser.EAT_LAST_DOT | ReferenceParser.WILDCARD;
|
||||||
if (ellipsis) flags |= ReferenceParser.ELLIPSIS;
|
if (ellipsis) flags |= ReferenceParser.ELLIPSIS;
|
||||||
|
if (disjunctiveType) flags |= ReferenceParser.DISJUNCTIONS;
|
||||||
final ReferenceParser.TypeInfo typeInfo = ReferenceParser.parseTypeInfo(builder, flags);
|
final ReferenceParser.TypeInfo typeInfo = ReferenceParser.parseTypeInfo(builder, flags);
|
||||||
|
|
||||||
if (typeInfo == null && modListInfo.second) {
|
|
||||||
param.rollbackTo();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeInfo == null) {
|
if (typeInfo == null) {
|
||||||
error(builder, JavaErrorMessages.message("expected.type"));
|
if (modListInfo.second) {
|
||||||
emptyElement(builder, JavaElementType.TYPE);
|
param.rollbackTo();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
error(builder, JavaErrorMessages.message("expected.type"));
|
||||||
|
emptyElement(builder, JavaElementType.TYPE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expect(builder, JavaTokenType.IDENTIFIER)) {
|
if (expect(builder, JavaTokenType.IDENTIFIER)) {
|
||||||
|
|||||||
@@ -142,6 +142,11 @@ public class JavaParserUtil {
|
|||||||
return getLanguageLevel(builder).isAtLeast(LanguageLevel.JDK_1_7);
|
return getLanguageLevel(builder).isAtLeast(LanguageLevel.JDK_1_7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo[r.sh] join all JDK 7 check clauses into single method (IDEA 11)
|
||||||
|
public static boolean areMultiCatchSupported(final PsiBuilder builder) {
|
||||||
|
return getLanguageLevel(builder).isAtLeast(LanguageLevel.JDK_1_7);
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean areTypeAnnotationsSupported(final PsiBuilder builder) {
|
public static boolean areTypeAnnotationsSupported(final PsiBuilder builder) {
|
||||||
return getLanguageLevel(builder).isAtLeast(LanguageLevel.JDK_1_8);
|
return getLanguageLevel(builder).isAtLeast(LanguageLevel.JDK_1_8);
|
||||||
}
|
}
|
||||||
@@ -460,4 +465,4 @@ public class JavaParserUtil {
|
|||||||
myDelegate.putUserDataUnprotected(key, value);
|
myDelegate.putUserDataUnprotected(key, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ public class ReferenceParser {
|
|||||||
public static final int ELLIPSIS = 0x02;
|
public static final int ELLIPSIS = 0x02;
|
||||||
public static final int WILDCARD = 0x04;
|
public static final int WILDCARD = 0x04;
|
||||||
public static final int DIAMONDS = 0x08;
|
public static final int DIAMONDS = 0x08;
|
||||||
|
public static final int DISJUNCTIONS = 0x10;
|
||||||
|
|
||||||
public static class TypeInfo {
|
public static class TypeInfo {
|
||||||
public boolean isPrimitive = false;
|
public boolean isPrimitive = false;
|
||||||
@@ -58,7 +59,24 @@ public class ReferenceParser {
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static TypeInfo parseTypeInfo(final PsiBuilder builder, final int flags) {
|
public static TypeInfo parseTypeInfo(final PsiBuilder builder, final int flags) {
|
||||||
return parseTypeInfo(builder, isSet(flags, EAT_LAST_DOT), isSet(flags, WILDCARD), isSet(flags, DIAMONDS), isSet(flags, ELLIPSIS));
|
final TypeInfo typeInfo =
|
||||||
|
parseTypeInfo(builder, isSet(flags, EAT_LAST_DOT), isSet(flags, WILDCARD), isSet(flags, DIAMONDS), isSet(flags, ELLIPSIS));
|
||||||
|
|
||||||
|
if (typeInfo != null && isSet(flags, DISJUNCTIONS) && builder.getTokenType() == JavaTokenType.OR) {
|
||||||
|
typeInfo.marker = typeInfo.marker.precede();
|
||||||
|
|
||||||
|
while (builder.getTokenType() == JavaTokenType.OR) {
|
||||||
|
builder.advanceLexer();
|
||||||
|
if (builder.getTokenType() != JavaTokenType.IDENTIFIER) {
|
||||||
|
error(builder, JavaErrorMessages.message("expected.identifier"));
|
||||||
|
}
|
||||||
|
parseTypeInfo(builder, isSet(flags, EAT_LAST_DOT), isSet(flags, WILDCARD), isSet(flags, DIAMONDS), isSet(flags, ELLIPSIS));
|
||||||
|
}
|
||||||
|
|
||||||
|
typeInfo.marker.done(JavaElementType.TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return typeInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
@@ -375,7 +375,7 @@ public class StatementParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final PsiBuilder.Marker afterParenth = builder.mark();
|
final PsiBuilder.Marker afterParenth = builder.mark();
|
||||||
final PsiBuilder.Marker param = DeclarationParser.parseParameter(builder, false);
|
final PsiBuilder.Marker param = DeclarationParser.parseParameter(builder, false, false);
|
||||||
if (param == null || JavaParserUtil.exprType(param) != JavaElementType.PARAMETER || builder.getTokenType() != JavaTokenType.COLON) {
|
if (param == null || JavaParserUtil.exprType(param) != JavaElementType.PARAMETER || builder.getTokenType() != JavaTokenType.COLON) {
|
||||||
afterParenth.rollbackTo();
|
afterParenth.rollbackTo();
|
||||||
return parseForLoopFromInitialization(builder, statement);
|
return parseForLoopFromInitialization(builder, statement);
|
||||||
@@ -651,7 +651,7 @@ public class StatementParser {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
final PsiBuilder.Marker param = DeclarationParser.parseParameter(builder, false);
|
final PsiBuilder.Marker param = DeclarationParser.parseParameter(builder, false, areMultiCatchSupported(builder));
|
||||||
if (param == null) {
|
if (param == null) {
|
||||||
error(builder, JavaErrorMessages.message("expected.parameter"));
|
error(builder, JavaErrorMessages.message("expected.parameter"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import com.intellij.util.containers.Stack;
|
|||||||
import gnu.trove.THashMap;
|
import gnu.trove.THashMap;
|
||||||
import gnu.trove.TIntArrayList;
|
import gnu.trove.TIntArrayList;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -63,11 +64,11 @@ class ControlFlowAnalyzer extends JavaJspElementVisitor {
|
|||||||
private final boolean myEnabledShortCircuit;
|
private final boolean myEnabledShortCircuit;
|
||||||
// true if evaluate constant expression inside 'if' statement condition and alter control flow accordingly
|
// true if evaluate constant expression inside 'if' statement condition and alter control flow accordingly
|
||||||
// in case of unreachable statement analysis must be false
|
// in case of unreachable statement analysis must be false
|
||||||
private final boolean myEvaluateConstantIfConfition;
|
private final boolean myEvaluateConstantIfCondition;
|
||||||
private final boolean myAssignmentTargetsAreElements;
|
private final boolean myAssignmentTargetsAreElements;
|
||||||
|
|
||||||
private final Stack<TIntArrayList> intArrayPool = new Stack<TIntArrayList>();
|
private final Stack<TIntArrayList> intArrayPool = new Stack<TIntArrayList>();
|
||||||
// map: PsiElement element -> TIntArrayList instructionOffsetsToPatch with getStartoffset(element)
|
// map: PsiElement element -> TIntArrayList instructionOffsetsToPatch with getStartOffset(element)
|
||||||
private final Map<PsiElement,TIntArrayList> offsetsAddElementStart = new THashMap<PsiElement, TIntArrayList>();
|
private final Map<PsiElement,TIntArrayList> offsetsAddElementStart = new THashMap<PsiElement, TIntArrayList>();
|
||||||
// map: PsiElement element -> TIntArrayList instructionOffsetsToPatch with getEndOffset(element)
|
// map: PsiElement element -> TIntArrayList instructionOffsetsToPatch with getEndOffset(element)
|
||||||
private final Map<PsiElement,TIntArrayList> offsetsAddElementEnd = new THashMap<PsiElement, TIntArrayList>();
|
private final Map<PsiElement,TIntArrayList> offsetsAddElementEnd = new THashMap<PsiElement, TIntArrayList>();
|
||||||
@@ -78,19 +79,19 @@ class ControlFlowAnalyzer extends JavaJspElementVisitor {
|
|||||||
ControlFlowAnalyzer(@NotNull PsiElement codeFragment,
|
ControlFlowAnalyzer(@NotNull PsiElement codeFragment,
|
||||||
@NotNull ControlFlowPolicy policy,
|
@NotNull ControlFlowPolicy policy,
|
||||||
boolean enabledShortCircuit,
|
boolean enabledShortCircuit,
|
||||||
boolean evaluateConstantIfConfition) {
|
boolean evaluateConstantIfCondition) {
|
||||||
this(codeFragment, policy, enabledShortCircuit, evaluateConstantIfConfition, false);
|
this(codeFragment, policy, enabledShortCircuit, evaluateConstantIfCondition, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ControlFlowAnalyzer(@NotNull PsiElement codeFragment,
|
private ControlFlowAnalyzer(@NotNull PsiElement codeFragment,
|
||||||
@NotNull ControlFlowPolicy policy,
|
@NotNull ControlFlowPolicy policy,
|
||||||
boolean enabledShortCircuit,
|
boolean enabledShortCircuit,
|
||||||
boolean evaluateConstantIfConfition,
|
boolean evaluateConstantIfCondition,
|
||||||
boolean assignmentTargetsAreElements) {
|
boolean assignmentTargetsAreElements) {
|
||||||
myCodeFragment = codeFragment;
|
myCodeFragment = codeFragment;
|
||||||
myPolicy = policy;
|
myPolicy = policy;
|
||||||
myEnabledShortCircuit = enabledShortCircuit;
|
myEnabledShortCircuit = enabledShortCircuit;
|
||||||
myEvaluateConstantIfConfition = evaluateConstantIfConfition;
|
myEvaluateConstantIfCondition = evaluateConstantIfCondition;
|
||||||
myAssignmentTargetsAreElements = assignmentTargetsAreElements;
|
myAssignmentTargetsAreElements = assignmentTargetsAreElements;
|
||||||
Project project = codeFragment.getProject();
|
Project project = codeFragment.getProject();
|
||||||
myControlFlowFactory = ControlFlowFactory.getInstance(project);
|
myControlFlowFactory = ControlFlowFactory.getInstance(project);
|
||||||
@@ -205,7 +206,7 @@ class ControlFlowAnalyzer extends JavaJspElementVisitor {
|
|||||||
ProgressManager.checkCanceled();
|
ProgressManager.checkCanceled();
|
||||||
ControlFlowSubRange subRange = entry.getValue();
|
ControlFlowSubRange subRange = entry.getValue();
|
||||||
PsiElement element = entry.getKey();
|
PsiElement element = entry.getKey();
|
||||||
myControlFlowFactory.registerSubRange(element, subRange, myEvaluateConstantIfConfition, myPolicy);
|
myControlFlowFactory.registerSubRange(element, subRange, myEvaluateConstantIfCondition, myPolicy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -730,7 +731,7 @@ class ControlFlowAnalyzer extends JavaJspElementVisitor {
|
|||||||
* [ generate (B) ]
|
* [ generate (B) ]
|
||||||
* :end
|
* :end
|
||||||
*/
|
*/
|
||||||
if (myEvaluateConstantIfConfition) {
|
if (myEvaluateConstantIfCondition) {
|
||||||
final Object value = myConstantEvaluationHelper.computeConstantExpression(conditionExpression);
|
final Object value = myConstantEvaluationHelper.computeConstantExpression(conditionExpression);
|
||||||
if (value instanceof Boolean) {
|
if (value instanceof Boolean) {
|
||||||
boolean condition = ((Boolean)value).booleanValue();
|
boolean condition = ((Boolean)value).booleanValue();
|
||||||
@@ -928,7 +929,7 @@ class ControlFlowAnalyzer extends JavaJspElementVisitor {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* find offsets of catch(es) corresponding to this throw statement
|
* find offsets of catch(es) corresponding to this throw statement
|
||||||
* mycatchParameters and mycatchpoints arrays should be sorted in ascending scope order (from outermost to innermost)
|
* myCatchParameters and myCatchBlocks arrays should be sorted in ascending scope order (from outermost to innermost)
|
||||||
*
|
*
|
||||||
* @return offset or -1 if not found
|
* @return offset or -1 if not found
|
||||||
*/
|
*/
|
||||||
@@ -946,12 +947,9 @@ class ControlFlowAnalyzer extends JavaJspElementVisitor {
|
|||||||
ProgressManager.checkCanceled();
|
ProgressManager.checkCanceled();
|
||||||
PsiParameter parameter = myCatchParameters.get(i);
|
PsiParameter parameter = myCatchParameters.get(i);
|
||||||
final PsiType type = parameter.getType();
|
final PsiType type = parameter.getType();
|
||||||
PsiClass catchedClass = PsiUtil.resolveClassInType(type);
|
PsiClass caughtClass = PsiUtil.resolveClassInType(type);
|
||||||
if (catchedClass == null) continue;
|
if (caughtClass == null) continue;
|
||||||
if (type.isAssignableFrom(throwType)) {
|
if (type.isAssignableFrom(throwType) || throwType.isAssignableFrom(type)) {
|
||||||
blocks.add(myCatchBlocks.get(i));
|
|
||||||
}
|
|
||||||
else if (throwType.isAssignableFrom(type)) {
|
|
||||||
blocks.add(myCatchBlocks.get(i));
|
blocks.add(myCatchBlocks.get(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -996,7 +994,8 @@ class ControlFlowAnalyzer extends JavaJspElementVisitor {
|
|||||||
finishElement(statement);
|
finishElement(statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void visitTryStatement(PsiTryStatement statement) {
|
@Override
|
||||||
|
public void visitTryStatement(PsiTryStatement statement) {
|
||||||
startElement(statement);
|
startElement(statement);
|
||||||
|
|
||||||
PsiCodeBlock[] catchBlocks = statement.getCatchBlocks();
|
PsiCodeBlock[] catchBlocks = statement.getCatchBlocks();
|
||||||
@@ -1010,7 +1009,8 @@ class ControlFlowAnalyzer extends JavaJspElementVisitor {
|
|||||||
|
|
||||||
final PsiType type = catchBlockParameters[i].getType();
|
final PsiType type = catchBlockParameters[i].getType();
|
||||||
// todo cast param
|
// todo cast param
|
||||||
if (type instanceof PsiClassType && ExceptionUtil.isUncheckedExceptionOrSuperclass((PsiClassType)type)) {
|
if (type instanceof PsiClassType && ExceptionUtil.isUncheckedExceptionOrSuperclass((PsiClassType)type) ||
|
||||||
|
type instanceof PsiDisjunctionType && ExceptionUtil.isUncheckedExceptionOrSuperclass(((PsiDisjunctionType)type).getLeastUpperBound())) {
|
||||||
myUnhandledExceptionCatchBlocks.push(catchBlocks[i]);
|
myUnhandledExceptionCatchBlocks.push(catchBlocks[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1028,6 +1028,7 @@ class ControlFlowAnalyzer extends JavaJspElementVisitor {
|
|||||||
tryBlock.accept(this);
|
tryBlock.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//noinspection StatementWithEmptyBody
|
||||||
while (myUnhandledExceptionCatchBlocks.pop() != null) ;
|
while (myUnhandledExceptionCatchBlocks.pop() != null) ;
|
||||||
|
|
||||||
myCurrentFlow.addInstruction(new GoToInstruction(finallyBlock == null ? 0 : -6));
|
myCurrentFlow.addInstruction(new GoToInstruction(finallyBlock == null ? 0 : -6));
|
||||||
@@ -1361,7 +1362,7 @@ class ControlFlowAnalyzer extends JavaJspElementVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean shouldCalculateConstantExpression(PsiExpression expression) {
|
private boolean shouldCalculateConstantExpression(PsiExpression expression) {
|
||||||
return myEvaluateConstantIfConfition || !isInsideIfCondition(expression);
|
return myEvaluateConstantIfCondition || !isInsideIfCondition(expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void visitClassObjectAccessExpression(PsiClassObjectAccessExpression expression) {
|
@Override public void visitClassObjectAccessExpression(PsiClassObjectAccessExpression expression) {
|
||||||
@@ -1576,6 +1577,7 @@ class ControlFlowAnalyzer extends JavaJspElementVisitor {
|
|||||||
myCurrentFlow.addInstruction(instruction);
|
myCurrentFlow.addInstruction(instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private PsiVariable getUsedVariable(PsiReferenceExpression refExpr) {
|
private PsiVariable getUsedVariable(PsiReferenceExpression refExpr) {
|
||||||
if (refExpr.getParent() instanceof PsiMethodCallExpression) return null;
|
if (refExpr.getParent() instanceof PsiMethodCallExpression) return null;
|
||||||
return myPolicy.getUsedVariable(refExpr);
|
return myPolicy.getUsedVariable(refExpr);
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import com.intellij.psi.impl.source.SourceTreeToPsiMap;
|
|||||||
import com.intellij.psi.impl.source.tree.TreeElement;
|
import com.intellij.psi.impl.source.tree.TreeElement;
|
||||||
import com.intellij.psi.javadoc.PsiDocComment;
|
import com.intellij.psi.javadoc.PsiDocComment;
|
||||||
import com.intellij.psi.javadoc.PsiDocTag;
|
import com.intellij.psi.javadoc.PsiDocTag;
|
||||||
|
import com.intellij.psi.util.PsiUtil;
|
||||||
import com.intellij.util.IncorrectOperationException;
|
import com.intellij.util.IncorrectOperationException;
|
||||||
import com.intellij.util.containers.HashMap;
|
import com.intellij.util.containers.HashMap;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -60,7 +61,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
|||||||
private static final JavaParserUtil.ParserWrapper PARAMETER = new JavaParserUtil.ParserWrapper() {
|
private static final JavaParserUtil.ParserWrapper PARAMETER = new JavaParserUtil.ParserWrapper() {
|
||||||
@Override
|
@Override
|
||||||
public void parse(final PsiBuilder builder) {
|
public void parse(final PsiBuilder builder) {
|
||||||
DeclarationParser.parseParameter(builder, true);
|
DeclarationParser.parseParameter(builder, true, false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -71,6 +72,14 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static final JavaParserUtil.ParserWrapper DISJUNCTIVE_TYPE = new JavaParserUtil.ParserWrapper() {
|
||||||
|
@Override
|
||||||
|
public void parse(final PsiBuilder builder) {
|
||||||
|
ReferenceParser.parseType(builder, ReferenceParser.EAT_LAST_DOT | ReferenceParser.ELLIPSIS |
|
||||||
|
ReferenceParser.WILDCARD | ReferenceParser.DISJUNCTIONS);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public static final JavaParserUtil.ParserWrapper REFERENCE = new JavaParserUtil.ParserWrapper() {
|
public static final JavaParserUtil.ParserWrapper REFERENCE = new JavaParserUtil.ParserWrapper() {
|
||||||
@Override
|
@Override
|
||||||
public void parse(final PsiBuilder builder) {
|
public void parse(final PsiBuilder builder) {
|
||||||
@@ -240,7 +249,11 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public PsiTypeElement createTypeElementFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
public PsiTypeElement createTypeElementFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||||
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, TYPE, false), context);
|
final boolean multiCatch = context instanceof PsiParameter &&
|
||||||
|
context.getParent() instanceof PsiCatchSection &&
|
||||||
|
PsiUtil.isLanguageLevel7OrHigher(context);
|
||||||
|
final JavaParserUtil.ParserWrapper wrapper = multiCatch ? DISJUNCTIVE_TYPE : TYPE;
|
||||||
|
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, wrapper, false), context);
|
||||||
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
|
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
|
||||||
if (!(element instanceof PsiTypeElement)) {
|
if (!(element instanceof PsiTypeElement)) {
|
||||||
throw new IncorrectOperationException("Incorrect type \"" + text + "\".");
|
throw new IncorrectOperationException("Incorrect type \"" + text + "\".");
|
||||||
@@ -261,7 +274,8 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public PsiJavaCodeReferenceElement createReferenceFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
public PsiJavaCodeReferenceElement createReferenceFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||||
final boolean isStaticImport = context instanceof PsiImportStaticStatement && !((PsiImportStaticStatement)context).isOnDemand();
|
final boolean isStaticImport = context instanceof PsiImportStaticStatement &&
|
||||||
|
!((PsiImportStaticStatement)context).isOnDemand();
|
||||||
final JavaParserUtil.ParserWrapper wrapper = isStaticImport ? STATIC_IMPORT_REF : REFERENCE;
|
final JavaParserUtil.ParserWrapper wrapper = isStaticImport ? STATIC_IMPORT_REF : REFERENCE;
|
||||||
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, wrapper, false), context);
|
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, wrapper, false), context);
|
||||||
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
|
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
|
||||||
|
|||||||
@@ -174,6 +174,9 @@ public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (parent instanceof PsiParameter) {
|
||||||
|
if (type == JavaTokenType.FINAL_KEYWORD && ((PsiParameter)parent).getType() instanceof PsiDisjunctionType) return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (type == null){ // package local
|
if (type == null){ // package local
|
||||||
return !hasModifierProperty(PsiModifier.PUBLIC) && !hasModifierProperty(PsiModifier.PRIVATE) && !hasModifierProperty(PsiModifier.PROTECTED);
|
return !hasModifierProperty(PsiModifier.PUBLIC) && !hasModifierProperty(PsiModifier.PRIVATE) && !hasModifierProperty(PsiModifier.PROTECTED);
|
||||||
@@ -206,22 +209,22 @@ public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub>
|
|||||||
if (value){
|
if (value){
|
||||||
if (parentTreeElement.getElementType() == JavaElementType.FIELD &&
|
if (parentTreeElement.getElementType() == JavaElementType.FIELD &&
|
||||||
parentTreeElement.getTreeParent().getElementType() == JavaElementType.CLASS &&
|
parentTreeElement.getTreeParent().getElementType() == JavaElementType.CLASS &&
|
||||||
((PsiClass)SourceTreeToPsiMap.treeElementToPsi(parentTreeElement.getTreeParent())).isInterface()) {
|
SourceTreeToPsiMap.<PsiClass>treeToPsiNotNull(parentTreeElement.getTreeParent()).isInterface()) {
|
||||||
if (type == JavaTokenType.PUBLIC_KEYWORD || type == JavaTokenType.STATIC_KEYWORD || type == JavaTokenType.FINAL_KEYWORD) return;
|
if (type == JavaTokenType.PUBLIC_KEYWORD || type == JavaTokenType.STATIC_KEYWORD || type == JavaTokenType.FINAL_KEYWORD) return;
|
||||||
}
|
}
|
||||||
else if (parentTreeElement.getElementType() == JavaElementType.METHOD &&
|
else if (parentTreeElement.getElementType() == JavaElementType.METHOD &&
|
||||||
parentTreeElement.getTreeParent().getElementType() == JavaElementType.CLASS &&
|
parentTreeElement.getTreeParent().getElementType() == JavaElementType.CLASS &&
|
||||||
((PsiClass)SourceTreeToPsiMap.treeElementToPsi(parentTreeElement.getTreeParent())).isInterface()) {
|
SourceTreeToPsiMap.<PsiClass>treeToPsiNotNull(parentTreeElement.getTreeParent()).isInterface()) {
|
||||||
if (type == JavaTokenType.PUBLIC_KEYWORD || type == JavaTokenType.ABSTRACT_KEYWORD) return;
|
if (type == JavaTokenType.PUBLIC_KEYWORD || type == JavaTokenType.ABSTRACT_KEYWORD) return;
|
||||||
}
|
}
|
||||||
else if (parentTreeElement.getElementType() == JavaElementType.CLASS &&
|
else if (parentTreeElement.getElementType() == JavaElementType.CLASS &&
|
||||||
parentTreeElement.getTreeParent().getElementType() == JavaElementType.CLASS &&
|
parentTreeElement.getTreeParent().getElementType() == JavaElementType.CLASS &&
|
||||||
((PsiClass)SourceTreeToPsiMap.treeElementToPsi(parentTreeElement.getTreeParent())).isInterface()) {
|
SourceTreeToPsiMap.<PsiClass>treeToPsiNotNull(parentTreeElement.getTreeParent()).isInterface()) {
|
||||||
if (type == JavaTokenType.PUBLIC_KEYWORD) return;
|
if (type == JavaTokenType.PUBLIC_KEYWORD) return;
|
||||||
}
|
}
|
||||||
else if (parentTreeElement.getElementType() == JavaElementType.ANNOTATION_METHOD &&
|
else if (parentTreeElement.getElementType() == JavaElementType.ANNOTATION_METHOD &&
|
||||||
parentTreeElement.getTreeParent().getElementType() == JavaElementType.CLASS &&
|
parentTreeElement.getTreeParent().getElementType() == JavaElementType.CLASS &&
|
||||||
((PsiClass)SourceTreeToPsiMap.treeElementToPsi(parentTreeElement.getTreeParent())).isAnnotationType()) {
|
SourceTreeToPsiMap.<PsiClass>treeToPsiNotNull(parentTreeElement.getTreeParent()).isAnnotationType()) {
|
||||||
if (type == JavaTokenType.PUBLIC_KEYWORD || type == JavaTokenType.ABSTRACT_KEYWORD) return;
|
if (type == JavaTokenType.PUBLIC_KEYWORD || type == JavaTokenType.ABSTRACT_KEYWORD) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,8 +249,8 @@ public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub>
|
|||||||
TreeElement keyword = Factory.createSingleLeafElement(type, name, null, getManager());
|
TreeElement keyword = Factory.createSingleLeafElement(type, name, null, getManager());
|
||||||
treeElement.addInternal(keyword, keyword, null, null);
|
treeElement.addInternal(keyword, keyword, null, null);
|
||||||
}
|
}
|
||||||
if ((type == JavaTokenType.ABSTRACT_KEYWORD || type == JavaTokenType.NATIVE_KEYWORD) && parentTreeElement.getElementType() ==
|
if ((type == JavaTokenType.ABSTRACT_KEYWORD || type == JavaTokenType.NATIVE_KEYWORD) &&
|
||||||
JavaElementType.METHOD){
|
parentTreeElement.getElementType() == JavaElementType.METHOD){
|
||||||
//Q: remove body?
|
//Q: remove body?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -257,7 +260,7 @@ public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub>
|
|||||||
}
|
}
|
||||||
ASTNode child = treeElement.findChildByType(type);
|
ASTNode child = treeElement.findChildByType(type);
|
||||||
if (child != null){
|
if (child != null){
|
||||||
SourceTreeToPsiMap.treeElementToPsi(child).delete();
|
SourceTreeToPsiMap.treeToPsiNotNull(child).delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import com.intellij.util.PatchedSoftReference;
|
|||||||
import com.intellij.util.SmartList;
|
import com.intellij.util.SmartList;
|
||||||
import org.jetbrains.annotations.NonNls;
|
import org.jetbrains.annotations.NonNls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -41,6 +42,7 @@ import java.util.List;
|
|||||||
|
|
||||||
public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeElement {
|
public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeElement {
|
||||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiTypeElementImpl");
|
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiTypeElementImpl");
|
||||||
|
|
||||||
private volatile PsiType myCachedType = null;
|
private volatile PsiType myCachedType = null;
|
||||||
private volatile PatchedSoftReference<PsiType> myCachedDetachedType = null;
|
private volatile PatchedSoftReference<PsiType> myCachedDetachedType = null;
|
||||||
|
|
||||||
@@ -78,26 +80,36 @@ public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeEl
|
|||||||
if (cachedType != null) {
|
if (cachedType != null) {
|
||||||
return cachedType;
|
return cachedType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final List<PsiAnnotation> typeAnnotations = new ArrayList<PsiAnnotation>();
|
||||||
TreeElement element = getFirstChildNode();
|
TreeElement element = getFirstChildNode();
|
||||||
List<PsiAnnotation> typeAnnos = new ArrayList<PsiAnnotation>();
|
|
||||||
while (element != null) {
|
while (element != null) {
|
||||||
IElementType elementType = element.getElementType();
|
IElementType elementType = element.getElementType();
|
||||||
if (element.getTreeNext() == null && ElementType.PRIMITIVE_TYPE_BIT_SET.contains(elementType)) {
|
if (element.getTreeNext() == null && ElementType.PRIMITIVE_TYPE_BIT_SET.contains(elementType)) {
|
||||||
addTypeUseAnnotationsFromModifierList(getParent(), typeAnnos);
|
addTypeUseAnnotationsFromModifierList(getParent(), typeAnnotations);
|
||||||
PsiAnnotation[] array = toAnnotationsArray(typeAnnos);
|
final PsiAnnotation[] array = toAnnotationsArray(typeAnnotations);
|
||||||
|
|
||||||
cachedType = JavaPsiFacade.getInstance(getProject()).getElementFactory().createPrimitiveType(element.getText(), array);
|
cachedType = JavaPsiFacade.getInstance(getProject()).getElementFactory().createPrimitiveType(element.getText(), array);
|
||||||
assert cachedType != null;
|
assert cachedType != null;
|
||||||
}
|
}
|
||||||
else if (elementType == JavaElementType.TYPE) {
|
else if (elementType == JavaElementType.TYPE) {
|
||||||
PsiType componentType = ((PsiTypeElement)SourceTreeToPsiMap.treeElementToPsi(element)).getType();
|
final IElementType tailType = getLastChildNode().getElementType();
|
||||||
cachedType = getLastChildNode().getElementType() == JavaTokenType.ELLIPSIS ? new PsiEllipsisType(componentType)
|
if (tailType == JavaTokenType.ELLIPSIS) {
|
||||||
: componentType.createArrayType();
|
final PsiType componentType = ((PsiTypeElement)SourceTreeToPsiMap.treeToPsiNotNull(element)).getType();
|
||||||
|
cachedType = new PsiEllipsisType(componentType);
|
||||||
|
}
|
||||||
|
else if (tailType == JavaTokenType.RBRACKET) {
|
||||||
|
final PsiType componentType = ((PsiTypeElement)SourceTreeToPsiMap.treeToPsiNotNull(element)).getType();
|
||||||
|
cachedType = componentType.createArrayType();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cachedType = new PsiDisjunctionType(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (elementType == JavaElementType.JAVA_CODE_REFERENCE) {
|
else if (elementType == JavaElementType.JAVA_CODE_REFERENCE) {
|
||||||
addTypeUseAnnotationsFromModifierList(getParent(), typeAnnos);
|
addTypeUseAnnotationsFromModifierList(getParent(), typeAnnotations);
|
||||||
PsiAnnotation[] array = toAnnotationsArray(typeAnnos);
|
final PsiAnnotation[] array = toAnnotationsArray(typeAnnotations);
|
||||||
cachedType = new PsiClassReferenceType((PsiJavaCodeReferenceElement)element.getPsi(), null,array);
|
final PsiJavaCodeReferenceElement reference = SourceTreeToPsiMap.treeToPsiNotNull(element);
|
||||||
|
cachedType = new PsiClassReferenceType(reference, null, array);
|
||||||
}
|
}
|
||||||
else if (elementType == JavaTokenType.QUEST) {
|
else if (elementType == JavaTokenType.QUEST) {
|
||||||
cachedType = createWildcardType();
|
cachedType = createWildcardType();
|
||||||
@@ -107,8 +119,9 @@ public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeEl
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (elementType == JavaElementType.ANNOTATION) {
|
else if (elementType == JavaElementType.ANNOTATION) {
|
||||||
PsiAnnotation annotation = JavaPsiFacade.getInstance(getProject()).getElementFactory().createAnnotationFromText(element.getText(), this);
|
final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(getProject()).getElementFactory();
|
||||||
typeAnnos.add(annotation);
|
final PsiAnnotation annotation = elementFactory.createAnnotationFromText(element.getText(), this);
|
||||||
|
typeAnnotations.add(annotation);
|
||||||
element = element.getTreeNext();
|
element = element.getTreeNext();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -128,18 +141,18 @@ public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeEl
|
|||||||
return cachedType;
|
return cachedType;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PsiAnnotation[] toAnnotationsArray(List<PsiAnnotation> typeAnnos) {
|
private static PsiAnnotation[] toAnnotationsArray(List<PsiAnnotation> typeAnnotations) {
|
||||||
final int size = typeAnnos.size();
|
final int size = typeAnnotations.size();
|
||||||
return size == 0 ? PsiAnnotation.EMPTY_ARRAY : typeAnnos.toArray(new PsiAnnotation[size]);
|
return size == 0 ? PsiAnnotation.EMPTY_ARRAY : typeAnnotations.toArray(new PsiAnnotation[size]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addTypeUseAnnotationsFromModifierList(PsiElement member, List<PsiAnnotation> typeAnnos) {
|
public static void addTypeUseAnnotationsFromModifierList(PsiElement member, List<PsiAnnotation> typeAnnotations) {
|
||||||
if (!(member instanceof PsiModifierListOwner)) return;
|
if (!(member instanceof PsiModifierListOwner)) return;
|
||||||
PsiModifierList list = ((PsiModifierListOwner)member).getModifierList();
|
PsiModifierList list = ((PsiModifierListOwner)member).getModifierList();
|
||||||
PsiAnnotation[] gluedAnnos = list == null ? PsiAnnotation.EMPTY_ARRAY : list.getAnnotations();
|
PsiAnnotation[] gluedAnnotations = list == null ? PsiAnnotation.EMPTY_ARRAY : list.getAnnotations();
|
||||||
for (PsiAnnotation anno : gluedAnnos) {
|
for (PsiAnnotation anno : gluedAnnotations) {
|
||||||
if (AnnotationsHighlightUtil.isAnnotationApplicableTo(anno, false, "TYPE_USE")) {
|
if (AnnotationsHighlightUtil.isAnnotationApplicableTo(anno, false, "TYPE_USE")) {
|
||||||
typeAnnos.add(anno);
|
typeAnnotations.add(anno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -149,8 +162,8 @@ public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeEl
|
|||||||
PsiType type = cached == null ? null : cached.get();
|
PsiType type = cached == null ? null : cached.get();
|
||||||
if (type != null) return type;
|
if (type != null) return type;
|
||||||
try {
|
try {
|
||||||
String combinedAnnos = getCombinedAnnosText();
|
String combinedAnnotations = getCombinedAnnotationsText();
|
||||||
String text = combinedAnnos.length() == 0 ? getText().trim() : combinedAnnos + " " + getText().trim();
|
String text = combinedAnnotations.length() == 0 ? getText().trim() : combinedAnnotations + " " + getText().trim();
|
||||||
type = JavaPsiFacade.getInstance(getProject()).getElementFactory().createTypeFromText(text, context);
|
type = JavaPsiFacade.getInstance(getProject()).getElementFactory().createTypeFromText(text, context);
|
||||||
myCachedDetachedType = new PatchedSoftReference<PsiType>(type);
|
myCachedDetachedType = new PatchedSoftReference<PsiType>(type);
|
||||||
}
|
}
|
||||||
@@ -161,7 +174,7 @@ public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeEl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private String getCombinedAnnosText() {
|
private String getCombinedAnnotationsText() {
|
||||||
final boolean typeAnnotationsSupported = PsiUtil.isLanguageLevel8OrHigher(this);
|
final boolean typeAnnotationsSupported = PsiUtil.isLanguageLevel8OrHigher(this);
|
||||||
if (!typeAnnotationsSupported) return "";
|
if (!typeAnnotationsSupported) return "";
|
||||||
return StringUtil.join(getApplicableAnnotations(), ANNOTATION_TEXT, " ");
|
return StringUtil.join(getApplicableAnnotations(), ANNOTATION_TEXT, " ");
|
||||||
@@ -177,8 +190,8 @@ public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeEl
|
|||||||
PsiFile file = getContainingFile();
|
PsiFile file = getContainingFile();
|
||||||
String text;
|
String text;
|
||||||
if (PsiUtil.isLanguageLevel8OrHigher(file)) {
|
if (PsiUtil.isLanguageLevel8OrHigher(file)) {
|
||||||
String combinedAnnos = StringUtil.join(getAnnotations(), ANNOTATION_TEXT, " ");
|
String combinedAnnotations = StringUtil.join(getAnnotations(), ANNOTATION_TEXT, " ");
|
||||||
text = combinedAnnos.length() == 0 ? getText().trim() : combinedAnnos + " " + getText().trim();
|
text = combinedAnnotations.length() == 0 ? getText().trim() : combinedAnnotations + " " + getText().trim();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
text = getText().trim();
|
text = getText().trim();
|
||||||
@@ -201,7 +214,7 @@ public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeEl
|
|||||||
temp = PsiWildcardType.createUnbounded(getManager());
|
temp = PsiWildcardType.createUnbounded(getManager());
|
||||||
}
|
}
|
||||||
else if (getLastChildNode().getElementType() == JavaElementType.TYPE) {
|
else if (getLastChildNode().getElementType() == JavaElementType.TYPE) {
|
||||||
PsiTypeElement bound = (PsiTypeElement)SourceTreeToPsiMap.treeElementToPsi(getLastChildNode());
|
PsiTypeElement bound = SourceTreeToPsiMap.treeToPsiNotNull(getLastChildNode());
|
||||||
ASTNode keyword = getFirstChildNode();
|
ASTNode keyword = getFirstChildNode();
|
||||||
while (keyword != null &&
|
while (keyword != null &&
|
||||||
keyword.getElementType() != JavaTokenType.EXTENDS_KEYWORD &&
|
keyword.getElementType() != JavaTokenType.EXTENDS_KEYWORD &&
|
||||||
@@ -235,7 +248,7 @@ public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeEl
|
|||||||
TreeElement firstChildNode = getFirstChildNode();
|
TreeElement firstChildNode = getFirstChildNode();
|
||||||
if (firstChildNode == null) return null;
|
if (firstChildNode == null) return null;
|
||||||
if (firstChildNode.getElementType() == JavaElementType.TYPE) {
|
if (firstChildNode.getElementType() == JavaElementType.TYPE) {
|
||||||
return ((PsiTypeElement)SourceTreeToPsiMap.treeElementToPsi(firstChildNode)).getInnermostComponentReferenceElement();
|
return SourceTreeToPsiMap.<PsiTypeElement>treeToPsiNotNull(firstChildNode).getInnermostComponentReferenceElement();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return getReferenceElement();
|
return getReferenceElement();
|
||||||
@@ -245,12 +258,12 @@ public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeEl
|
|||||||
public PsiAnnotationOwner getOwner(PsiAnnotation annotation) {
|
public PsiAnnotationOwner getOwner(PsiAnnotation annotation) {
|
||||||
PsiElement next = PsiTreeUtil.skipSiblingsForward(annotation, PsiComment.class, PsiWhiteSpace.class);
|
PsiElement next = PsiTreeUtil.skipSiblingsForward(annotation, PsiComment.class, PsiWhiteSpace.class);
|
||||||
if (next != null && next.getNode().getElementType() == JavaTokenType.LBRACKET) {
|
if (next != null && next.getNode().getElementType() == JavaTokenType.LBRACKET) {
|
||||||
PsiType type = getType();
|
return getType(); // annotation belongs to array type dimension
|
||||||
return type; // annotation belongs to array type dimension
|
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private PsiJavaCodeReferenceElement getReferenceElement() {
|
private PsiJavaCodeReferenceElement getReferenceElement() {
|
||||||
ASTNode ref = findChildByType(JavaElementType.JAVA_CODE_REFERENCE);
|
ASTNode ref = findChildByType(JavaElementType.JAVA_CODE_REFERENCE);
|
||||||
if (ref == null) return null;
|
if (ref == null) return null;
|
||||||
@@ -337,4 +350,3 @@ public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeEl
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -465,8 +465,13 @@ public class JavaCodeStyleManagerImpl extends JavaCodeStyleManager {
|
|||||||
return getTypeName(((PsiCapturedWildcardType)type).getWildcard());
|
return getTypeName(((PsiCapturedWildcardType)type).getWildcard());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LOG.error("Unknown type:" + type);
|
if (type instanceof PsiDisjunctionType) {
|
||||||
return null;
|
return getTypeName(((PsiDisjunctionType)type).getLeastUpperBound());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG.error("Unknown type:" + type);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -474,8 +479,8 @@ public class JavaCodeStyleManagerImpl extends JavaCodeStyleManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable private static
|
@Nullable
|
||||||
String getLongTypeName(PsiType type) {
|
private static String getLongTypeName(PsiType type) {
|
||||||
if (type instanceof PsiClassType) {
|
if (type instanceof PsiClassType) {
|
||||||
PsiClass aClass = ((PsiClassType)type).resolve();
|
PsiClass aClass = ((PsiClassType)type).resolve();
|
||||||
if( aClass == null )
|
if( aClass == null )
|
||||||
@@ -525,8 +530,13 @@ public class JavaCodeStyleManagerImpl extends JavaCodeStyleManager {
|
|||||||
return getLongTypeName(((PsiIntersectionType)type).getRepresentative());
|
return getLongTypeName(((PsiIntersectionType)type).getRepresentative());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LOG.error("Unknown type:" + type);
|
if (type instanceof PsiDisjunctionType) {
|
||||||
return null;
|
return getLongTypeName(((PsiDisjunctionType)type).getLeastUpperBound());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG.error("Unknown type:" + type);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -291,6 +291,9 @@ public class PsiScopesUtil {
|
|||||||
if (!processQualifierType(conjunct, processor, manager, methodCall)) break;
|
if (!processQualifierType(conjunct, processor, manager, methodCall)) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (type instanceof PsiDisjunctionType) {
|
||||||
|
processQualifierType(((PsiDisjunctionType)type).getLeastUpperBound(), processor, manager, methodCall);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
processQualifierType(type, processor, manager, methodCall);
|
processQualifierType(type, processor, manager, methodCall);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
abstract class C {
|
||||||
|
private static class NE { }
|
||||||
|
private static class E extends Exception { }
|
||||||
|
private static class E1 extends E { }
|
||||||
|
private static class E2 extends E { }
|
||||||
|
private static class E3 extends E { }
|
||||||
|
private static class RE extends RuntimeException { }
|
||||||
|
|
||||||
|
abstract void f() throws E1, E2;
|
||||||
|
|
||||||
|
void m() {
|
||||||
|
try { f(); } catch (E1 | E2 e) { }
|
||||||
|
try { f(); } catch (E2 | E e) { e.printStackTrace(); }
|
||||||
|
try { f(); } catch (E2 | E1 e) { } catch (E e) { } catch (RE e) { }
|
||||||
|
try { f(); } catch (E1 | E e) { E ee = e; }
|
||||||
|
|
||||||
|
try { f(); } catch (E1 | E2 | <error descr="Exception 'C.E3' is never thrown in the corresponding try block">E3</error> e) { }
|
||||||
|
try { f(); } catch (<error descr="Exception 'C.E3' is never thrown in the corresponding try block">E3</error> | E e) { }
|
||||||
|
|
||||||
|
try { f(); } catch (E | <error descr="Exception 'C.E1' has already been caught">E1</error> e) { }
|
||||||
|
try { f(); } catch (E | <error descr="Exception 'C.E3' has already been caught">E3</error> e) { }
|
||||||
|
try { f(); } catch (E e) { } catch (<error descr="Exception 'C.E1' has already been caught">E1</error> | <error descr="Exception 'C.E3' has already been caught">E3</error> e) { }
|
||||||
|
try { f(); } catch (E1 | E e) { } catch (<error descr="Exception 'C.E2' has already been caught">E2</error> e) { }
|
||||||
|
|
||||||
|
try { f(); } catch (E1 | E2 e) { } catch (E e) { <error descr="Incompatible types. Found: 'C.E', required: 'C.E1'">E1 ee = e;</error> }
|
||||||
|
try { } catch (<error descr="Incompatible types. Found: 'C.RE | C.NE', required: 'java.lang.Throwable'">RE | <error descr="Exception 'C.NE' is never thrown in the corresponding try block">NE</error> e</error>) { }
|
||||||
|
try { f(); } catch (E | RE e) { <error descr="Cannot assign a value to final variable 'e'">e = null</error>; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
// "Delete catch for 'java.io.IOException'" "true"
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
class C {
|
||||||
|
void m() {
|
||||||
|
try {
|
||||||
|
int p = 0;
|
||||||
|
}
|
||||||
|
catch (/*somethihg*/ RuntimeException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
// "Delete catch for 'java.io.FileNotFoundException'" "true"
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
class C {
|
||||||
|
void m() {
|
||||||
|
try {
|
||||||
|
int p = 0;
|
||||||
|
}
|
||||||
|
catch (IOException /*somethihg*/ e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
// "Delete catch for 'java.io.FileNotFoundException'" "true"
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
class C {
|
||||||
|
void m() {
|
||||||
|
try {
|
||||||
|
int p = 0;
|
||||||
|
}
|
||||||
|
catch (IOException | RuntimeException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
// "Delete catch for 'java.io.IOException'" "true"
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
class C {
|
||||||
|
void m() {
|
||||||
|
try {
|
||||||
|
int p = 0;
|
||||||
|
}
|
||||||
|
catch (<caret>IOException | /*somethihg*/ RuntimeException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
// "Delete catch for 'java.io.FileNotFoundException'" "true"
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
class C {
|
||||||
|
void m() {
|
||||||
|
try {
|
||||||
|
int p = 0;
|
||||||
|
}
|
||||||
|
catch (IOException | <caret>FileNotFoundException /*somethihg*/ e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
// "Delete catch for 'java.io.FileNotFoundException'" "true"
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
class C {
|
||||||
|
void m() {
|
||||||
|
try {
|
||||||
|
int p = 0;
|
||||||
|
}
|
||||||
|
catch (IOException | <caret>FileNotFoundException | RuntimeException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
class A{
|
||||||
|
{
|
||||||
|
try{}catch(E| e){}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
PsiJavaFile:Incomplete9.java
|
||||||
|
PsiImportList
|
||||||
|
<empty list>
|
||||||
|
PsiClass:A
|
||||||
|
PsiModifierList:
|
||||||
|
<empty list>
|
||||||
|
PsiKeyword:class('class')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiIdentifier:A('A')
|
||||||
|
PsiTypeParameterList
|
||||||
|
<empty list>
|
||||||
|
PsiReferenceList
|
||||||
|
<empty list>
|
||||||
|
PsiReferenceList
|
||||||
|
<empty list>
|
||||||
|
PsiJavaToken:LBRACE('{')
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
PsiClassInitializer
|
||||||
|
PsiModifierList:
|
||||||
|
<empty list>
|
||||||
|
PsiCodeBlock
|
||||||
|
PsiJavaToken:LBRACE('{')
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
PsiTryStatement
|
||||||
|
PsiKeyword:try('try')
|
||||||
|
PsiCodeBlock
|
||||||
|
PsiJavaToken:LBRACE('{')
|
||||||
|
PsiJavaToken:RBRACE('}')
|
||||||
|
PsiCatchSection
|
||||||
|
PsiKeyword:catch('catch')
|
||||||
|
PsiJavaToken:LPARENTH('(')
|
||||||
|
PsiModifierList:
|
||||||
|
<empty list>
|
||||||
|
PsiTypeElement:E| e
|
||||||
|
PsiTypeElement:E
|
||||||
|
PsiJavaCodeReferenceElement:E
|
||||||
|
PsiIdentifier:E('E')
|
||||||
|
PsiReferenceParameterList
|
||||||
|
<empty list>
|
||||||
|
PsiJavaToken:OR('|')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiTypeElement:e
|
||||||
|
PsiJavaCodeReferenceElement:e
|
||||||
|
PsiIdentifier:e('e')
|
||||||
|
PsiReferenceParameterList
|
||||||
|
<empty list>
|
||||||
|
PsiErrorElement:Identifier expected
|
||||||
|
<empty list>
|
||||||
|
PsiJavaToken:RPARENTH(')')
|
||||||
|
PsiCodeBlock
|
||||||
|
PsiJavaToken:LBRACE('{')
|
||||||
|
PsiJavaToken:RBRACE('}')
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
PsiJavaToken:RBRACE('}')
|
||||||
|
PsiWhiteSpace('\n')
|
||||||
|
PsiJavaToken:RBRACE('}')
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
class A{
|
||||||
|
{
|
||||||
|
try{}catch(E1|E2 e){}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
PsiJavaFile:Normal4.java
|
||||||
|
PsiImportList
|
||||||
|
<empty list>
|
||||||
|
PsiClass:A
|
||||||
|
PsiModifierList:
|
||||||
|
<empty list>
|
||||||
|
PsiKeyword:class('class')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiIdentifier:A('A')
|
||||||
|
PsiTypeParameterList
|
||||||
|
<empty list>
|
||||||
|
PsiReferenceList
|
||||||
|
<empty list>
|
||||||
|
PsiReferenceList
|
||||||
|
<empty list>
|
||||||
|
PsiJavaToken:LBRACE('{')
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
PsiClassInitializer
|
||||||
|
PsiModifierList:
|
||||||
|
<empty list>
|
||||||
|
PsiCodeBlock
|
||||||
|
PsiJavaToken:LBRACE('{')
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
PsiTryStatement
|
||||||
|
PsiKeyword:try('try')
|
||||||
|
PsiCodeBlock
|
||||||
|
PsiJavaToken:LBRACE('{')
|
||||||
|
PsiJavaToken:RBRACE('}')
|
||||||
|
PsiCatchSection
|
||||||
|
PsiKeyword:catch('catch')
|
||||||
|
PsiJavaToken:LPARENTH('(')
|
||||||
|
PsiParameter:e
|
||||||
|
PsiModifierList:
|
||||||
|
<empty list>
|
||||||
|
PsiTypeElement:E1|E2
|
||||||
|
PsiTypeElement:E1
|
||||||
|
PsiJavaCodeReferenceElement:E1
|
||||||
|
PsiIdentifier:E1('E1')
|
||||||
|
PsiReferenceParameterList
|
||||||
|
<empty list>
|
||||||
|
PsiJavaToken:OR('|')
|
||||||
|
PsiTypeElement:E2
|
||||||
|
PsiJavaCodeReferenceElement:E2
|
||||||
|
PsiIdentifier:E2('E2')
|
||||||
|
PsiReferenceParameterList
|
||||||
|
<empty list>
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiIdentifier:e('e')
|
||||||
|
PsiJavaToken:RPARENTH(')')
|
||||||
|
PsiCodeBlock
|
||||||
|
PsiJavaToken:LBRACE('{')
|
||||||
|
PsiJavaToken:RBRACE('}')
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
PsiJavaToken:RBRACE('}')
|
||||||
|
PsiWhiteSpace('\n')
|
||||||
|
PsiJavaToken:RBRACE('}')
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
PsiJavaFile:Type8.java
|
||||||
|
PsiTypeElement:A|
|
||||||
|
PsiTypeElement:A
|
||||||
|
PsiJavaCodeReferenceElement:A
|
||||||
|
PsiIdentifier:A('A')
|
||||||
|
PsiReferenceParameterList
|
||||||
|
<empty list>
|
||||||
|
PsiJavaToken:OR('|')
|
||||||
|
PsiErrorElement:Identifier expected
|
||||||
|
<empty list>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
PsiJavaFile:Type9.java
|
||||||
|
PsiTypeElement:A|B
|
||||||
|
PsiTypeElement:A
|
||||||
|
PsiJavaCodeReferenceElement:A
|
||||||
|
PsiIdentifier:A('A')
|
||||||
|
PsiReferenceParameterList
|
||||||
|
<empty list>
|
||||||
|
PsiJavaToken:OR('|')
|
||||||
|
PsiTypeElement:B
|
||||||
|
PsiJavaCodeReferenceElement:B
|
||||||
|
PsiIdentifier:B('B')
|
||||||
|
PsiReferenceParameterList
|
||||||
|
<empty list>
|
||||||
@@ -148,4 +148,8 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase {
|
|||||||
public void testNumericLiterals() throws Exception {
|
public void testNumericLiterals() throws Exception {
|
||||||
doTest(false, false);
|
doTest(false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testMultiCatch() throws Exception {
|
||||||
|
doTest(false, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2000-2011 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.intellij.codeInsight.daemon.quickFix;
|
||||||
|
|
||||||
|
public class DeleteMultiCatchTest extends LightQuickFixTestCase {
|
||||||
|
public void test() throws Exception { doAllTests(); }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getBasePath() {
|
||||||
|
return "/codeInsight/daemonCodeAnalyzer/quickFix/deleteMultiCatch";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -42,6 +42,8 @@ public class ReferenceParserTest extends JavaParsingTestCase {
|
|||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
public void testType7() { doTypeParserTest("Diamond<>"); }
|
public void testType7() { doTypeParserTest("Diamond<>"); }
|
||||||
|
public void testType8() { doTypeParserTest("A|"); }
|
||||||
|
public void testType9() { doTypeParserTest("A|B"); }
|
||||||
|
|
||||||
public void testTypeParams0() { doTypeParamsParserTest("<T>"); }
|
public void testTypeParams0() { doTypeParamsParserTest("<T>"); }
|
||||||
public void testTypeParams1() { doTypeParamsParserTest("<T, U>"); }
|
public void testTypeParams1() { doTypeParamsParserTest("<T, U>"); }
|
||||||
@@ -65,7 +67,7 @@ public class ReferenceParserTest extends JavaParsingTestCase {
|
|||||||
doParserTest(text, new TestParser() {
|
doParserTest(text, new TestParser() {
|
||||||
@Override
|
@Override
|
||||||
public void parse(final PsiBuilder builder) {
|
public void parse(final PsiBuilder builder) {
|
||||||
ReferenceParser.parseType(builder, ReferenceParser.DIAMONDS | ReferenceParser.ELLIPSIS);
|
ReferenceParser.parseType(builder, ReferenceParser.ELLIPSIS | ReferenceParser.DIAMONDS | ReferenceParser.DISJUNCTIONS);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
package com.intellij.lang.java.parser.statementParsing;
|
package com.intellij.lang.java.parser.statementParsing;
|
||||||
|
|
||||||
import com.intellij.lang.java.parser.JavaParsingTestCase;
|
import com.intellij.lang.java.parser.JavaParsingTestCase;
|
||||||
|
import com.intellij.pom.java.LanguageLevel;
|
||||||
|
|
||||||
|
|
||||||
public class TryParsingTest extends JavaParsingTestCase {
|
public class TryParsingTest extends JavaParsingTestCase {
|
||||||
@@ -12,6 +12,11 @@ public class TryParsingTest extends JavaParsingTestCase {
|
|||||||
public void testNormal1() { doTest(true); }
|
public void testNormal1() { doTest(true); }
|
||||||
public void testNormal2() { doTest(true); }
|
public void testNormal2() { doTest(true); }
|
||||||
public void testNormal3() { doTest(true); }
|
public void testNormal3() { doTest(true); }
|
||||||
|
public void testNormal4() {
|
||||||
|
withLevel(LanguageLevel.JDK_1_7, new Runnable() { @Override public void run() {
|
||||||
|
doTest(true);
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
|
||||||
public void testIncomplete1() { doTest(true); }
|
public void testIncomplete1() { doTest(true); }
|
||||||
public void testIncomplete2() { doTest(true); }
|
public void testIncomplete2() { doTest(true); }
|
||||||
@@ -21,4 +26,9 @@ public class TryParsingTest extends JavaParsingTestCase {
|
|||||||
public void testIncomplete6() { doTest(true); }
|
public void testIncomplete6() { doTest(true); }
|
||||||
public void testIncomplete7() { doTest(true); }
|
public void testIncomplete7() { doTest(true); }
|
||||||
public void testIncomplete8() { doTest(true); }
|
public void testIncomplete8() { doTest(true); }
|
||||||
|
public void testIncomplete9() {
|
||||||
|
withLevel(LanguageLevel.JDK_1_7, new Runnable() { @Override public void run() {
|
||||||
|
doTest(true);
|
||||||
|
}});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
118
java/openapi/src/com/intellij/psi/PsiDisjunctionType.java
Normal file
118
java/openapi/src/com/intellij/psi/PsiDisjunctionType.java
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
* 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 com.intellij.openapi.util.Comparing;
|
||||||
|
import com.intellij.openapi.util.text.StringUtil;
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope;
|
||||||
|
import com.intellij.psi.util.*;
|
||||||
|
import com.intellij.util.Function;
|
||||||
|
import com.intellij.util.containers.ContainerUtil;
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class PsiDisjunctionType extends PsiType {
|
||||||
|
private final PsiTypeElement myTypeElement;
|
||||||
|
private final List<PsiType> myTypes;
|
||||||
|
private final CachedValue<PsiClassType> myLubCache;
|
||||||
|
|
||||||
|
public PsiDisjunctionType(final PsiTypeElement typeElement) {
|
||||||
|
super(PsiAnnotation.EMPTY_ARRAY);
|
||||||
|
|
||||||
|
myTypeElement = typeElement;
|
||||||
|
|
||||||
|
final List<PsiTypeElement> typeElements = PsiTreeUtil.getChildrenOfTypeAsList(myTypeElement, PsiTypeElement.class);
|
||||||
|
myTypes = Collections.unmodifiableList(ContainerUtil.map(typeElements, new Function<PsiTypeElement, PsiType>() {
|
||||||
|
@Override
|
||||||
|
public PsiType fun(final PsiTypeElement psiTypeElement) {
|
||||||
|
return psiTypeElement.getType();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
final CachedValuesManager cacheManager = CachedValuesManager.getManager(myTypeElement.getProject());
|
||||||
|
myLubCache = cacheManager.createCachedValue(new CachedValueProvider<PsiClassType>() {
|
||||||
|
public Result<PsiClassType> compute() {
|
||||||
|
PsiType lub = myTypes.get(0);
|
||||||
|
for (int i = 1; i < myTypes.size(); i++) {
|
||||||
|
lub = GenericsUtil.getLeastUpperBound(lub, myTypes.get(i), myTypeElement.getManager());
|
||||||
|
}
|
||||||
|
assert lub instanceof PsiClassType : getCanonicalText() + ", " + lub;
|
||||||
|
return Result.create((PsiClassType)lub, PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
|
||||||
|
}
|
||||||
|
}, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PsiClassType getLeastUpperBound() {
|
||||||
|
return myLubCache.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<PsiType> getDisjunctions() {
|
||||||
|
return myTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPresentableText() {
|
||||||
|
return StringUtil.join(myTypes, new Function<PsiType, String>() {
|
||||||
|
@Override public String fun(PsiType psiType) { return psiType.getPresentableText(); }
|
||||||
|
}, " | ");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCanonicalText() {
|
||||||
|
return StringUtil.join(myTypes, new Function<PsiType, String>() {
|
||||||
|
@Override public String fun(PsiType psiType) { return psiType.getCanonicalText(); }
|
||||||
|
}, " | ");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getInternalCanonicalText() {
|
||||||
|
return StringUtil.join(myTypes, new Function<PsiType, String>() {
|
||||||
|
@Override public String fun(PsiType psiType) { return psiType.getInternalCanonicalText(); }
|
||||||
|
}, " | ");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValid() {
|
||||||
|
for (PsiType type : myTypes) {
|
||||||
|
if (!type.isValid()) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equalsToText(@NonNls final String text) {
|
||||||
|
return Comparing.equal(text, getCanonicalText());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <A> A accept(final PsiTypeVisitor<A> visitor) {
|
||||||
|
return visitor.visitClassType(getLeastUpperBound());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GlobalSearchScope getResolveScope() {
|
||||||
|
return getLeastUpperBound().getResolveScope();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public PsiType[] getSuperTypes() {
|
||||||
|
return getLeastUpperBound().getSuperTypes();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,12 +16,15 @@
|
|||||||
package com.intellij.psi.util;
|
package com.intellij.psi.util;
|
||||||
|
|
||||||
import com.intellij.psi.*;
|
import com.intellij.psi.*;
|
||||||
|
import com.intellij.util.containers.HashSet;
|
||||||
import gnu.trove.THashMap;
|
import gnu.trove.THashMap;
|
||||||
import org.jetbrains.annotations.NonNls;
|
import org.jetbrains.annotations.NonNls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class PsiTypesUtil {
|
public class PsiTypesUtil {
|
||||||
@NonNls private static final Map<String, String> ourUnboxedTypes = new THashMap<String, String>();
|
@NonNls private static final Map<String, String> ourUnboxedTypes = new THashMap<String, String>();
|
||||||
@@ -47,6 +50,7 @@ public class PsiTypesUtil {
|
|||||||
ourBoxedTypes.put("char", CommonClassNames.JAVA_LANG_CHARACTER);
|
ourBoxedTypes.put("char", CommonClassNames.JAVA_LANG_CHARACTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private PsiTypesUtil() { }
|
||||||
|
|
||||||
public static String getDefaultValueOfType(PsiType type) {
|
public static String getDefaultValueOfType(PsiType type) {
|
||||||
if (type instanceof PsiArrayType) {
|
if (type instanceof PsiArrayType) {
|
||||||
@@ -115,4 +119,16 @@ public class PsiTypesUtil {
|
|||||||
public static PsiClassType getClassType(@NotNull PsiClass psiClass) {
|
public static PsiClassType getClassType(@NotNull PsiClass psiClass) {
|
||||||
return JavaPsiFacade.getElementFactory(psiClass.getProject()).createType(psiClass);
|
return JavaPsiFacade.getElementFactory(psiClass.getProject()).createType(psiClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static Collection<PsiClass> getPsiClasses(@NotNull final Collection<PsiType> types) {
|
||||||
|
final Set<PsiClass> result = new HashSet<PsiClass>();
|
||||||
|
for (PsiType type : types) {
|
||||||
|
final PsiClass psiClass = getPsiClass(type);
|
||||||
|
if (psiClass != null) {
|
||||||
|
result.add(psiClass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -371,6 +371,9 @@ public final class PsiUtil extends PsiUtilBase {
|
|||||||
if (type instanceof PsiArrayType) {
|
if (type instanceof PsiArrayType) {
|
||||||
return resolveClassInType(((PsiArrayType) type).getComponentType());
|
return resolveClassInType(((PsiArrayType) type).getComponentType());
|
||||||
}
|
}
|
||||||
|
if (type instanceof PsiDisjunctionType) {
|
||||||
|
return ((PsiDisjunctionType)type).getLeastUpperBound().resolve();
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ public class TypeConversionUtil {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true iff fromType can be casted to toType
|
* @return true if fromType can be casted to toType
|
||||||
*/
|
*/
|
||||||
public static boolean areTypesConvertible(@NotNull PsiType fromType, @NotNull PsiType toType) {
|
public static boolean areTypesConvertible(@NotNull PsiType fromType, @NotNull PsiType toType) {
|
||||||
if (fromType == toType) return true;
|
if (fromType == toType) return true;
|
||||||
@@ -114,7 +114,7 @@ public class TypeConversionUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* see JLS 5.1.5, JLS3 5.5
|
* see JLS 5.1.5, JLS3 5.1.6
|
||||||
*/
|
*/
|
||||||
private static boolean isNarrowingReferenceConversionAllowed(PsiType fromType, PsiType toType) {
|
private static boolean isNarrowingReferenceConversionAllowed(PsiType fromType, PsiType toType) {
|
||||||
if (toType instanceof PsiPrimitiveType || fromType instanceof PsiPrimitiveType) return fromType.equals(toType);
|
if (toType instanceof PsiPrimitiveType || fromType instanceof PsiPrimitiveType) return fromType.equals(toType);
|
||||||
@@ -154,7 +154,15 @@ public class TypeConversionUtil {
|
|||||||
if (isNarrowingReferenceConversionAllowed(conjunct, toType)) return true;
|
if (isNarrowingReferenceConversionAllowed(conjunct, toType)) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
} else if (toType instanceof PsiIntersectionType) return false;
|
}
|
||||||
|
else if (toType instanceof PsiIntersectionType) return false;
|
||||||
|
|
||||||
|
if (fromType instanceof PsiDisjunctionType) {
|
||||||
|
return isNarrowingReferenceConversionAllowed(((PsiDisjunctionType)fromType).getLeastUpperBound(), toType);
|
||||||
|
}
|
||||||
|
if (toType instanceof PsiDisjunctionType) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (fromType instanceof PsiWildcardType) {
|
if (fromType instanceof PsiWildcardType) {
|
||||||
final PsiWildcardType fromWildcard = (PsiWildcardType)fromType;
|
final PsiWildcardType fromWildcard = (PsiWildcardType)fromType;
|
||||||
@@ -665,6 +673,16 @@ public class TypeConversionUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (left instanceof PsiDisjunctionType) {
|
||||||
|
for (PsiType type : ((PsiDisjunctionType)left).getDisjunctions()) {
|
||||||
|
if (isAssignable(type, right, allowUncheckedConversion)) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (right instanceof PsiDisjunctionType) {
|
||||||
|
return isAssignable(left, ((PsiDisjunctionType)right).getLeastUpperBound(), allowUncheckedConversion);
|
||||||
|
}
|
||||||
|
|
||||||
if (left instanceof PsiArrayType) return false;
|
if (left instanceof PsiArrayType) return false;
|
||||||
if (right instanceof PsiPrimitiveType) {
|
if (right instanceof PsiPrimitiveType) {
|
||||||
if (isVoidType(right)) return false;
|
if (isVoidType(right)) return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user