mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
+3
@@ -219,4 +219,7 @@ public abstract class TestDiscoveryConfiguration extends JavaTestConfigurationBa
|
||||
public String getChangeList() {
|
||||
return myChangeList;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public abstract String getFrameworkPrefix();
|
||||
}
|
||||
|
||||
+10
-2
@@ -22,6 +22,7 @@ import com.intellij.execution.actions.ConfigurationContext;
|
||||
import com.intellij.execution.configurations.ConfigurationType;
|
||||
import com.intellij.execution.junit.JavaRunConfigurationProducerBase;
|
||||
import com.intellij.execution.testframework.TestSearchScope;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
@@ -31,6 +32,7 @@ import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.testIntegration.TestFramework;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
@@ -41,7 +43,7 @@ public abstract class TestDiscoveryConfigurationProducer extends JavaRunConfigur
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean setupConfigurationFromContext(TestDiscoveryConfiguration configuration,
|
||||
protected boolean setupConfigurationFromContext(final TestDiscoveryConfiguration configuration,
|
||||
ConfigurationContext configurationContext,
|
||||
Ref<PsiElement> ref) {
|
||||
if (!Registry.is("testDiscovery.enabled")) {
|
||||
@@ -56,7 +58,13 @@ public abstract class TestDiscoveryConfigurationProducer extends JavaRunConfigur
|
||||
try {
|
||||
final Collection<String> testsByMethodName = TestDiscoveryIndex
|
||||
.getInstance(configuration.getProject()).getTestsByMethodName(position.first, position.second);
|
||||
if (testsByMethodName == null || testsByMethodName.isEmpty()) return false;
|
||||
if (testsByMethodName == null || ContainerUtil.filter(testsByMethodName, new Condition<String>() {
|
||||
@Override
|
||||
public boolean value(String s) {
|
||||
return s.startsWith(configuration.getFrameworkPrefix());
|
||||
}
|
||||
}).isEmpty()) return false;
|
||||
|
||||
}
|
||||
catch (IOException e) {
|
||||
return false;
|
||||
|
||||
+1
-1
@@ -85,7 +85,7 @@ public class TestDiscoveryExtension extends RunConfigurationExtension {
|
||||
if ((root == null || root.getHandler() == handler)) {
|
||||
final String fullTestName = test.getLocationUrl();
|
||||
if (fullTestName != null && fullTestName.startsWith(JavaTestLocator.TEST_PROTOCOL)) {
|
||||
myCompletedMethodNames.add(fullTestName.substring(JavaTestLocator.TEST_PROTOCOL.length() + 3));
|
||||
myCompletedMethodNames.add(((TestDiscoveryConfiguration)configuration).getFrameworkPrefix() + fullTestName.substring(JavaTestLocator.TEST_PROTOCOL.length() + 3));
|
||||
if (myCompletedMethodNames.size() > 50) {
|
||||
final String[] fullTestNames = ArrayUtil.toStringArray(myCompletedMethodNames);
|
||||
myCompletedMethodNames.clear();
|
||||
|
||||
+29
-17
@@ -18,6 +18,7 @@ package com.intellij.execution.testDiscovery;
|
||||
import com.intellij.codeInsight.actions.FormatChangedTextUtil;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
@@ -27,6 +28,7 @@ import com.intellij.openapi.vcs.changes.LocalChangeList;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -35,17 +37,14 @@ import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
public class TestDiscoverySearchHelper {
|
||||
public static Set<String> search(final Project project, final Pair<String, String> position, final String changeList) {
|
||||
public static Set<String> search(final Project project,
|
||||
final Pair<String, String> position,
|
||||
final String changeList,
|
||||
final String frameworkPrefix) {
|
||||
final Set<String> patterns = new LinkedHashSet<String>();
|
||||
if (position != null) {
|
||||
try {
|
||||
final Collection<String> testsByMethodName = TestDiscoveryIndex
|
||||
.getInstance(project).getTestsByMethodName(position.first, position.second);
|
||||
if (testsByMethodName != null) {
|
||||
for (String pattern : testsByMethodName) {
|
||||
patterns.add(pattern.replace('-', ','));
|
||||
}
|
||||
}
|
||||
collectPatterns(project, patterns, position.first, position.second, frameworkPrefix);
|
||||
}
|
||||
catch (IOException ignore) {
|
||||
}
|
||||
@@ -73,7 +72,7 @@ public class TestDiscoverySearchHelper {
|
||||
methods.add(containingMethod);
|
||||
}
|
||||
for (PsiMethod changedMethod : methods) {
|
||||
final LinkedHashSet<String> detectedPatterns = collectPatterns(changedMethod);
|
||||
final LinkedHashSet<String> detectedPatterns = collectPatterns(changedMethod, frameworkPrefix);
|
||||
if (detectedPatterns != null) {
|
||||
patterns.addAll(detectedPatterns);
|
||||
}
|
||||
@@ -90,6 +89,25 @@ public class TestDiscoverySearchHelper {
|
||||
return patterns;
|
||||
}
|
||||
|
||||
private static void collectPatterns(final Project project,
|
||||
final Set<String> patterns,
|
||||
final String classFQName,
|
||||
final String methodName,
|
||||
final String frameworkId) throws IOException {
|
||||
final Collection<String> testsByMethodName = TestDiscoveryIndex
|
||||
.getInstance(project).getTestsByMethodName(classFQName, methodName);
|
||||
if (testsByMethodName != null) {
|
||||
for (String pattern : ContainerUtil.filter(testsByMethodName, new Condition<String>() {
|
||||
@Override
|
||||
public boolean value(String s) {
|
||||
return s.startsWith(frameworkId);
|
||||
}
|
||||
})) {
|
||||
patterns.add(pattern.substring(frameworkId.length()).replace('-', ','));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<VirtualFile> getAffectedFiles(String changeListName, Project project) {
|
||||
final ChangeListManager changeListManager = ChangeListManager.getInstance(project);
|
||||
@@ -115,20 +133,14 @@ public class TestDiscoverySearchHelper {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static LinkedHashSet<String> collectPatterns(PsiMethod psiMethod) {
|
||||
private static LinkedHashSet<String> collectPatterns(PsiMethod psiMethod, String frameworkId) {
|
||||
LinkedHashSet<String> patterns = new LinkedHashSet<String>();
|
||||
final PsiClass containingClass = psiMethod.getContainingClass();
|
||||
if (containingClass != null) {
|
||||
final String qualifiedName = containingClass.getQualifiedName();
|
||||
if (qualifiedName != null) {
|
||||
try {
|
||||
final Collection<String> testsByMethodName
|
||||
= TestDiscoveryIndex.getInstance(containingClass.getProject()).getTestsByMethodName(qualifiedName, psiMethod.getName());
|
||||
if (testsByMethodName != null) {
|
||||
for (String pattern : testsByMethodName) {
|
||||
patterns.add(pattern.replace('-', ','));
|
||||
}
|
||||
}
|
||||
collectPatterns(psiMethod.getProject(), patterns, qualifiedName, psiMethod.getName(), frameworkId);
|
||||
}
|
||||
catch (IOException e) {
|
||||
return null;
|
||||
|
||||
+19
-14
@@ -32,6 +32,7 @@ import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.options.ShowSettingsUtil;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectBundle;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
@@ -300,23 +301,27 @@ public class ModulesConfigurator implements ModulesProvider, ModuleEditor.Change
|
||||
}
|
||||
myFacetsConfigurator.applyEditors();
|
||||
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
DumbService.getInstance(myProject).allowStartingDumbModeInside(DumbService.DumbModePermission.MAY_START_BACKGROUND, new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
final ModifiableRootModel[] rootModels = models.toArray(new ModifiableRootModel[models.size()]);
|
||||
ModifiableModelCommitter.multiCommit(rootModels, myModuleModel);
|
||||
myModuleModelCommitted = true;
|
||||
myFacetsConfigurator.commitFacets();
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
final ModifiableRootModel[] rootModels = models.toArray(new ModifiableRootModel[models.size()]);
|
||||
ModifiableModelCommitter.multiCommit(rootModels, myModuleModel);
|
||||
myModuleModelCommitted = true;
|
||||
myFacetsConfigurator.commitFacets();
|
||||
|
||||
}
|
||||
finally {
|
||||
ModuleStructureConfigurable.getInstance(myProject).getFacetEditorFacade().clearMaps(false);
|
||||
}
|
||||
finally {
|
||||
ModuleStructureConfigurable.getInstance(myProject).getFacetEditorFacade().clearMaps(false);
|
||||
|
||||
myFacetsConfigurator = createFacetsConfigurator();
|
||||
myModuleModel = ModuleManager.getInstance(myProject).getModifiableModel();
|
||||
myModuleModelCommitted = false;
|
||||
}
|
||||
myFacetsConfigurator = createFacetsConfigurator();
|
||||
myModuleModel = ModuleManager.getInstance(myProject).getModifiableModel();
|
||||
myModuleModelCommitted = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
+59
-22
@@ -725,13 +725,18 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static HighlightInfo checkUnderscore(@NotNull PsiIdentifier identifier,
|
||||
@NotNull PsiVariable variable,
|
||||
@NotNull LanguageLevel languageLevel) {
|
||||
if ("_".equals(variable.getName()) && languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) {
|
||||
if (variable instanceof PsiParameter && ((PsiParameter)variable).getDeclarationScope() instanceof PsiLambdaExpression) {
|
||||
String message = JavaErrorMessages.message("underscore.lambda.identifier");
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(identifier).descriptionAndTooltip(message).create();
|
||||
static HighlightInfo checkUnderscore(@NotNull PsiIdentifier identifier, @NotNull LanguageLevel languageLevel) {
|
||||
if ("_".equals(identifier.getText())) {
|
||||
if (languageLevel.isAtLeast(LanguageLevel.JDK_1_9)) {
|
||||
String text = JavaErrorMessages.message("underscore.identifier.error");
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(identifier).descriptionAndTooltip(text).create();
|
||||
}
|
||||
else if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) {
|
||||
PsiElement parent = identifier.getParent();
|
||||
if (parent instanceof PsiParameter && ((PsiParameter)parent).getDeclarationScope() instanceof PsiLambdaExpression) {
|
||||
String text = JavaErrorMessages.message("underscore.lambda.identifier");
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(identifier).descriptionAndTooltip(text).create();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -770,23 +775,20 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static HighlightInfo checkUnhandledCloserExceptions(@NotNull final PsiResourceVariable resource) {
|
||||
final List<PsiClassType> unhandled = ExceptionUtil.getUnhandledCloserExceptions(resource, null);
|
||||
static HighlightInfo checkUnhandledCloserExceptions(@NotNull PsiResourceListElement resource) {
|
||||
List<PsiClassType> unhandled = ExceptionUtil.getUnhandledCloserExceptions(resource, null);
|
||||
if (unhandled.isEmpty()) return null;
|
||||
|
||||
final HighlightInfoType highlightType = getUnhandledExceptionHighlightType(resource);
|
||||
HighlightInfoType highlightType = getUnhandledExceptionHighlightType(resource);
|
||||
if (highlightType == null) return null;
|
||||
|
||||
final String description = getUnhandledExceptionsDescriptor(unhandled, "auto-closeable resource");
|
||||
final HighlightInfo highlight =
|
||||
HighlightInfo.newHighlightInfo(highlightType).range(resource).descriptionAndTooltip(description).create();
|
||||
String description = getUnhandledExceptionsDescriptor(unhandled, "auto-closeable resource");
|
||||
HighlightInfo highlight = HighlightInfo.newHighlightInfo(highlightType).range(resource).descriptionAndTooltip(description).create();
|
||||
registerUnhandledExceptionFixes(resource, highlight, unhandled);
|
||||
return highlight;
|
||||
}
|
||||
|
||||
private static void registerUnhandledExceptionFixes(@NotNull final PsiElement element,
|
||||
final HighlightInfo errorResult,
|
||||
@NotNull final List<PsiClassType> unhandled) {
|
||||
private static void registerUnhandledExceptionFixes(PsiElement element, HighlightInfo errorResult, List<PsiClassType> unhandled) {
|
||||
QuickFixAction.registerQuickFixAction(errorResult, QUICK_FIX_FACTORY.createAddExceptionToCatchFix());
|
||||
QuickFixAction.registerQuickFixAction(errorResult, QUICK_FIX_FACTORY.createAddExceptionToThrowsFix(element));
|
||||
QuickFixAction.registerQuickFixAction(errorResult, QUICK_FIX_FACTORY.createSurroundWithTryCatchFix(element));
|
||||
@@ -1717,15 +1719,49 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static HighlightInfo checkTryResourceIsAutoCloseable(@NotNull final PsiResourceVariable resource) {
|
||||
final PsiType type = resource.getType();
|
||||
final PsiElementFactory factory = JavaPsiFacade.getInstance(resource.getProject()).getElementFactory();
|
||||
final PsiClassType autoCloseable = factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_AUTO_CLOSEABLE, resource.getResolveScope());
|
||||
static HighlightInfo checkTryResourceIsAutoCloseable(@NotNull PsiResourceListElement resource) {
|
||||
PsiType type = resource.getType();
|
||||
if (type == null) return null;
|
||||
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(resource.getProject()).getElementFactory();
|
||||
PsiClassType autoCloseable = factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_AUTO_CLOSEABLE, resource.getResolveScope());
|
||||
if (TypeConversionUtil.isAssignable(autoCloseable, type)) return null;
|
||||
|
||||
return createIncompatibleTypeHighlightInfo(autoCloseable, type, resource.getTextRange(), 0);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static HighlightInfo checkResourceVariableIsFinal(@NotNull PsiResourceExpression resource) {
|
||||
PsiExpression expression = resource.getExpression();
|
||||
|
||||
if (expression instanceof PsiThisExpression) return null;
|
||||
|
||||
if (expression instanceof PsiReferenceExpression) {
|
||||
PsiElement target = ((PsiReferenceExpression)expression).resolve();
|
||||
if (target == null) return null;
|
||||
|
||||
if (target instanceof PsiVariable) {
|
||||
PsiVariable variable = (PsiVariable)target;
|
||||
|
||||
PsiModifierList modifierList = variable.getModifierList();
|
||||
if (modifierList != null && modifierList.hasModifierProperty(PsiModifier.FINAL)) return null;
|
||||
|
||||
PsiElement scope = null;
|
||||
if (variable instanceof PsiParameter) scope = ((PsiParameter)variable).getDeclarationScope();
|
||||
else if (variable instanceof PsiResourceVariable) scope = variable.getParent().getParent();
|
||||
else if (variable instanceof PsiLocalVariable) scope = PsiTreeUtil.getParentOfType(variable, PsiCodeBlock.class);
|
||||
if (scope != null) {
|
||||
if (HighlightControlFlowUtil.isEffectivelyFinal(variable, scope, null)) return null;
|
||||
}
|
||||
}
|
||||
|
||||
String text = JavaErrorMessages.message("resource.variable.must.be.final");
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(text).create();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static Collection<HighlightInfo> checkArrayInitializer(final PsiExpression initializer, PsiType type) {
|
||||
if (!(initializer instanceof PsiArrayInitializerExpression)) return null;
|
||||
@@ -2915,12 +2951,13 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
METHOD_REFERENCES(LanguageLevel.JDK_1_8, "feature.method.references"),
|
||||
LAMBDA_EXPRESSIONS(LanguageLevel.JDK_1_8, "feature.lambda.expressions"),
|
||||
TYPE_ANNOTATIONS(LanguageLevel.JDK_1_8, "feature.type.annotations"),
|
||||
RECEIVERS(LanguageLevel.JDK_1_8, "feature.type.receivers");
|
||||
RECEIVERS(LanguageLevel.JDK_1_8, "feature.type.receivers"),
|
||||
REFS_AS_RESOURCE(LanguageLevel.JDK_1_9, "feature.try.with.resources.refs");
|
||||
|
||||
private final LanguageLevel level;
|
||||
private final String key;
|
||||
|
||||
Feature(@NotNull LanguageLevel level, @NotNull @PropertyKey(resourceBundle = JavaErrorMessages.BUNDLE) final String key) {
|
||||
Feature(@NotNull LanguageLevel level, @NotNull @PropertyKey(resourceBundle = JavaErrorMessages.BUNDLE) String key) {
|
||||
this.level = level;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
+31
-34
@@ -220,8 +220,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IndexNotReadyException ignored) {
|
||||
}
|
||||
catch (IndexNotReadyException ignored) { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -568,8 +567,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
myHolder.add(HighlightMethodUtil.checkAmbiguousMethodCallArguments(referenceExpression, results, list, resolved, result, expression, myResolveHelper, list));
|
||||
}
|
||||
}
|
||||
catch (IndexNotReadyException ignored) {
|
||||
}
|
||||
catch (IndexNotReadyException ignored) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -623,8 +621,6 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
myHolder.add(HighlightNamesUtil.highlightVariableName(variable, identifier, colorsScheme));
|
||||
}
|
||||
}
|
||||
|
||||
myHolder.add(HighlightUtil.checkUnderscore(identifier, variable, myLanguageLevel));
|
||||
}
|
||||
else if (parent instanceof PsiClass) {
|
||||
PsiClass aClass = (PsiClass)parent;
|
||||
@@ -652,6 +648,8 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
}
|
||||
|
||||
myHolder.add(HighlightUtil.checkUnderscore(identifier, myLanguageLevel));
|
||||
|
||||
super.visitIdentifier(identifier);
|
||||
}
|
||||
|
||||
@@ -841,8 +839,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IndexNotReadyException ignored) {
|
||||
}
|
||||
catch (IndexNotReadyException ignored) { }
|
||||
}
|
||||
else if (parent instanceof PsiImportStatement && ((PsiImportStatement)parent).isOnDemand()) {
|
||||
// highlight on demand import as class
|
||||
@@ -862,8 +859,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
try {
|
||||
myHolder.add(HighlightMethodUtil.checkMethodCall(expression, myResolveHelper, myLanguageLevel,myJavaSdkVersion));
|
||||
}
|
||||
catch (IndexNotReadyException ignored) {
|
||||
}
|
||||
catch (IndexNotReadyException ignored) { }
|
||||
}
|
||||
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkConstructorCallMustBeFirstStatement(expression));
|
||||
@@ -892,8 +888,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IndexNotReadyException ignored) {
|
||||
}
|
||||
catch (IndexNotReadyException ignored) { }
|
||||
}
|
||||
PsiClass aClass = method.getContainingClass();
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodMustHaveBody(method, aClass));
|
||||
@@ -948,8 +943,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
try {
|
||||
if (!myHolder.hasErrorResults()) HighlightMethodUtil.checkNewExpression(expression, type, myHolder, myJavaSdkVersion);
|
||||
}
|
||||
catch (IndexNotReadyException ignored) {
|
||||
}
|
||||
catch (IndexNotReadyException ignored) { }
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkEnumInstantiation(expression, aClass));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkGenericArrayCreation(expression, type));
|
||||
if (!myHolder.hasErrorResults()) registerConstructorCall(expression);
|
||||
@@ -1198,8 +1192,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
try {
|
||||
myHolder.add(HighlightControlFlowUtil.checkVariableInitializedBeforeUsage(expression, (PsiVariable)resolved, myUninitializedVarProblems,myFile));
|
||||
}
|
||||
catch (IndexNotReadyException ignored) {
|
||||
}
|
||||
catch (IndexNotReadyException ignored) { }
|
||||
}
|
||||
PsiVariable variable = (PsiVariable)resolved;
|
||||
boolean isFinal = variable.hasModifierProperty(PsiModifier.FINAL);
|
||||
@@ -1224,8 +1217,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
.checkAmbiguousMethodCallArguments(expression, results, list, resolved, result, methodCallExpression, myResolveHelper, expression.getReferenceNameElement()));
|
||||
}
|
||||
}
|
||||
catch (IndexNotReadyException ignored) {
|
||||
}
|
||||
catch (IndexNotReadyException ignored) { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1234,8 +1226,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
try {
|
||||
myHolder.add(HighlightUtil.checkIllegalForwardReferenceToField(expression, (PsiField)resolved));
|
||||
}
|
||||
catch (IndexNotReadyException ignored) {
|
||||
}
|
||||
catch (IndexNotReadyException ignored) { }
|
||||
}
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkAccessStaticFieldFromEnumConstructor(expression, result));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkClassReferenceAfterQualifier(expression, resolved));
|
||||
@@ -1424,8 +1415,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
try {
|
||||
myHolder.add(HighlightUtil.checkReturnStatementType(statement));
|
||||
}
|
||||
catch (IndexNotReadyException ignore) {
|
||||
}
|
||||
catch (IndexNotReadyException ignore) { }
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1485,13 +1475,6 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitResourceVariable(final PsiResourceVariable resourceVariable) {
|
||||
visitVariable(resourceVariable);
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkTryResourceIsAutoCloseable(resourceVariable));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkUnhandledCloserExceptions(resourceVariable));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitResourceList(PsiResourceList resourceList) {
|
||||
super.visitResourceList(resourceList);
|
||||
@@ -1499,7 +1482,23 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTypeElement(final PsiTypeElement type) {
|
||||
public void visitResourceVariable(PsiResourceVariable resource) {
|
||||
super.visitResourceVariable(resource);
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkTryResourceIsAutoCloseable(resource));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkUnhandledCloserExceptions(resource));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitResourceExpression(PsiResourceExpression resource) {
|
||||
super.visitResourceExpression(resource);
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(checkFeature(resource, Feature.REFS_AS_RESOURCE));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkResourceVariableIsFinal(resource));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkTryResourceIsAutoCloseable(resource));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkUnhandledCloserExceptions(resource));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTypeElement(PsiTypeElement type) {
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkIllegalType(type));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkReferenceTypeUsedAsTypeArgument(type, myLanguageLevel));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkWildcardUsage(type));
|
||||
@@ -1512,8 +1511,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkIntersectionInTypeCast(typeCast, myLanguageLevel));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkInconvertibleTypeCast(typeCast));
|
||||
}
|
||||
catch (IndexNotReadyException ignore) {
|
||||
}
|
||||
catch (IndexNotReadyException ignored) { }
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1531,8 +1529,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
try {
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkVariableInitializerType(variable));
|
||||
}
|
||||
catch (IndexNotReadyException ignored) {
|
||||
}
|
||||
catch (IndexNotReadyException ignored) { }
|
||||
}
|
||||
|
||||
private boolean isReassigned(@NotNull PsiVariable variable) {
|
||||
|
||||
+10
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -34,9 +34,13 @@ public class JavacQuirksInspectionVisitor extends JavaElementVisitor {
|
||||
psiElement().withParent(PsiJavaCodeReferenceElement.class).withSuperParent(2, PsiJavaCodeReferenceElement.class);
|
||||
|
||||
private final ProblemsHolder myHolder;
|
||||
private final LanguageLevel myLanguageLevel;
|
||||
private final JavaSdkVersion mySdkVersion;
|
||||
|
||||
public JavacQuirksInspectionVisitor(ProblemsHolder holder) {
|
||||
myHolder = holder;
|
||||
mySdkVersion = JavaVersionService.getInstance().getJavaSdkVersion(myHolder.getFile());
|
||||
myLanguageLevel = PsiUtil.getLanguageLevel(myHolder.getFile());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -72,12 +76,11 @@ public class JavacQuirksInspectionVisitor extends JavaElementVisitor {
|
||||
@Override
|
||||
public void visitIdentifier(PsiIdentifier identifier) {
|
||||
super.visitIdentifier(identifier);
|
||||
final JavaSdkVersion version = JavaVersionService.getInstance().getJavaSdkVersion(identifier);
|
||||
if (version != null && version.isAtLeast(JavaSdkVersion.JDK_1_8)) {
|
||||
if ("_".equals(identifier.getText())) {
|
||||
myHolder.registerProblem(identifier, JavaErrorMessages.message("underscore.identifier"),
|
||||
version.isAtLeast(JavaSdkVersion.JDK_1_9) ? ProblemHighlightType.ERROR : ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
|
||||
}
|
||||
if ("_".equals(identifier.getText()) &&
|
||||
mySdkVersion != null && mySdkVersion.isAtLeast(JavaSdkVersion.JDK_1_8) &&
|
||||
myLanguageLevel.isLessThan(LanguageLevel.JDK_1_9)) {
|
||||
final String message = JavaErrorMessages.message("underscore.identifier.warn");
|
||||
myHolder.registerProblem(identifier, message, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+16
-7
@@ -350,8 +350,10 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
else if (parent instanceof PsiTryStatement) {
|
||||
PsiResourceList list = ((PsiTryStatement)parent).getResourceList();
|
||||
if (list != null) {
|
||||
for (PsiResourceVariable variable : list.getResourceVariables()) {
|
||||
myCurrentFlow.removeVariable(variable);
|
||||
for (PsiResourceListElement resource : list) {
|
||||
if (resource instanceof PsiResourceVariable) {
|
||||
myCurrentFlow.removeVariable((PsiVariable)resource);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1029,12 +1031,19 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
|
||||
@Override
|
||||
public void visitResourceList(PsiResourceList resourceList) {
|
||||
for (PsiResourceVariable variable : resourceList.getResourceVariables()) {
|
||||
PsiExpression initializer = variable.getInitializer();
|
||||
if (initializer != null) {
|
||||
initializeVariable(variable, initializer);
|
||||
for (PsiResourceListElement resource : resourceList) {
|
||||
if (resource instanceof PsiResourceVariable) {
|
||||
PsiResourceVariable variable = (PsiResourceVariable)resource;
|
||||
PsiExpression initializer = variable.getInitializer();
|
||||
if (initializer != null) {
|
||||
initializeVariable(variable, initializer);
|
||||
}
|
||||
}
|
||||
PsiMethod closer = PsiUtil.getResourceCloserMethod(variable);
|
||||
else if (resource instanceof PsiResourceExpression) {
|
||||
((PsiResourceExpression)resource).getExpression().accept(this);
|
||||
}
|
||||
|
||||
PsiMethod closer = PsiUtil.getResourceCloserMethod(resource);
|
||||
if (closer != null) {
|
||||
addMethodThrows(closer, null);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -502,8 +502,8 @@ public class ExpectedTypesProvider {
|
||||
|
||||
@Override public void visitVariable(@NotNull PsiVariable variable) {
|
||||
PsiType type = variable.getType();
|
||||
myResult.add(createInfoImpl(type, ExpectedTypeInfo.TYPE_OR_SUBTYPE, type,
|
||||
variable instanceof PsiResourceVariable ? TailType.NONE : TailType.SEMICOLON, null, getPropertyName(variable)));
|
||||
TailType tail = variable instanceof PsiResourceVariable ? TailType.NONE : TailType.SEMICOLON;
|
||||
myResult.add(createInfoImpl(type, ExpectedTypeInfo.TYPE_OR_SUBTYPE, type, tail, null, getPropertyName(variable)));
|
||||
}
|
||||
|
||||
@Override public void visitAssignmentExpression(@NotNull PsiAssignmentExpression assignment) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -51,20 +51,26 @@ public class PreferByKindWeigher extends LookupElementWeigher {
|
||||
withParent(psiElement(PsiTypeElement.class).
|
||||
withParent(or(psiElement(PsiCatchSection.class),
|
||||
psiElement(PsiVariable.class).withParent(PsiCatchSection.class)))));
|
||||
|
||||
static final ElementPattern<PsiElement> IN_MULTI_CATCH_TYPE =
|
||||
or(psiElement().afterLeaf(psiElement().withText("|").withParent(PsiTypeElement.class).withSuperParent(2, PsiCatchSection.class)),
|
||||
psiElement().afterLeaf(psiElement().withText("|").withParent(PsiTypeElement.class).withSuperParent(2, PsiParameter.class)
|
||||
.withSuperParent(3, PsiCatchSection.class)));
|
||||
or(psiElement().afterLeaf(psiElement().withText("|").
|
||||
withParent(PsiTypeElement.class).withSuperParent(2, PsiCatchSection.class)),
|
||||
psiElement().afterLeaf(psiElement().withText("|").
|
||||
withParent(PsiTypeElement.class).withSuperParent(2, PsiParameter.class).withSuperParent(3, PsiCatchSection.class)));
|
||||
|
||||
static final ElementPattern<PsiElement> INSIDE_METHOD_THROWS_CLAUSE =
|
||||
psiElement().afterLeaf(PsiKeyword.THROWS, ",").inside(psiElement(JavaElementType.THROWS_LIST));
|
||||
static final ElementPattern<PsiElement> IN_RESOURCE_TYPE =
|
||||
psiElement().withParent(psiElement(PsiJavaCodeReferenceElement.class).
|
||||
withParent(psiElement(PsiTypeElement.class).
|
||||
withParent(or(psiElement(PsiResourceVariable.class), psiElement(PsiResourceList.class)))));
|
||||
|
||||
static final ElementPattern<PsiElement> IN_RESOURCE =
|
||||
psiElement().withParent(or(
|
||||
psiElement(PsiJavaCodeReferenceElement.class).withParent(PsiTypeElement.class).
|
||||
withSuperParent(2, or(psiElement(PsiResourceVariable.class), psiElement(PsiResourceList.class))),
|
||||
psiElement(PsiReferenceExpression.class).withParent(PsiResourceExpression.class)));
|
||||
|
||||
private final CompletionType myCompletionType;
|
||||
private final PsiElement myPosition;
|
||||
private final Set<PsiField> myNonInitializedFields;
|
||||
@NotNull private final Condition<PsiClass> myRequiredSuper;
|
||||
private final Condition<PsiClass> myRequiredSuper;
|
||||
|
||||
public PreferByKindWeigher(CompletionType completionType, final PsiElement position) {
|
||||
super("kind");
|
||||
@@ -74,6 +80,7 @@ public class PreferByKindWeigher extends LookupElementWeigher {
|
||||
myRequiredSuper = createSuitabilityCondition(position);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Condition<PsiClass> createSuitabilityCondition(final PsiElement position) {
|
||||
if (IN_CATCH_TYPE.accepts(position) || IN_MULTI_CATCH_TYPE.accepts(position)) {
|
||||
PsiTryStatement tryStatement = PsiTreeUtil.getParentOfType(position, PsiTryStatement.class);
|
||||
@@ -109,7 +116,7 @@ public class PreferByKindWeigher extends LookupElementWeigher {
|
||||
};
|
||||
}
|
||||
|
||||
if (IN_RESOURCE_TYPE.accepts(position)) {
|
||||
if (IN_RESOURCE.accepts(position)) {
|
||||
return new Condition<PsiClass>() {
|
||||
@Override
|
||||
public boolean value(PsiClass psiClass) {
|
||||
|
||||
+1
@@ -380,6 +380,7 @@ public class ExtractMethodSignatureSuggester {
|
||||
myDuplicatesNumber = duplicatesNumber;
|
||||
setTitle("Extract Parameters to Replace Duplicates");
|
||||
setOKButtonText("Accept Signature Change");
|
||||
setCancelButtonText("Keep Original Signature");
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
+4
-194
@@ -16,84 +16,24 @@
|
||||
package com.intellij.psi.search.searches;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressIndicatorProvider;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.PsiSearchScopeUtil;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Conditions;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.reference.SoftReference;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.Query;
|
||||
import com.intellij.util.QueryExecutor;
|
||||
import com.intellij.util.containers.Stack;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
public class ClassInheritorsSearch extends ExtensibleQueryFactory<PsiClass, ClassInheritorsSearch.SearchParameters> {
|
||||
public static final ExtensionPointName<QueryExecutor> EP_NAME = ExtensionPointName.create("com.intellij.classInheritorsSearch");
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.search.searches.ClassInheritorsSearch");
|
||||
|
||||
public static final ClassInheritorsSearch INSTANCE = new ClassInheritorsSearch();
|
||||
|
||||
static {
|
||||
INSTANCE.registerExecutor(new QueryExecutor<PsiClass, SearchParameters>() {
|
||||
@Override
|
||||
public boolean execute(@NotNull final SearchParameters parameters, @NotNull final Processor<PsiClass> consumer) {
|
||||
final PsiClass baseClass = parameters.getClassToProcess();
|
||||
final SearchScope searchScope = parameters.getScope();
|
||||
|
||||
LOG.assertTrue(searchScope != null);
|
||||
|
||||
ProgressIndicator progress = ProgressIndicatorProvider.getGlobalProgressIndicator();
|
||||
if (progress != null) {
|
||||
progress.pushState();
|
||||
String className = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
|
||||
@Override
|
||||
public String compute() {
|
||||
return baseClass.getName();
|
||||
}
|
||||
});
|
||||
progress.setText(className != null ?
|
||||
PsiBundle.message("psi.search.inheritors.of.class.progress", className) :
|
||||
PsiBundle.message("psi.search.inheritors.progress"));
|
||||
}
|
||||
|
||||
boolean result = processInheritors(consumer, baseClass, searchScope, parameters);
|
||||
|
||||
if (progress != null) {
|
||||
progress.popState();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public interface InheritanceChecker {
|
||||
boolean checkInheritance(@NotNull PsiClass subClass, @NotNull PsiClass parentClass);
|
||||
|
||||
InheritanceChecker DEFAULT = new InheritanceChecker() {
|
||||
@Override
|
||||
public boolean checkInheritance(@NotNull PsiClass subClass, @NotNull PsiClass parentClass) {
|
||||
return subClass.isInheritor(parentClass, false);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static class SearchParameters {
|
||||
private final PsiClass myClass;
|
||||
private final SearchScope myScope;
|
||||
@@ -101,7 +41,6 @@ public class ClassInheritorsSearch extends ExtensibleQueryFactory<PsiClass, Clas
|
||||
private final boolean myCheckInheritance;
|
||||
private final boolean myIncludeAnonymous;
|
||||
private final Condition<String> myNameCondition;
|
||||
private final InheritanceChecker myInheritanceChecker;
|
||||
|
||||
public SearchParameters(@NotNull final PsiClass aClass, @NotNull SearchScope scope, final boolean checkDeep, final boolean checkInheritance, boolean includeAnonymous) {
|
||||
this(aClass, scope, checkDeep, checkInheritance, includeAnonymous, Conditions.<String>alwaysTrue());
|
||||
@@ -109,18 +48,12 @@ public class ClassInheritorsSearch extends ExtensibleQueryFactory<PsiClass, Clas
|
||||
|
||||
public SearchParameters(@NotNull final PsiClass aClass, @NotNull SearchScope scope, final boolean checkDeep, final boolean checkInheritance,
|
||||
boolean includeAnonymous, @NotNull final Condition<String> nameCondition) {
|
||||
this(aClass, scope, checkDeep, checkInheritance, includeAnonymous, nameCondition, InheritanceChecker.DEFAULT);
|
||||
}
|
||||
|
||||
public SearchParameters(@NotNull final PsiClass aClass, @NotNull SearchScope scope, final boolean checkDeep, final boolean checkInheritance,
|
||||
boolean includeAnonymous, @NotNull final Condition<String> nameCondition, @NotNull InheritanceChecker inheritanceChecker) {
|
||||
myClass = aClass;
|
||||
myScope = scope;
|
||||
myCheckDeep = checkDeep;
|
||||
myCheckInheritance = checkInheritance;
|
||||
myIncludeAnonymous = includeAnonymous;
|
||||
myNameCondition = nameCondition;
|
||||
myInheritanceChecker = inheritanceChecker;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -183,127 +116,4 @@ public class ClassInheritorsSearch extends ExtensibleQueryFactory<PsiClass, Clas
|
||||
return search(aClass, true);
|
||||
}
|
||||
|
||||
private static boolean processInheritors(@NotNull final Processor<PsiClass> consumer,
|
||||
@NotNull final PsiClass baseClass,
|
||||
@NotNull final SearchScope searchScope,
|
||||
@NotNull final SearchParameters parameters) {
|
||||
if (baseClass instanceof PsiAnonymousClass || isFinal(baseClass)) return true;
|
||||
|
||||
final String qname = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
|
||||
@Override
|
||||
public String compute() {
|
||||
return baseClass.getQualifiedName();
|
||||
}
|
||||
});
|
||||
if (CommonClassNames.JAVA_LANG_OBJECT.equals(qname)) {
|
||||
Project project = PsiUtilCore.getProjectInReadAction(baseClass);
|
||||
return AllClassesSearch.search(searchScope, project, parameters.getNameCondition()).forEach(new Processor<PsiClass>() {
|
||||
@Override
|
||||
public boolean process(final PsiClass aClass) {
|
||||
ProgressIndicatorProvider.checkCanceled();
|
||||
final String qname1 = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
|
||||
@Override
|
||||
@Nullable
|
||||
public String compute() {
|
||||
return aClass.getQualifiedName();
|
||||
}
|
||||
});
|
||||
return CommonClassNames.JAVA_LANG_OBJECT.equals(qname1) || consumer.process(aClass);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
final Ref<PsiClass> currentBase = Ref.create(null);
|
||||
final Stack<Pair<Reference<PsiClass>, String>> stack = new Stack<Pair<Reference<PsiClass>, String>>();
|
||||
// there are two sets for memory optimization: it's cheaper to hold FQN than PsiClass
|
||||
final Set<String> processedFqns = new THashSet<String>(); // FQN of processed classes if the class has one
|
||||
final Set<PsiClass> processed = new THashSet<PsiClass>(); // processed classes without FQN (e.g. anonymous)
|
||||
|
||||
final Processor<PsiClass> processor = new Processor<PsiClass>() {
|
||||
@Override
|
||||
public boolean process(final PsiClass candidate) {
|
||||
ProgressIndicatorProvider.checkCanceled();
|
||||
|
||||
final Ref<Boolean> result = new Ref<Boolean>();
|
||||
final String[] fqn = new String[1];
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
fqn[0] = candidate.getQualifiedName();
|
||||
if (parameters.isCheckInheritance() || parameters.isCheckDeep() && !(candidate instanceof PsiAnonymousClass)) {
|
||||
if (!parameters.myInheritanceChecker.checkInheritance(candidate, currentBase.get())) {
|
||||
result.set(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (PsiSearchScopeUtil.isInScope(searchScope, candidate)) {
|
||||
if (candidate instanceof PsiAnonymousClass) {
|
||||
result.set(consumer.process(candidate));
|
||||
}
|
||||
else {
|
||||
final String name = candidate.getName();
|
||||
if (name != null && parameters.getNameCondition().value(name) && !consumer.process(candidate)) result.set(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!result.isNull()) return result.get().booleanValue();
|
||||
|
||||
if (parameters.isCheckDeep() && !(candidate instanceof PsiAnonymousClass) && !isFinal(candidate)) {
|
||||
Reference<PsiClass> ref = fqn[0] == null ? createHardReference(candidate) : new SoftReference<PsiClass>(candidate);
|
||||
stack.push(Pair.create(ref, fqn[0]));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
stack.push(Pair.create(createHardReference(baseClass), qname));
|
||||
final GlobalSearchScope projectScope = GlobalSearchScope.allScope(PsiUtilCore.getProjectInReadAction(baseClass));
|
||||
final JavaPsiFacade facade = JavaPsiFacade.getInstance(projectScope.getProject());
|
||||
while (!stack.isEmpty()) {
|
||||
ProgressIndicatorProvider.checkCanceled();
|
||||
|
||||
Pair<Reference<PsiClass>, String> pair = stack.pop();
|
||||
PsiClass psiClass = pair.getFirst().get();
|
||||
final String fqn = pair.getSecond();
|
||||
if (psiClass == null) {
|
||||
psiClass = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
|
||||
@Override
|
||||
public PsiClass compute() {
|
||||
return facade.findClass(fqn, projectScope);
|
||||
}
|
||||
});
|
||||
if (psiClass == null) continue;
|
||||
}
|
||||
if (fqn == null) {
|
||||
if (!processed.add(psiClass)) continue;
|
||||
}
|
||||
else {
|
||||
if (!processedFqns.add(fqn)) continue;
|
||||
}
|
||||
|
||||
currentBase.set(psiClass);
|
||||
if (!DirectClassInheritorsSearch.search(psiClass, projectScope, parameters.isIncludeAnonymous(), false).forEach(processor)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static Reference<PsiClass> createHardReference(final PsiClass candidate) {
|
||||
return new SoftReference<PsiClass>(candidate){
|
||||
@Override
|
||||
public PsiClass get() {
|
||||
return candidate;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static boolean isFinal(@NotNull final PsiClass baseClass) {
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
|
||||
@Override
|
||||
public Boolean compute() {
|
||||
return Boolean.valueOf(baseClass.hasModifierProperty(PsiModifier.FINAL));
|
||||
}
|
||||
}).booleanValue();
|
||||
}
|
||||
}
|
||||
|
||||
+169
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.search;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.QueryExecutorBase;
|
||||
import com.intellij.openapi.application.ReadActionProcessor;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressIndicatorProvider;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.PsiSearchScopeUtil;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.search.searches.AllClassesSearch;
|
||||
import com.intellij.psi.search.searches.ClassInheritorsSearch;
|
||||
import com.intellij.psi.search.searches.DirectClassInheritorsSearch;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.Stack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class JavaClassInheritorsSearcher extends QueryExecutorBase<PsiClass, ClassInheritorsSearch.SearchParameters> {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.search.JavaClassInheritorsSearcher");
|
||||
|
||||
@Override
|
||||
public void processQuery(@NotNull ClassInheritorsSearch.SearchParameters parameters, @NotNull Processor<PsiClass> consumer) {
|
||||
final PsiClass baseClass = parameters.getClassToProcess();
|
||||
final SearchScope searchScope = parameters.getScope();
|
||||
|
||||
LOG.assertTrue(searchScope != null);
|
||||
|
||||
ProgressIndicator progress = ProgressIndicatorProvider.getGlobalProgressIndicator();
|
||||
if (progress != null) {
|
||||
progress.pushState();
|
||||
String className = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
|
||||
@Override
|
||||
public String compute() {
|
||||
return baseClass.getName();
|
||||
}
|
||||
});
|
||||
progress.setText(className != null ?
|
||||
PsiBundle.message("psi.search.inheritors.of.class.progress", className) :
|
||||
PsiBundle.message("psi.search.inheritors.progress"));
|
||||
}
|
||||
|
||||
processInheritors(consumer, baseClass, searchScope, parameters);
|
||||
|
||||
if (progress != null) {
|
||||
progress.popState();
|
||||
}
|
||||
}
|
||||
|
||||
private static void processInheritors(@NotNull final Processor<PsiClass> consumer,
|
||||
@NotNull final PsiClass baseClass,
|
||||
@NotNull final SearchScope searchScope,
|
||||
@NotNull final ClassInheritorsSearch.SearchParameters parameters) {
|
||||
if (baseClass instanceof PsiAnonymousClass || isFinal(baseClass)) return;
|
||||
|
||||
Project project = PsiUtilCore.getProjectInReadAction(baseClass);
|
||||
if (isJavaLangObject(baseClass)) {
|
||||
AllClassesSearch.search(searchScope, project, parameters.getNameCondition()).forEach(new Processor<PsiClass>() {
|
||||
@Override
|
||||
public boolean process(final PsiClass aClass) {
|
||||
ProgressIndicatorProvider.checkCanceled();
|
||||
return isJavaLangObject(aClass) || consumer.process(aClass);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
final Ref<PsiClass> currentBase = Ref.create(null);
|
||||
final Stack<PsiAnchor> stack = new Stack<PsiAnchor>();
|
||||
final Set<PsiAnchor> processed = ContainerUtil.newTroveSet();
|
||||
|
||||
final Processor<PsiClass> processor = new ReadActionProcessor<PsiClass>() {
|
||||
@Override
|
||||
public boolean processInReadAction(PsiClass candidate) {
|
||||
ProgressIndicatorProvider.checkCanceled();
|
||||
|
||||
if (parameters.isCheckInheritance() || parameters.isCheckDeep() && !(candidate instanceof PsiAnonymousClass)) {
|
||||
if (!candidate.isInheritor(currentBase.get(), false)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (PsiSearchScopeUtil.isInScope(searchScope, candidate)) {
|
||||
if (candidate instanceof PsiAnonymousClass) {
|
||||
return consumer.process(candidate);
|
||||
}
|
||||
|
||||
final String name = candidate.getName();
|
||||
if (name != null && parameters.getNameCondition().value(name) && !consumer.process(candidate)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (parameters.isCheckDeep() && !(candidate instanceof PsiAnonymousClass) && !isFinal(candidate)) {
|
||||
stack.push(PsiAnchor.create(candidate));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
stack.push(PsiAnchor.create(baseClass));
|
||||
}
|
||||
});
|
||||
final GlobalSearchScope projectScope = GlobalSearchScope.allScope(project);
|
||||
|
||||
while (!stack.isEmpty()) {
|
||||
ProgressIndicatorProvider.checkCanceled();
|
||||
|
||||
final PsiAnchor anchor = stack.pop();
|
||||
if (!processed.add(anchor)) continue;
|
||||
|
||||
PsiClass psiClass = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
|
||||
@Override
|
||||
public PsiClass compute() {
|
||||
return (PsiClass)anchor.retrieve();
|
||||
}
|
||||
});
|
||||
if (psiClass == null) continue;
|
||||
|
||||
currentBase.set(psiClass);
|
||||
if (!DirectClassInheritorsSearch.search(psiClass, projectScope, parameters.isIncludeAnonymous(), false).forEach(processor)) return;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isJavaLangObject(@NotNull final PsiClass baseClass) {
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
|
||||
@Override
|
||||
public Boolean compute() {
|
||||
return baseClass.isValid() && CommonClassNames.JAVA_LANG_OBJECT.equals(baseClass.getQualifiedName());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static boolean isFinal(@NotNull final PsiClass baseClass) {
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
|
||||
@Override
|
||||
public Boolean compute() {
|
||||
return Boolean.valueOf(baseClass.hasModifierProperty(PsiModifier.FINAL));
|
||||
}
|
||||
}).booleanValue();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -64,6 +64,10 @@ public enum LanguageLevel {
|
||||
return compareTo(level) >= 0;
|
||||
}
|
||||
|
||||
public boolean isLessThan(@NotNull LanguageLevel level) {
|
||||
return compareTo(level) < 0;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static LanguageLevel parse(@Nullable String value) {
|
||||
if ("1.3".equals(value)) return JDK_1_3;
|
||||
|
||||
@@ -17,7 +17,6 @@ package com.intellij.psi;
|
||||
|
||||
import com.intellij.psi.javadoc.*;
|
||||
|
||||
@SuppressWarnings({"JavaDoc"})
|
||||
public abstract class JavaElementVisitor extends PsiElementVisitor {
|
||||
|
||||
public void visitAnonymousClass(PsiAnonymousClass aClass) {
|
||||
@@ -244,6 +243,7 @@ public abstract class JavaElementVisitor extends PsiElementVisitor {
|
||||
* PsiRecursiveElement visitor works that around and implements this method accordingly.
|
||||
* All other visitor must decide themselves what implementation (visitReferenceElement() or visitExpression() or none or LOG.error())
|
||||
* is appropriate for them.
|
||||
*
|
||||
* @param expression
|
||||
*/
|
||||
public void visitReferenceExpression(PsiReferenceExpression expression) {}
|
||||
@@ -308,8 +308,12 @@ public abstract class JavaElementVisitor extends PsiElementVisitor {
|
||||
visitElement(resourceList);
|
||||
}
|
||||
|
||||
public void visitResourceVariable(PsiResourceVariable resourceVariable) {
|
||||
visitLocalVariable(resourceVariable);
|
||||
public void visitResourceVariable(PsiResourceVariable variable) {
|
||||
visitLocalVariable(variable);
|
||||
}
|
||||
|
||||
public void visitResourceExpression(PsiResourceExpression expression) {
|
||||
visitElement(expression);
|
||||
}
|
||||
|
||||
public void visitTypeElement(PsiTypeElement type) {
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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;
|
||||
|
||||
/**
|
||||
* Represents a resource expression of enhanced try-with-resources statement introduced in JDK 9.
|
||||
*
|
||||
* @see PsiResourceList
|
||||
* @since 15
|
||||
*/
|
||||
public interface PsiResourceExpression extends PsiResourceListElement {
|
||||
@NotNull
|
||||
PsiExpression getExpression();
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -15,19 +15,18 @@
|
||||
*/
|
||||
package com.intellij.psi;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a resource list of try-with-resources statement (automatic resource management) introduced in JDK 7.
|
||||
*
|
||||
* @see PsiTryStatement#getResourceList()
|
||||
* @since 10.5.
|
||||
* @since 10.5
|
||||
*/
|
||||
public interface PsiResourceList extends PsiElement {
|
||||
public interface PsiResourceList extends PsiElement, Iterable<PsiResourceListElement> {
|
||||
int getResourceVariablesCount();
|
||||
|
||||
@NotNull
|
||||
/** @deprecated use {@link #iterator()} (to be removed in IDEA 17) */
|
||||
@SuppressWarnings("unused")
|
||||
List<PsiResourceVariable> getResourceVariables();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.Nullable;
|
||||
|
||||
/**
|
||||
* Common interface for {@link PsiResourceVariable} and {@link PsiResourceExpression}.
|
||||
*
|
||||
* @since 15
|
||||
*/
|
||||
public interface PsiResourceListElement extends PsiElement {
|
||||
@Nullable
|
||||
PsiType getType();
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,10 +20,10 @@ import org.jetbrains.annotations.NotNull;
|
||||
/**
|
||||
* Represents a resource variable of try-with-resources statement (automatic resource management) introduced in JDK 7.
|
||||
*
|
||||
* @see PsiResourceList#getResourceVariables()
|
||||
* @since 10.5.
|
||||
* @see PsiResourceList
|
||||
* @since 10.5
|
||||
*/
|
||||
public interface PsiResourceVariable extends PsiLocalVariable {
|
||||
public interface PsiResourceVariable extends PsiLocalVariable, PsiResourceListElement {
|
||||
@NotNull
|
||||
PsiElement[] getDeclarationScope();
|
||||
}
|
||||
|
||||
@@ -1126,10 +1126,15 @@ public final class PsiUtil extends PsiUtilCore {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiMethod getResourceCloserMethod(@NotNull final PsiResourceVariable resource) {
|
||||
final PsiType resourceType = resource.getType();
|
||||
if (!(resourceType instanceof PsiClassType)) return null;
|
||||
return getResourceCloserMethodForType((PsiClassType)resourceType);
|
||||
public static PsiMethod getResourceCloserMethod(@NotNull PsiResourceListElement resource) {
|
||||
PsiType resourceType = resource.getType();
|
||||
return resourceType instanceof PsiClassType ? getResourceCloserMethodForType((PsiClassType)resourceType) : null;
|
||||
}
|
||||
|
||||
/** @deprecated use {@link #getResourceCloserMethod(PsiResourceListElement)} (to be removed in IDEA 17) */
|
||||
@SuppressWarnings("unused")
|
||||
public static PsiMethod getResourceCloserMethod(@NotNull PsiResourceVariable resource) {
|
||||
return getResourceCloserMethod((PsiResourceListElement)resource);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -118,14 +118,19 @@ public class ExceptionUtil {
|
||||
else if (element instanceof PsiTryStatement) {
|
||||
return getTryExceptions((PsiTryStatement)element);
|
||||
}
|
||||
else if (element instanceof PsiResourceVariable) {
|
||||
final PsiResourceVariable variable = (PsiResourceVariable)element;
|
||||
final List<PsiClassType> types = ContainerUtil.newArrayList();
|
||||
addExceptions(types, getCloserExceptions(variable));
|
||||
final PsiExpression initializer = variable.getInitializer();
|
||||
if (initializer != null) addExceptions(types, getThrownExceptions(initializer));
|
||||
else if (element instanceof PsiResourceListElement) {
|
||||
List<PsiClassType> types = ContainerUtil.newArrayList();
|
||||
addExceptions(types, getCloserExceptions((PsiResourceListElement)element));
|
||||
if (element instanceof PsiResourceVariable) {
|
||||
PsiResourceVariable variable = (PsiResourceVariable)element;
|
||||
PsiExpression initializer = variable.getInitializer();
|
||||
if (initializer != null) {
|
||||
addExceptions(types, getThrownExceptions(initializer));
|
||||
}
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
return getThrownExceptions(element.getChildren());
|
||||
}
|
||||
|
||||
@@ -135,8 +140,8 @@ public class ExceptionUtil {
|
||||
|
||||
PsiResourceList resourceList = tryStatement.getResourceList();
|
||||
if (resourceList != null) {
|
||||
for (PsiResourceVariable variable : resourceList.getResourceVariables()) {
|
||||
addExceptions(array, getUnhandledCloserExceptions(variable, resourceList));
|
||||
for (PsiResourceListElement resource : resourceList) {
|
||||
addExceptions(array, getUnhandledCloserExceptions(resource, resourceList));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,16 +308,10 @@ public class ExceptionUtil {
|
||||
}
|
||||
unhandledExceptions = unhandled;
|
||||
}
|
||||
|
||||
if (element instanceof PsiResourceVariable) {
|
||||
final List<PsiClassType> unhandled = getUnhandledCloserExceptions((PsiResourceVariable)element, topElement);
|
||||
else if (element instanceof PsiResourceListElement) {
|
||||
final List<PsiClassType> unhandled = getUnhandledCloserExceptions((PsiResourceListElement)element, topElement);
|
||||
if (!unhandled.isEmpty()) {
|
||||
if (unhandledExceptions == null) {
|
||||
unhandledExceptions = ContainerUtil.newArrayList(unhandled);
|
||||
}
|
||||
else {
|
||||
unhandledExceptions.addAll(unhandled);
|
||||
}
|
||||
unhandledExceptions = ContainerUtil.newArrayList(unhandled);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,6 +355,7 @@ public class ExceptionUtil {
|
||||
@NotNull
|
||||
public static List<PsiClassType> getUnhandledExceptions(final @NotNull PsiElement[] elements) {
|
||||
final List<PsiClassType> array = ContainerUtil.newArrayList();
|
||||
|
||||
final PsiElementVisitor visitor = new JavaRecursiveElementWalkingVisitor() {
|
||||
@Override
|
||||
public void visitCallExpression(@NotNull PsiCallExpression expression) {
|
||||
@@ -377,9 +377,15 @@ public class ExceptionUtil {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitResourceVariable(@NotNull PsiResourceVariable resourceVariable) {
|
||||
addExceptions(array, getUnhandledCloserExceptions(resourceVariable, null));
|
||||
visitElement(resourceVariable);
|
||||
public void visitResourceVariable(@NotNull PsiResourceVariable resource) {
|
||||
addExceptions(array, getUnhandledCloserExceptions((PsiResourceListElement)resource, null));
|
||||
visitElement(resource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitResourceExpression(@NotNull PsiResourceExpression resource) {
|
||||
addExceptions(array, getUnhandledCloserExceptions(resource, null));
|
||||
visitElement(resource);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -392,18 +398,6 @@ public class ExceptionUtil {
|
||||
|
||||
@NotNull
|
||||
public static List<PsiClassType> getUnhandledExceptions(@NotNull PsiElement element) {
|
||||
if (element instanceof PsiCallExpression) {
|
||||
PsiCallExpression expression = (PsiCallExpression)element;
|
||||
return getUnhandledExceptions(expression, null);
|
||||
}
|
||||
else if (element instanceof PsiThrowStatement) {
|
||||
PsiThrowStatement throwStatement = (PsiThrowStatement)element;
|
||||
return getUnhandledExceptions(throwStatement, null);
|
||||
}
|
||||
else if (element instanceof PsiResourceVariable) {
|
||||
return getUnhandledCloserExceptions((PsiResourceVariable)element, null);
|
||||
}
|
||||
|
||||
return getUnhandledExceptions(new PsiElement[]{element});
|
||||
}
|
||||
|
||||
@@ -532,19 +526,31 @@ public class ExceptionUtil {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<PsiClassType> getCloserExceptions(@NotNull PsiResourceVariable resource) {
|
||||
public static List<PsiClassType> getCloserExceptions(@NotNull PsiResourceListElement resource) {
|
||||
PsiMethod method = PsiUtil.getResourceCloserMethod(resource);
|
||||
PsiSubstitutor substitutor = PsiUtil.resolveGenericsClassInType(resource.getType()).getSubstitutor();
|
||||
return method != null ? getExceptionsByMethod(method, substitutor, resource) : Collections.<PsiClassType>emptyList();
|
||||
}
|
||||
|
||||
/** @deprecated use {@link #getCloserExceptions(PsiResourceListElement)} (to be removed in IDEA 16) */
|
||||
@SuppressWarnings("unused")
|
||||
public static List<PsiClassType> getCloserExceptions(@NotNull PsiResourceVariable resource) {
|
||||
return getCloserExceptions((PsiResourceListElement)resource);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<PsiClassType> getUnhandledCloserExceptions(@NotNull PsiResourceVariable resource, @Nullable PsiElement topElement) {
|
||||
public static List<PsiClassType> getUnhandledCloserExceptions(@NotNull PsiResourceListElement resource, @Nullable PsiElement topElement) {
|
||||
PsiMethod method = PsiUtil.getResourceCloserMethod(resource);
|
||||
PsiSubstitutor substitutor = PsiUtil.resolveGenericsClassInType(resource.getType()).getSubstitutor();
|
||||
return method != null ? getUnhandledExceptions(method, resource, topElement, substitutor) : Collections.<PsiClassType>emptyList();
|
||||
}
|
||||
|
||||
/** @deprecated use {@link #getUnhandledCloserExceptions(PsiResourceListElement, PsiElement)} (to be removed in IDEA 16) */
|
||||
@SuppressWarnings("unused")
|
||||
public static List<PsiClassType> getUnhandledCloserExceptions(@NotNull PsiResourceVariable resource, @Nullable PsiElement topElement) {
|
||||
return getUnhandledCloserExceptions((PsiResourceListElement)resource, topElement);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<PsiClassType> getUnhandledExceptions(@NotNull PsiThrowStatement throwStatement, @Nullable PsiElement topElement) {
|
||||
List<PsiClassType> unhandled = new SmartList<PsiClassType>();
|
||||
@@ -574,7 +580,7 @@ public class ExceptionUtil {
|
||||
if (expression != null) {
|
||||
final PsiType type = expression.getType();
|
||||
if (type != null) {
|
||||
return Arrays.asList(type);
|
||||
return Collections.singletonList(type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,8 @@ public class DeclarationParser {
|
||||
JavaTokenType.RPARENTH, JavaTokenType.LBRACE, JavaTokenType.ARROW);
|
||||
private static final TokenSet TYPE_START = TokenSet.orSet(
|
||||
ElementType.PRIMITIVE_TYPE_BIT_SET, TokenSet.create(JavaTokenType.IDENTIFIER, JavaTokenType.AT));
|
||||
private static final TokenSet RESOURCE_EXPRESSIONS = TokenSet.create(
|
||||
JavaElementType.REFERENCE_EXPRESSION, JavaElementType.THIS_EXPRESSION);
|
||||
|
||||
private static final String WHITESPACES = "\n\r \t";
|
||||
private static final String LINE_ENDS = "\n\r";
|
||||
@@ -575,6 +577,16 @@ public class DeclarationParser {
|
||||
|
||||
@Nullable
|
||||
public PsiBuilder.Marker parseResource(PsiBuilder builder) {
|
||||
PsiBuilder.Marker marker = builder.mark();
|
||||
|
||||
PsiBuilder.Marker expr = myParser.getExpressionParser().parse(builder);
|
||||
if (expr != null && RESOURCE_EXPRESSIONS.contains(exprType(expr)) && builder.getTokenType() != JavaTokenType.IDENTIFIER) {
|
||||
marker.done(JavaElementType.RESOURCE_EXPRESSION);
|
||||
return marker;
|
||||
}
|
||||
|
||||
marker.rollbackTo();
|
||||
|
||||
return parseListElement(builder, true, false, false, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -1163,10 +1163,14 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
public void visitResourceList(final PsiResourceList resourceList) {
|
||||
startElement(resourceList);
|
||||
|
||||
final List<PsiResourceVariable> resources = resourceList.getResourceVariables();
|
||||
for (PsiResourceVariable resource : resources) {
|
||||
for (PsiResourceListElement resource : resourceList) {
|
||||
ProgressIndicatorProvider.checkCanceled();
|
||||
processVariable(resource);
|
||||
if (resource instanceof PsiResourceVariable) {
|
||||
processVariable((PsiVariable)resource);
|
||||
}
|
||||
else if (resource instanceof PsiResourceExpression) {
|
||||
((PsiResourceExpression)resource).getExpression().accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
finishElement(resourceList);
|
||||
|
||||
@@ -239,11 +239,9 @@ public class PsiImplUtil {
|
||||
final ElementClassHint hint = processor.getHint(ElementClassHint.KEY);
|
||||
if (hint != null && !hint.shouldProcess(ElementClassHint.DeclarationKind.VARIABLE)) return true;
|
||||
|
||||
final List<PsiResourceVariable> resources = resourceList.getResourceVariables();
|
||||
@SuppressWarnings({"SuspiciousMethodCalls"})
|
||||
final int lastIdx = lastParent instanceof PsiResourceVariable ? resources.indexOf(lastParent) : resources.size();
|
||||
for (int i = 0; i < lastIdx; i++) {
|
||||
if (!processor.execute(resources.get(i), state)) return false;
|
||||
for (PsiResourceListElement resource : resourceList) {
|
||||
if (resource == lastParent) break;
|
||||
if (resource instanceof PsiResourceVariable && !processor.execute(resource, state)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
+8
-1
@@ -233,7 +233,14 @@ public class InferenceSession {
|
||||
|
||||
private static PsiType getParameterType(PsiParameter[] parameters, int i, @Nullable PsiSubstitutor substitutor, boolean varargs) {
|
||||
if (substitutor == null) return null;
|
||||
PsiType parameterType = substitutor.substitute(parameters[i < parameters.length ? i : parameters.length - 1].getType());
|
||||
|
||||
final PsiParameter parameter = parameters[i < parameters.length ? i : parameters.length - 1];
|
||||
final PsiType type = parameter.getType();
|
||||
if (!type.isValid()) {
|
||||
PsiUtil.ensureValidType(type, "Invalid type of parameter " + parameter + " of " + parameter.getClass());
|
||||
}
|
||||
|
||||
PsiType parameterType = substitutor.substitute(type);
|
||||
if (parameterType instanceof PsiEllipsisType && varargs) {
|
||||
parameterType = ((PsiEllipsisType)parameterType).getComponentType();
|
||||
}
|
||||
|
||||
@@ -133,6 +133,7 @@ public interface JavaElementType {
|
||||
IElementType TRY_STATEMENT = new JavaCompositeElementType("TRY_STATEMENT", PsiTryStatementImpl.class);
|
||||
IElementType RESOURCE_LIST = new JavaCompositeElementType("RESOURCE_LIST", PsiResourceListImpl.class);
|
||||
IElementType RESOURCE_VARIABLE = new JavaCompositeElementType("RESOURCE_VARIABLE", PsiResourceVariableImpl.class);
|
||||
IElementType RESOURCE_EXPRESSION = new JavaCompositeElementType("RESOURCE_EXPRESSION", PsiResourceExpressionImpl.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);
|
||||
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.psi.impl.source.tree.java;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.tree.CompositePsiElement;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class PsiResourceExpressionImpl extends CompositePsiElement implements PsiResourceExpression {
|
||||
public PsiResourceExpressionImpl() {
|
||||
super(JavaElementType.RESOURCE_EXPRESSION);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiExpression getExpression() {
|
||||
return (PsiExpression)getFirstChild();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiType getType() {
|
||||
return getExpression().getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(@NotNull PsiElementVisitor visitor) {
|
||||
if (visitor instanceof JavaElementVisitor) {
|
||||
((JavaElementVisitor)visitor).visitResourceExpression(this);
|
||||
}
|
||||
else {
|
||||
visitor.visitElement(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PsiResourceExpression";
|
||||
}
|
||||
}
|
||||
+17
-10
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -24,6 +24,7 @@ import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class PsiResourceListImpl extends CompositePsiElement implements PsiResourceList {
|
||||
@@ -35,19 +36,25 @@ public class PsiResourceListImpl extends CompositePsiElement implements PsiResou
|
||||
public int getResourceVariablesCount() {
|
||||
int count = 0;
|
||||
for (PsiElement child = getFirstChild(); child != null; child = child.getNextSibling()) {
|
||||
if (child instanceof PsiResourceVariable) ++count;
|
||||
if (child instanceof PsiResourceListElement) ++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Deprecated
|
||||
@Override
|
||||
public List<PsiResourceVariable> getResourceVariables() {
|
||||
return PsiTreeUtil.getChildrenOfTypeAsList(this, PsiResourceVariable.class);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public void accept(@NotNull final PsiElementVisitor visitor) {
|
||||
public Iterator<PsiResourceListElement> iterator() {
|
||||
return PsiTreeUtil.childIterator(this, PsiResourceListElement.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(@NotNull PsiElementVisitor visitor) {
|
||||
if (visitor instanceof JavaElementVisitor) {
|
||||
((JavaElementVisitor)visitor).visitResourceList(this);
|
||||
}
|
||||
@@ -57,16 +64,16 @@ public class PsiResourceListImpl extends CompositePsiElement implements PsiResou
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processDeclarations(@NotNull final PsiScopeProcessor processor,
|
||||
@NotNull final ResolveState state,
|
||||
final PsiElement lastParent,
|
||||
@NotNull final PsiElement place) {
|
||||
public boolean processDeclarations(@NotNull PsiScopeProcessor processor,
|
||||
@NotNull ResolveState state,
|
||||
PsiElement lastParent,
|
||||
@NotNull PsiElement place) {
|
||||
return PsiImplUtil.processDeclarationsInResourceList(this, processor, state, lastParent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteChildInternal(@NotNull final ASTNode child) {
|
||||
if (child.getPsi() instanceof PsiResourceVariable && getResourceVariablesCount() == 1) {
|
||||
public void deleteChildInternal(@NotNull ASTNode child) {
|
||||
if (child.getPsi() instanceof PsiResourceListElement && getResourceVariablesCount() == 1) {
|
||||
getTreeParent().deleteChildInternal(this);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -144,6 +144,7 @@ assignment.to.final.variable=Cannot assign a value to final variable ''{0}''
|
||||
variable.must.be.final=Variable ''{0}'' is accessed from within inner class, needs to be declared final
|
||||
variable.must.be.final.or.effectively.final=Variable ''{0}'' is accessed from within inner class, needs to be final or effectively final
|
||||
lambda.variable.must.be.final=Variable used in lambda expression should be final or effectively final
|
||||
resource.variable.must.be.final=Variable used as a try-with-resources resource should be final or effectively final
|
||||
initializer.must.be.able.to.complete.normally=Initializer must be able to complete normally
|
||||
weaker.privileges={0}; attempting to assign weaker access privileges (''{1}''); was ''{2}''
|
||||
incompatible.return.type=attempting to use incompatible return type
|
||||
@@ -378,7 +379,8 @@ override.not.allowed.in.interfaces=@Override is not allowed when implementing in
|
||||
wildcard.not.expected=Unexpected wildcard
|
||||
bound.not.expected=Unexpected bound
|
||||
|
||||
underscore.identifier=Use of '_' as an identifier might not be supported in releases after Java 8
|
||||
underscore.identifier.warn=Use of '_' as an identifier might not be supported in releases after Java 8
|
||||
underscore.identifier.error=As of Java 9, '_' is a keyword, and may not be used as an identifier
|
||||
underscore.lambda.identifier=Use of '_' as a lambda parameter name is not allowed
|
||||
|
||||
feature.generics=Generics
|
||||
@@ -397,4 +399,5 @@ feature.method.references=Method references
|
||||
feature.lambda.expressions=Lambda expressions
|
||||
feature.type.annotations=Type annotations
|
||||
feature.type.receivers=Receiver parameters
|
||||
feature.try.with.resources.refs=Resource references
|
||||
insufficient.language.level={0} are not supported at this language level
|
||||
|
||||
@@ -17,10 +17,11 @@ package com.intellij.execution;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class TestDiscoveryListener {
|
||||
public abstract class TestDiscoveryListener {
|
||||
public abstract String getFrameworkId();
|
||||
public void testStarted(String className, String methodName) {
|
||||
final Object data = getData();
|
||||
try {
|
||||
final Object data = getData();
|
||||
Method testStarted = data.getClass().getMethod("testStarted", new Class[] {String.class});
|
||||
testStarted.invoke(data, new Object[] {className + "-" + methodName});
|
||||
} catch (Throwable t) {
|
||||
@@ -29,24 +30,19 @@ public class TestDiscoveryListener {
|
||||
}
|
||||
|
||||
public void testFinished(String className, String methodName) {
|
||||
final Object data = getData();
|
||||
try {
|
||||
final Object data = getData();
|
||||
Method testEnded = data.getClass().getMethod("testEnded", new Class[] {String.class});
|
||||
testEnded.invoke(data, new Object[] {className + "-" + methodName});
|
||||
testEnded.invoke(data, new Object[] {getFrameworkId() + className + "-" + methodName});
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
protected Object getData() {
|
||||
try {
|
||||
return Class.forName("org.jetbrains.testme.instrumentation.ProjectData")
|
||||
protected Object getData() throws Exception {
|
||||
return Class.forName("org.jetbrains.testme.instrumentation.ProjectData")
|
||||
.getMethod("getProjectData", new Class[0])
|
||||
.invoke(null, new Object[0]);
|
||||
|
||||
} catch (Exception e) {
|
||||
return null; //should not happen
|
||||
}
|
||||
}
|
||||
|
||||
public void testRunStarted(String name) {}
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
class MyClass {
|
||||
void f() {
|
||||
String response;
|
||||
AutoCloseable resource;
|
||||
try (re<caret>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
class MyClass {
|
||||
void f() {
|
||||
String response;
|
||||
AutoCloseable resource;
|
||||
try (resource<caret>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import java.io.*;
|
||||
|
||||
class UnsupportedFeatures {
|
||||
void m() throws Exception {
|
||||
Reader r1 = new FileReader("/dev/null");
|
||||
try (<error descr="Resource references are not supported at this language level">r1</error>; Reader r2 = new FileReader("/dev/null")) { }
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
import java.io.IOException;
|
||||
|
||||
class TryWithResources {
|
||||
final AutoCloseable f1 = null;
|
||||
AutoCloseable f2 = null;
|
||||
|
||||
void testFields() throws Exception {
|
||||
try (f1; <error descr="Variable used as a try-with-resources resource should be final or effectively final">f2</error>) { }
|
||||
catch (Exception ignore) { }
|
||||
}
|
||||
|
||||
void testLocalVars() throws Exception {
|
||||
final AutoCloseable r1 = null;
|
||||
AutoCloseable r2 = null;
|
||||
AutoCloseable r3 = null;
|
||||
try (r1; r2; <error descr="Variable used as a try-with-resources resource should be final or effectively final">r3</error>) { }
|
||||
r3 = null;
|
||||
}
|
||||
|
||||
void testType() throws Exception {
|
||||
String s = "";
|
||||
try (<error descr="Incompatible types. Found: 'java.lang.String', required: 'java.lang.AutoCloseable'">s</error>;
|
||||
<error descr="Incompatible types. Found: 'TryWithResources', required: 'java.lang.AutoCloseable'">this</error>) { }
|
||||
}
|
||||
|
||||
void testUnhandled() {
|
||||
class Resource implements AutoCloseable {
|
||||
@Override public void close() throws IOException { }
|
||||
}
|
||||
Resource r = new Resource();
|
||||
try (<error descr="Unhandled exception from auto-closeable resource: java.io.IOException">r</error>) { }
|
||||
}
|
||||
|
||||
void testResolve() throws Exception {
|
||||
try (<error descr="Cannot resolve symbol 'r'">r</error>; AutoCloseable r = null) { }
|
||||
try (AutoCloseable r = null; r) { }
|
||||
}
|
||||
|
||||
void testUnassigned() throws Exception {
|
||||
AutoCloseable r;
|
||||
try (<error descr="Variable 'r' might not have been initialized">r</error>) {
|
||||
System.out.println(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
class Undescore {
|
||||
void <error descr="As of Java 9, '_' is a keyword, and may not be used as an identifier">_</error>() { }
|
||||
}
|
||||
-1
@@ -15,7 +15,6 @@ class C {
|
||||
@interface Anno { String f(Anno this); }
|
||||
|
||||
void m0() {
|
||||
try (Object <error descr="Receivers are not allowed outside of method parameter list">this</error>) { }
|
||||
Runnable r = (C <error descr="Receivers are not allowed outside of method parameter list">C.this</error>) -> { };
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
PsiJavaFile:TryIncomplete18.java
|
||||
PsiTryStatement
|
||||
PsiKeyword:try('try')
|
||||
PsiResourceList:(R<T> r)
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiResourceVariable:r
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeElement:R<T>
|
||||
PsiJavaCodeReferenceElement:R<T>
|
||||
PsiIdentifier:R('R')
|
||||
PsiReferenceParameterList
|
||||
PsiJavaToken:LT('<')
|
||||
PsiTypeElement:T
|
||||
PsiJavaCodeReferenceElement:T
|
||||
PsiIdentifier:T('T')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiJavaToken:GT('>')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:r('r')
|
||||
PsiErrorElement:'=' expected
|
||||
<empty list>
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiCodeBlock
|
||||
PsiJavaToken:LBRACE('{')
|
||||
PsiJavaToken:RBRACE('}')
|
||||
@@ -0,0 +1,14 @@
|
||||
PsiJavaFile:TryNormal10.java
|
||||
PsiTryStatement
|
||||
PsiKeyword:try('try')
|
||||
PsiResourceList:(this)
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiResourceExpression
|
||||
PsiThisExpression:this
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiKeyword:this('this')
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiCodeBlock
|
||||
PsiJavaToken:LBRACE('{')
|
||||
PsiJavaToken:RBRACE('}')
|
||||
@@ -0,0 +1,14 @@
|
||||
PsiJavaFile:TryNormal7.java
|
||||
PsiTryStatement
|
||||
PsiKeyword:try('try')
|
||||
PsiResourceList:(r)
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiResourceExpression
|
||||
PsiReferenceExpression:r
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiIdentifier:r('r')
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiCodeBlock
|
||||
PsiJavaToken:LBRACE('{')
|
||||
PsiJavaToken:RBRACE('}')
|
||||
@@ -0,0 +1,15 @@
|
||||
PsiJavaFile:TryNormal8.java
|
||||
PsiTryStatement
|
||||
PsiKeyword:try('try')
|
||||
PsiResourceList:(r;)
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiResourceExpression
|
||||
PsiReferenceExpression:r
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiIdentifier:r('r')
|
||||
PsiJavaToken:SEMICOLON(';')
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiCodeBlock
|
||||
PsiJavaToken:LBRACE('{')
|
||||
PsiJavaToken:RBRACE('}')
|
||||
@@ -0,0 +1,31 @@
|
||||
PsiJavaFile:TryNormal9.java
|
||||
PsiTryStatement
|
||||
PsiKeyword:try('try')
|
||||
PsiResourceList:(r1; R r2 = 0)
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiResourceExpression
|
||||
PsiReferenceExpression:r1
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiIdentifier:r1('r1')
|
||||
PsiJavaToken:SEMICOLON(';')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiResourceVariable:r2
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeElement:R
|
||||
PsiJavaCodeReferenceElement:R
|
||||
PsiIdentifier:R('R')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:r2('r2')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:EQ('=')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiLiteralExpression:0
|
||||
PsiJavaToken:INTEGER_LITERAL('0')
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiCodeBlock
|
||||
PsiJavaToken:LBRACE('{')
|
||||
PsiJavaToken:RBRACE('}')
|
||||
+5
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -22,7 +22,7 @@ import org.jetbrains.annotations.NotNull
|
||||
public class Normal17CompletionTest extends LightFixtureCompletionTestCase {
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return JavaTestUtil.getRelativeJavaTestDataPath() + "/codeInsight/completion/normal/";
|
||||
return JavaTestUtil.getRelativeJavaTestDataPath() + "/codeInsight/completion/normal/"
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -38,6 +38,7 @@ public class Normal17CompletionTest extends LightFixtureCompletionTestCase {
|
||||
public void testOnlyResourcesInResourceList2() { doTest() }
|
||||
public void testOnlyResourcesInResourceList3() { doTest() }
|
||||
public void testOnlyResourcesInResourceList4() { doTest() }
|
||||
public void testOnlyResourcesInResourceList5() { doTest() }
|
||||
|
||||
public void testMethodReferenceNoStatic() { doTest() }
|
||||
public void testMethodReferenceCallContext() { doTest() }
|
||||
@@ -47,7 +48,8 @@ public class Normal17CompletionTest extends LightFixtureCompletionTestCase {
|
||||
assert 'MyOuterResource' == myFixture.lookupElementStrings[0]
|
||||
assert 'MyClass' in myFixture.lookupElementStrings
|
||||
myFixture.type('C\n')
|
||||
checkResultByFile(getTestName(false) + "_after.java") }
|
||||
checkResultByFile(getTestName(false) + "_after.java")
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
configureByFile(getTestName(false) + ".java")
|
||||
|
||||
+1
@@ -48,4 +48,5 @@ public class LightAdvHighlightingJdk8Test extends LightDaemonAnalyzerTestCase {
|
||||
public void testMethodReferences() { doTest(false, true); }
|
||||
public void testUsedMethodsByMethodReferences() { enableInspectionTool(new UnusedDeclarationInspection()); doTest(true, true); }
|
||||
public void testLambdaExpressions() { doTest(false, true); }
|
||||
public void testUnsupportedFeatures() { doTest(false, false); }
|
||||
}
|
||||
|
||||
+3
-2
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.daemon;
|
||||
|
||||
import com.intellij.codeInspection.compiler.JavacQuirksInspection;
|
||||
import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection;
|
||||
import com.intellij.codeInspection.redundantCast.RedundantCastInspection;
|
||||
import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection;
|
||||
@@ -30,7 +29,7 @@ public class LightAdvHighlightingJdk9Test extends LightDaemonAnalyzerTestCase {
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
enableInspectionTools(new UnusedDeclarationInspection(), new UncheckedWarningLocalInspection(), new JavacQuirksInspection(), new RedundantCastInspection());
|
||||
enableInspectionTools(new UnusedDeclarationInspection(), new UncheckedWarningLocalInspection(), new RedundantCastInspection());
|
||||
setLanguageLevel(LanguageLevel.JDK_1_9);
|
||||
IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_9, getModule(), getTestRootDisposable());
|
||||
}
|
||||
@@ -46,6 +45,8 @@ public class LightAdvHighlightingJdk9Test extends LightDaemonAnalyzerTestCase {
|
||||
|
||||
public void testSafeVarargsApplicability() { doTest(true, false); }
|
||||
public void testPrivateInInterfaces() { doTest(false, false); }
|
||||
public void testUnderscore() { doTest(false, false); }
|
||||
public void testTryWithResources() { doTest(false, false); }
|
||||
|
||||
public void testValueTypes() { setLanguageLevel(LanguageLevel.JDK_X); doTest(false, false); }
|
||||
}
|
||||
|
||||
@@ -122,6 +122,10 @@ public class StatementParserTest extends JavaParsingTestCase {
|
||||
public void testTryNormal4() { doParserTest("try(R r = 0){}"); }
|
||||
public void testTryNormal5() { doParserTest("try(R1 r1 = 1; R2 r2 = 2){}"); }
|
||||
public void testTryNormal6() { doParserTest("try(R r = 0;){}"); }
|
||||
public void testTryNormal7() { doParserTest("try(r){}"); }
|
||||
public void testTryNormal8() { doParserTest("try(r;){}"); }
|
||||
public void testTryNormal9() { doParserTest("try(r1; R r2 = 0){}"); }
|
||||
public void testTryNormal10() { doParserTest("try(this){}"); }
|
||||
public void testTryIncomplete0() { doParserTest("try"); }
|
||||
public void testTryIncomplete1() { doParserTest("try{}"); }
|
||||
public void testTryIncomplete2() { doParserTest("try{}catch"); }
|
||||
@@ -140,6 +144,7 @@ public class StatementParserTest extends JavaParsingTestCase {
|
||||
public void testTryIncomplete15() { doParserTest("try(R r){}"); }
|
||||
public void testTryIncomplete16() { doParserTest("try(R r =){}"); }
|
||||
public void testTryIncomplete17() { doParserTest("try(R r = 0;;){}"); }
|
||||
public void testTryIncomplete18() { doParserTest("try(R<T> r){}"); }
|
||||
|
||||
public void testWhileNormal() { doParserTest("while (true) foo();"); }
|
||||
public void testWhileIncomplete0() { doParserTest("while"); }
|
||||
|
||||
@@ -70,8 +70,8 @@ public class MultiModuleEditingTest extends ModuleTestCase {
|
||||
|
||||
{
|
||||
final ModifiableModuleModel modifiableModel = moduleManager.getModifiableModel();
|
||||
moduleA = modifiableModel.newModule(new File("a.iml").getAbsolutePath(), StdModuleTypes.JAVA.getId());
|
||||
moduleB = modifiableModel.newModule(new File("b.iml").getAbsolutePath(), StdModuleTypes.JAVA.getId());
|
||||
moduleA = modifiableModel.newModule("a.iml", StdModuleTypes.JAVA.getId());
|
||||
moduleB = modifiableModel.newModule("b.iml", StdModuleTypes.JAVA.getId());
|
||||
assertEquals("Changes are not applied until commit", 0, moduleManager.getModules().length);
|
||||
//noinspection SSBasedInspection
|
||||
moduleListener.assertCorrectEvents(new String[0][]);
|
||||
@@ -107,8 +107,8 @@ public class MultiModuleEditingTest extends ModuleTestCase {
|
||||
final Module moduleB;
|
||||
{
|
||||
final ModifiableModuleModel moduleModel = moduleManager.getModifiableModel();
|
||||
moduleA = moduleModel.newModule(new File("a.iml").getAbsolutePath(), StdModuleTypes.JAVA.getId());
|
||||
moduleB = moduleModel.newModule(new File("b.iml").getAbsolutePath(), StdModuleTypes.JAVA.getId());
|
||||
moduleA = moduleModel.newModule("a.iml", StdModuleTypes.JAVA.getId());
|
||||
moduleB = moduleModel.newModule("b.iml", StdModuleTypes.JAVA.getId());
|
||||
final ModifiableRootModel rootModelA = ModuleRootManager.getInstance(moduleA).getModifiableModel();
|
||||
final ModifiableRootModel rootModelB = ModuleRootManager.getInstance(moduleB).getModifiableModel();
|
||||
rootModelB.addModuleOrderEntry(moduleA);
|
||||
@@ -146,9 +146,9 @@ public class MultiModuleEditingTest extends ModuleTestCase {
|
||||
|
||||
{
|
||||
final ModifiableModuleModel moduleModel = moduleManager.getModifiableModel();
|
||||
moduleA = moduleModel.newModule(new File("a.iml").getAbsolutePath(), StdModuleTypes.JAVA.getId());
|
||||
moduleB = moduleModel.newModule(new File("b.iml").getAbsolutePath(), StdModuleTypes.JAVA.getId());
|
||||
final Module moduleC = moduleModel.newModule(new File("c.iml").getAbsolutePath(), StdModuleTypes.JAVA.getId());
|
||||
moduleA = moduleModel.newModule("a.iml", StdModuleTypes.JAVA.getId());
|
||||
moduleB = moduleModel.newModule("b.iml", StdModuleTypes.JAVA.getId());
|
||||
final Module moduleC = moduleModel.newModule("c.iml", StdModuleTypes.JAVA.getId());
|
||||
final ModifiableRootModel rootModelB = ModuleRootManager.getInstance(moduleB).getModifiableModel();
|
||||
rootModelB.addModuleOrderEntry(moduleC);
|
||||
moduleModel.disposeModule(moduleC);
|
||||
|
||||
+19
-4
@@ -1,3 +1,18 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.structuralsearch.impl.matcher;
|
||||
|
||||
import com.intellij.dupLocator.iterators.ArrayBackedNodeIterator;
|
||||
@@ -1358,11 +1373,11 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
myMatchingVisitor.setResult(false);
|
||||
return;
|
||||
}
|
||||
final List<PsiResourceVariable> resourceVariables1 = resourceList1.getResourceVariables();
|
||||
final List<PsiResourceVariable> resourceVariables2 = resourceList2.getResourceVariables();
|
||||
final List<PsiResourceListElement> resources1 = PsiTreeUtil.getChildrenOfTypeAsList(resourceList1, PsiResourceListElement.class);
|
||||
final List<PsiResourceListElement> resources2 = PsiTreeUtil.getChildrenOfTypeAsList(resourceList2, PsiResourceListElement.class);
|
||||
myMatchingVisitor.setResult(myMatchingVisitor.matchInAnyOrder(
|
||||
resourceVariables1.toArray(new PsiResourceVariable[resourceVariables1.size()]),
|
||||
resourceVariables2.toArray(new PsiResourceVariable[resourceVariables2.size()])));
|
||||
resources1.toArray(new PsiResourceListElement[resources1.size()]),
|
||||
resources2.toArray(new PsiResourceListElement[resources2.size()])));
|
||||
if (!myMatchingVisitor.getResult()) return;
|
||||
}
|
||||
else if (resourceList2 != null){
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
class ModuleStateStorageManager extends StateStorageManagerImpl {
|
||||
public class ModuleStateStorageManager extends StateStorageManagerImpl {
|
||||
@NonNls private static final String ROOT_TAG_NAME = "module";
|
||||
private final Module myModule;
|
||||
|
||||
|
||||
+5
-6
@@ -135,7 +135,7 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<FileBasedStorage> getCachedFileStorages(@NotNull Collection<String> fileSpecs) {
|
||||
Collection<FileBasedStorage> getCachedFileStorages(@NotNull Collection<String> fileSpecs) {
|
||||
if (fileSpecs.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
@@ -175,14 +175,13 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di
|
||||
((MutablePicoContainer)myPicoContainer).registerComponentImplementation(key, storageClass);
|
||||
return (StateStorage)myPicoContainer.getComponentInstance(key);
|
||||
}
|
||||
final String filePath = expandMacros(fileSpec);
|
||||
File file = new File(filePath).getAbsoluteFile();
|
||||
|
||||
String filePath = expandMacros(fileSpec);
|
||||
File file = new File(filePath);
|
||||
|
||||
//noinspection deprecation
|
||||
if (!stateSplitter.equals(StateSplitter.class) && !stateSplitter.equals(StateSplitterEx.class)) {
|
||||
@SuppressWarnings("deprecation")
|
||||
StateSplitter splitter = ReflectionUtil.newInstance(stateSplitter);
|
||||
return new DirectoryBasedStorage(myPathMacroSubstitutor, file, splitter, this, createStorageTopicListener());
|
||||
return new DirectoryBasedStorage(myPathMacroSubstitutor, file, ReflectionUtil.newInstance(stateSplitter), this, createStorageTopicListener());
|
||||
}
|
||||
|
||||
if (!ApplicationManager.getApplication().isHeadlessEnvironment() && PathUtilRt.getFileName(filePath).lastIndexOf('.') < 0) {
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package com.intellij.openapi.module;
|
||||
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -23,12 +26,28 @@ import org.jetbrains.annotations.Nullable;
|
||||
* @author yole
|
||||
*/
|
||||
public class ModuleServiceManager {
|
||||
private static final Logger LOG = Logger.getInstance(ModuleServiceManager.class);
|
||||
|
||||
private ModuleServiceManager() {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static <T> T getService(@NotNull Module module, @NotNull Class<T> serviceClass) {
|
||||
//noinspection unchecked
|
||||
return (T)module.getPicoContainer().getComponentInstance(serviceClass.getName());
|
||||
T instance = (T)module.getPicoContainer().getComponentInstance(serviceClass.getName());
|
||||
if (instance == null) {
|
||||
instance = module.getComponent(serviceClass);
|
||||
if (instance != null) {
|
||||
Application app = ApplicationManager.getApplication();
|
||||
String message = serviceClass.getName() + " requested as a service, but it is a component - convert it to a service or change call to module.getComponent()";
|
||||
if (app.isUnitTestMode()) {
|
||||
LOG.error(message);
|
||||
}
|
||||
else {
|
||||
LOG.warn(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
@@ -265,6 +265,27 @@ public abstract class DumbService {
|
||||
*/
|
||||
public abstract boolean isAlternativeResolveEnabled();
|
||||
|
||||
/**
|
||||
* By default, dumb mode tasks (including indexing) are allowed in non-modal state only. The reason is that
|
||||
* when some code shows a dialog, it probably does't expect that after the dialog is closed the dumb mode will be on.
|
||||
* Therefore any dumb mode started within a dialog is considered a mistake, performed under modal progress and reported as an exception.<p/>
|
||||
*
|
||||
* If the dialog (e.g. Project Structure) starting background dumb mode is an expected situation, the dumb mode should be started inside the runnable
|
||||
* passed to this method. This will suppress the exception and allow either modal or background indexing. Note that this will only affect the invocation time
|
||||
* modality state, so showing other dialogs from within the runnable and starting dumb mode from them would still result in an assertion failure.
|
||||
*/
|
||||
public abstract void allowStartingDumbModeInside(@NotNull DumbModePermission permission, @NotNull Runnable runnable);
|
||||
|
||||
/**
|
||||
* Permits the dumb mode to start at a specific moment, either modally or in background.
|
||||
* @see #allowStartingDumbModeInside(DumbModePermission, Runnable)
|
||||
*/
|
||||
public enum DumbModePermission {
|
||||
MAY_START_MODAL,
|
||||
MAY_START_BACKGROUND
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see #DUMB_MODE
|
||||
*/
|
||||
|
||||
@@ -1044,4 +1044,29 @@ public class PsiTreeUtil {
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static <T extends PsiElement> Iterator<T> childIterator(@NotNull final PsiElement element, @NotNull final Class<T> aClass) {
|
||||
return new Iterator<T>() {
|
||||
private T next = getChildOfType(element, aClass);
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return next != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
if (next == null) throw new NoSuchElementException();
|
||||
T current = this.next;
|
||||
next = getNextSiblingOfType(current, aClass);
|
||||
return current;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,6 +90,11 @@ public class MockDumbService extends DumbService {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void allowStartingDumbModeInside(@NotNull DumbModePermission permission, @NotNull Runnable runnable) {
|
||||
runnable.run();
|
||||
}
|
||||
|
||||
public void smartInvokeLater(@NotNull final Runnable runnable) {
|
||||
runnable.run();
|
||||
}
|
||||
|
||||
@@ -19,8 +19,11 @@ package com.intellij.psi;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.NullableComputable;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -34,6 +37,7 @@ import com.intellij.psi.stubs.StubElement;
|
||||
import com.intellij.psi.stubs.StubTree;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.IStubFileElementType;
|
||||
import com.intellij.psi.util.PsiModificationTracker;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -436,7 +440,8 @@ public abstract class PsiAnchor {
|
||||
private final int myIndex;
|
||||
private final Language myLanguage;
|
||||
private final IStubElementType myElementType;
|
||||
private final int myCreationModCount;
|
||||
private final short myCreationModCount;
|
||||
private final short myCreationStamp;
|
||||
|
||||
private StubIndexReference(@NotNull final PsiFile file, final int index, @NotNull Language language, IStubElementType elementType) {
|
||||
myLanguage = language;
|
||||
@@ -444,7 +449,16 @@ public abstract class PsiAnchor {
|
||||
myVirtualFile = file.getVirtualFile();
|
||||
myProject = file.getProject();
|
||||
myIndex = index;
|
||||
myCreationModCount = (int)file.getManager().getModificationTracker().getModificationCount();
|
||||
myCreationModCount = getModCount();
|
||||
myCreationStamp = (short)file.getModificationStamp();
|
||||
}
|
||||
|
||||
private short getModCount() {
|
||||
final PsiModificationTracker tracker = PsiManager.getInstance(getProject()).getModificationTracker();
|
||||
if (myVirtualFile.getName().endsWith(".java")) {
|
||||
return (short)tracker.getJavaStructureModificationCount();
|
||||
}
|
||||
return (short)tracker.getModificationCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -474,19 +488,35 @@ public abstract class PsiAnchor {
|
||||
}
|
||||
|
||||
public String diagnoseNull() {
|
||||
final PsiFile file = ApplicationManager.getApplication().runReadAction(new Computable<PsiFile>() {
|
||||
@Override
|
||||
public PsiFile compute() {
|
||||
return getFile();
|
||||
}
|
||||
});
|
||||
try {
|
||||
PsiElement element = ApplicationManager.getApplication().runReadAction(new NullableComputable<PsiElement>() {
|
||||
@Override
|
||||
public PsiElement compute() {
|
||||
return restoreFromStubIndex((PsiFileWithStubSupport)getFile(), myIndex, myElementType, true);
|
||||
return restoreFromStubIndex((PsiFileWithStubSupport)file, myIndex, myElementType, true);
|
||||
}
|
||||
});
|
||||
return "No diagnostics, element=" + element + "@" + (element == null ? 0 : System.identityHashCode(element));
|
||||
}
|
||||
catch (AssertionError e) {
|
||||
return e.getMessage() +
|
||||
"; current modCount=" + PsiManager.getInstance(getProject()).getModificationTracker().getModificationCount() +
|
||||
"; creation modCount=" + myCreationModCount;
|
||||
String msg = e.getMessage();
|
||||
msg += "\n current (java)modCount=" + getModCount() + "; creation (java)modCount=" + myCreationModCount;
|
||||
if (file == null) {
|
||||
msg += "\n no PSI file";
|
||||
} else {
|
||||
msg += "\n current file stamp=" + (short)file.getModificationStamp() + "; creation file stamp=" + myCreationStamp;
|
||||
}
|
||||
final Document document = FileDocumentManager.getInstance().getCachedDocument(myVirtualFile);
|
||||
if (document != null) {
|
||||
msg += "\n committed=" + PsiDocumentManager.getInstance(myProject).isCommitted(document);
|
||||
msg += "\n saved=" + !FileDocumentManager.getInstance().isDocumentUnsaved(document);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import.title=Import {0} Projects
|
||||
module.type.title={0} Module
|
||||
module.type.description={0} modules are used for developing <b>JVM-based</b> applications with dependencies managed by <b>{0}</b>
|
||||
orphan.modules.text=<html>The modules below are not backed by {0} anymore.<br/>Check those to be removed from the ide project too:
|
||||
orphan.modules.text=<html>The modules below are not imported from {0} anymore.<br/>Check those to be removed from the ide project too:
|
||||
|
||||
# Settings.
|
||||
setting.type.location.deduced={0} location is deduced
|
||||
|
||||
+4
-11
@@ -21,7 +21,7 @@ import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
|
||||
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.ui.ExternalProjectStructureDialog;
|
||||
import com.intellij.openapi.externalSystem.service.ui.ExternalProjectDataSelectorDialog;
|
||||
import com.intellij.openapi.externalSystem.view.ExternalSystemNode;
|
||||
import com.intellij.openapi.externalSystem.view.ProjectNode;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -33,14 +33,7 @@ import java.util.List;
|
||||
* @author Vladislav.Soroka
|
||||
* @since 5/12/2015
|
||||
*/
|
||||
public class ExternalSystemOpenProjectStructureAction extends ExternalSystemAction {
|
||||
|
||||
public ExternalSystemOpenProjectStructureAction() {
|
||||
//super(AbstractExternalEntityData.class);
|
||||
//getTemplatePresentation().setText(ExternalSystemBundle.message("action.detach.external.project.text", "external"));
|
||||
//getTemplatePresentation().setDescription(ExternalSystemBundle.message("action.detach.external.project.description"));
|
||||
//getTemplatePresentation().setIcon(SystemInfoRt.isMac ? AllIcons.ToolbarDecorator.Mac.Remove : AllIcons.ToolbarDecorator.Remove);
|
||||
}
|
||||
public class ExternalSystemSelectProjectDataToImportAction extends ExternalSystemAction {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
@@ -65,9 +58,9 @@ public class ExternalSystemOpenProjectStructureAction extends ExternalSystemActi
|
||||
ProjectDataManager.getInstance().getExternalProjectData(project, projectSystemId, projectData.getLinkedExternalProjectPath());
|
||||
}
|
||||
|
||||
final ExternalProjectStructureDialog dialog;
|
||||
final ExternalProjectDataSelectorDialog dialog;
|
||||
if (projectInfo != null) {
|
||||
dialog = new ExternalProjectStructureDialog(project, projectInfo, externalSystemNode != null ? externalSystemNode.getData() : null);
|
||||
dialog = new ExternalProjectDataSelectorDialog(project, projectInfo, externalSystemNode != null ? externalSystemNode.getData() : null);
|
||||
dialog.showAndGet();
|
||||
}
|
||||
}
|
||||
+5
@@ -356,6 +356,11 @@ public class ModuleDataService extends AbstractProjectDataService<ModuleData, Mo
|
||||
protected JComponent createCenterPanel() {
|
||||
return new JBScrollPane(content);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected Action[] createActions() {
|
||||
return new Action[]{getOKAction()};
|
||||
}
|
||||
};
|
||||
|
||||
dialog.showAndGet();
|
||||
|
||||
+2
-2
@@ -18,7 +18,7 @@ import com.intellij.openapi.externalSystem.service.project.PlatformFacadeImpl;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.settings.AbstractImportFromExternalSystemControl;
|
||||
import com.intellij.openapi.externalSystem.service.ui.ExternalProjectStructureDialog;
|
||||
import com.intellij.openapi.externalSystem.service.ui.ExternalProjectDataSelectorDialog;
|
||||
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings;
|
||||
import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
|
||||
import com.intellij.openapi.externalSystem.util.DisposeAwareProjectChange;
|
||||
@@ -158,7 +158,7 @@ public abstract class AbstractExternalProjectImportBuilder<C extends AbstractImp
|
||||
systemSettings.setLinkedProjectsSettings(projects);
|
||||
|
||||
if (externalProjectNode != null) {
|
||||
ExternalProjectStructureDialog dialog = new ExternalProjectStructureDialog(
|
||||
ExternalProjectDataSelectorDialog dialog = new ExternalProjectDataSelectorDialog(
|
||||
project, new InternalExternalProjectInfo(myExternalSystemId, projectSettings.getExternalProjectPath(), externalProjectNode));
|
||||
dialog.showAndGet();
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.openapi.externalSystem.service.ui.ExternalProjectStructureDialog">
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.openapi.externalSystem.service.ui.ExternalProjectDataSelectorDialog">
|
||||
<grid id="cbd77" binding="mainPanel" layout-manager="BorderLayout" hgap="5" vgap="5">
|
||||
<constraints>
|
||||
<xy x="48" y="54" width="793" height="309"/>
|
||||
+18
-14
@@ -33,7 +33,7 @@ import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataMan
|
||||
import com.intellij.openapi.externalSystem.util.DisposeAwareProjectChange;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemUiUtil;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
@@ -69,7 +69,7 @@ import java.util.Set;
|
||||
* @author Vladislav.Soroka
|
||||
* @since 5/12/2015
|
||||
*/
|
||||
public class ExternalProjectStructureDialog extends DialogWrapper {
|
||||
public class ExternalProjectDataSelectorDialog extends DialogWrapper {
|
||||
|
||||
private static final int MAX_PATH_LENGTH = 50;
|
||||
private static final Set<? extends Key<?>> DATA_KEYS = ContainerUtil.set(ProjectKeys.PROJECT, ProjectKeys.MODULE);
|
||||
@@ -107,14 +107,14 @@ public class ExternalProjectStructureDialog extends DialogWrapper {
|
||||
private boolean myShowSelectedRowsOnly;
|
||||
private int myModulesCount;
|
||||
|
||||
public ExternalProjectStructureDialog(@NotNull Project project,
|
||||
@NotNull ExternalProjectInfo projectInfo) {
|
||||
public ExternalProjectDataSelectorDialog(@NotNull Project project,
|
||||
@NotNull ExternalProjectInfo projectInfo) {
|
||||
this(project, projectInfo, null);
|
||||
}
|
||||
|
||||
public ExternalProjectStructureDialog(@NotNull Project project,
|
||||
@NotNull ExternalProjectInfo projectInfo,
|
||||
@Nullable Object preselectedNodeDataObject) {
|
||||
public ExternalProjectDataSelectorDialog(@NotNull Project project,
|
||||
@NotNull ExternalProjectInfo projectInfo,
|
||||
@Nullable Object preselectedNodeDataObject) {
|
||||
super(project, true);
|
||||
myProject = project;
|
||||
myIgnorableKeys = getIgnorableKeys();
|
||||
@@ -212,15 +212,19 @@ public class ExternalProjectStructureDialog extends DialogWrapper {
|
||||
ExternalSystemApiUtil.executeProjectChangeAction(true, new DisposeAwareProjectChange(myProject) {
|
||||
@Override
|
||||
public void execute() {
|
||||
ProjectRootManagerEx.getInstanceEx(myProject).mergeRootsChangesDuring(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ServiceManager.getService(ProjectDataManager.class).importData(projectStructure, myProject, true);
|
||||
}
|
||||
});
|
||||
DumbService.getInstance(myProject).allowStartingDumbModeInside(
|
||||
DumbService.DumbModePermission.MAY_START_BACKGROUND, new Runnable() {
|
||||
public void run() {
|
||||
ProjectRootManagerEx.getInstanceEx(myProject).mergeRootsChangesDuring(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ServiceManager.getService(ProjectDataManager.class).importData(projectStructure, myProject, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
//ExternalSystemUtil.scheduleExternalViewStructureUpdate(myProject, myProjectInfo.getProjectSystemId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,12 +20,12 @@ import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.psi.Weigher;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* For completion FAQ, see {@link CompletionContributor}.
|
||||
@@ -103,11 +103,9 @@ public abstract class CompletionService {
|
||||
* The main method that is invoked to collect all the completion variants
|
||||
* @param parameters Parameters specifying current completion environment
|
||||
* @param consumer This consumer will directly add lookup elements to the lookup
|
||||
* @return all suitable lookup elements
|
||||
*/
|
||||
@NotNull
|
||||
public LookupElement[] performCompletion(final CompletionParameters parameters, final Consumer<CompletionResult> consumer) {
|
||||
final Collection<LookupElement> lookupSet = new LinkedHashSet<LookupElement>();
|
||||
public void performCompletion(final CompletionParameters parameters, final Consumer<CompletionResult> consumer) {
|
||||
final Set<LookupElement> lookupSet = ContainerUtil.newConcurrentSet();
|
||||
|
||||
getVariantsFromContributors(parameters, null, new Consumer<CompletionResult>() {
|
||||
@Override
|
||||
@@ -117,7 +115,6 @@ public abstract class CompletionService {
|
||||
}
|
||||
}
|
||||
});
|
||||
return lookupSet.toArray(new LookupElement[lookupSet.size()]);
|
||||
}
|
||||
|
||||
public abstract CompletionSorter defaultSorter(CompletionParameters parameters, PrefixMatcher matcher);
|
||||
|
||||
+7
-2
@@ -609,6 +609,7 @@ public class CodeCompletionHandlerBase {
|
||||
final Editor hostEditor = InjectedLanguageUtil.getTopLevelEditor(editor);
|
||||
final PsiFile originalFile = indicator.getParameters().getOriginalFile();
|
||||
final PsiFile hostFile = InjectedLanguageUtil.getTopLevelFile(originalFile);
|
||||
assert hostFile != null;
|
||||
final OffsetMap hostMap = translateOffsetMapToHost(originalFile, hostFile, hostEditor, indicator.getOffsetMap());
|
||||
hostEditor.getCaretModel().runForEachCaret(new CaretAction() {
|
||||
@Override
|
||||
@@ -618,9 +619,13 @@ public class CodeCompletionHandlerBase {
|
||||
Editor targetEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(hostEditor, targetFile);
|
||||
int targetCaretOffset = targetEditor.getCaretModel().getOffset();
|
||||
OffsetMap injectedMap = translateOffsetMapToInjected(hostMap, targetEditor.getDocument());
|
||||
int idEnd = targetCaretOffset + idEndOffsetDelta;
|
||||
if (idEnd > targetEditor.getDocument().getTextLength()) {
|
||||
idEnd = targetCaretOffset; // no replacement by Tab when offsets gone wrong for some reason
|
||||
}
|
||||
CompletionAssertions.WatchingInsertionContext currentContext = insertItem(indicator, item, completionChar, items, update,
|
||||
targetEditor, targetFile == null ? hostFile : targetFile,
|
||||
targetCaretOffset, targetCaretOffset + idEndOffsetDelta,
|
||||
targetCaretOffset, idEnd,
|
||||
injectedMap);
|
||||
contexts.add(currentContext);
|
||||
}
|
||||
@@ -691,7 +696,7 @@ public class CodeCompletionHandlerBase {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (caretOffset != idEndOffset && completionChar == Lookup.REPLACE_SELECT_CHAR) {
|
||||
if (caretOffset < idEndOffset && completionChar == Lookup.REPLACE_SELECT_CHAR) {
|
||||
editor.getDocument().deleteString(caretOffset, idEndOffset);
|
||||
}
|
||||
|
||||
|
||||
+15
-6
@@ -40,6 +40,7 @@ import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Caret;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
@@ -56,6 +57,7 @@ import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.ReferenceRange;
|
||||
@@ -130,7 +132,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
|
||||
private volatile boolean myHasPsiElements;
|
||||
private boolean myLookupUpdated;
|
||||
private final ConcurrentMap<LookupElement, CompletionSorterImpl> myItemSorters =
|
||||
ContainerUtil.newConcurrentMap(ContainerUtil.<LookupElement>identityStrategy());
|
||||
ContainerUtil.createConcurrentWeakMap(ContainerUtil.<LookupElement>identityStrategy());
|
||||
private final PropertyChangeListener myLookupManagerListener;
|
||||
private final Queue<Runnable> myAdvertiserChanges = new ConcurrentLinkedQueue<Runnable>();
|
||||
private final List<CompletionResult> myDelayedMiddleMatches = ContainerUtil.newArrayList();
|
||||
@@ -229,7 +231,16 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
|
||||
final int selectionEndOffset = initContext.getSelectionEndOffset();
|
||||
final PsiReference reference = TargetElementUtil.findReference(myEditor, selectionEndOffset);
|
||||
if (reference != null) {
|
||||
initContext.setReplacementOffset(findReplacementOffset(selectionEndOffset, reference));
|
||||
final int replacementOffset = findReplacementOffset(selectionEndOffset, reference);
|
||||
final Document document = initContext.getEditor().getDocument();
|
||||
if (replacementOffset > document.getTextLength()) {
|
||||
LOG.error("Invalid replacementOffset: " + replacementOffset + " returned by reference " + reference + " of " + reference.getClass() +
|
||||
"; doc=" + document +
|
||||
"; doc actual=" + (document == initContext.getFile().getViewProvider().getDocument()) +
|
||||
"; doc committed=" + PsiDocumentManager.getInstance(getProject()).isCommitted(document));
|
||||
} else {
|
||||
initContext.setReplacementOffset(replacementOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IndexNotReadyException ignored) {
|
||||
@@ -818,17 +829,15 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
|
||||
strategy.startThread(this, new CalculateItems());
|
||||
}
|
||||
|
||||
private LookupElement[] calculateItems(CompletionInitializationContext initContext, WeighingDelegate weigher) {
|
||||
private void calculateItems(CompletionInitializationContext initContext, WeighingDelegate weigher) {
|
||||
duringCompletion(initContext);
|
||||
ProgressManager.checkCanceled();
|
||||
|
||||
LookupElement[] result = CompletionService.getCompletionService().performCompletion(myParameters, weigher);
|
||||
CompletionService.getCompletionService().performCompletion(myParameters, weigher);
|
||||
ProgressManager.checkCanceled();
|
||||
|
||||
weigher.waitFor();
|
||||
ProgressManager.checkCanceled();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void addAdvertisement(@NotNull final String text, @Nullable final Color bgColor) {
|
||||
|
||||
+2
-2
@@ -20,9 +20,9 @@ import com.intellij.codeInsight.navigation.ListBackgroundUpdaterTask;
|
||||
import com.intellij.find.FindUtil;
|
||||
import com.intellij.ide.PsiCopyPasteManager;
|
||||
import com.intellij.ide.util.PsiElementListCellRenderer;
|
||||
import com.intellij.ide.util.gotoByName.ChooseByNameBase;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ex.util.EditorUtil;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.ui.popup.JBPopup;
|
||||
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
|
||||
@@ -128,7 +128,7 @@ public class PsiElementListNavigator {
|
||||
});
|
||||
|
||||
list.setCellRenderer(listRenderer);
|
||||
list.setFont(ChooseByNameBase.getEditorFont());
|
||||
list.setFont(EditorUtil.getEditorFont());
|
||||
|
||||
final PopupChooserBuilder builder = new PopupChooserBuilder(list);
|
||||
if (listRenderer instanceof PsiElementListCellRenderer) {
|
||||
|
||||
+12
-13
@@ -36,14 +36,15 @@ import com.intellij.ui.components.JBList;
|
||||
import com.intellij.ui.speedSearch.SpeedSearchUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.FList;
|
||||
import com.intellij.util.ui.*;
|
||||
import com.intellij.util.ui.EmptyIcon;
|
||||
import com.intellij.util.ui.GraphicsUtil;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -483,18 +484,16 @@ public class LookupCellRenderer implements ListCellRenderer {
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g){
|
||||
super.paint(g);
|
||||
if (!myLookup.isFocused() && myLookup.isCompletion()) {
|
||||
((Graphics2D)g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.6f));
|
||||
|
||||
// sub-pixel antialiasing does not work with alpha composite, so we workaround this by painting to RGB image first
|
||||
BufferedImage image = UIUtil.createImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D imageGraphics = image.createGraphics();
|
||||
super.paint(imageGraphics);
|
||||
imageGraphics.dispose();
|
||||
UIUtil.drawImage(g, image, 0, 0, null);
|
||||
}
|
||||
else {
|
||||
super.paint(g);
|
||||
g = g.create();
|
||||
try {
|
||||
g.setColor(ColorUtil.withAlpha(BACKGROUND_COLOR, .4));
|
||||
g.fillRect(0, 0, getWidth(), getHeight());
|
||||
}
|
||||
finally {
|
||||
g.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable,
|
||||
private volatile LookupArranger myArranger;
|
||||
private LookupArranger myPresentableArranger;
|
||||
private final Map<LookupElement, PrefixMatcher> myMatchers =
|
||||
ContainerUtil.newConcurrentMap(ContainerUtil.<LookupElement>identityStrategy());
|
||||
ContainerUtil.createConcurrentWeakMap(ContainerUtil.<LookupElement>identityStrategy());
|
||||
private final Map<LookupElement, Font> myCustomFonts = ContainerUtil.createConcurrentWeakMap(10, 0.75f, Runtime.getRuntime().availableProcessors(),
|
||||
ContainerUtil.<LookupElement>identityStrategy());
|
||||
private boolean myStartCompletionWhenNothingMatches;
|
||||
@@ -536,7 +536,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable,
|
||||
public void perform(Caret caret) {
|
||||
EditorModificationUtil.deleteSelectedText(hostEditor);
|
||||
final int caretOffset = hostEditor.getCaretModel().getOffset();
|
||||
int lookupStart = Math.max(caretOffset - prefix, 0);
|
||||
int lookupStart = Math.min(caretOffset, Math.max(caretOffset - prefix, 0));
|
||||
|
||||
int len = hostEditor.getDocument().getTextLength();
|
||||
LOG.assertTrue(lookupStart >= 0 && lookupStart <= len,
|
||||
|
||||
@@ -35,6 +35,7 @@ import com.intellij.openapi.actionSystem.impl.ActionButton;
|
||||
import com.intellij.openapi.actionSystem.impl.PresentationFactory;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.components.AbstractProjectComponent;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.EditorFactory;
|
||||
@@ -102,6 +103,7 @@ import java.util.EventObject;
|
||||
import java.util.List;
|
||||
|
||||
public class CtrlMouseHandler extends AbstractProjectComponent {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.navigation.CtrlMouseHandler");
|
||||
private static final AbstractDocumentationTooltipAction[] ourTooltipActions = {new ShowQuickDocAtPinnedWindowFromTooltipAction()};
|
||||
private final EditorColorsManager myEditorColorsManager;
|
||||
|
||||
@@ -382,8 +384,19 @@ public class CtrlMouseHandler extends AbstractProjectComponent {
|
||||
}
|
||||
|
||||
public Info(@NotNull PsiElement elementAtPointer) {
|
||||
this(elementAtPointer, Collections.singletonList(new TextRange(elementAtPointer.getTextOffset(),
|
||||
elementAtPointer.getTextOffset() + elementAtPointer.getTextLength())));
|
||||
this(elementAtPointer, Collections.singletonList(getReferenceRange(elementAtPointer)));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static TextRange getReferenceRange(@NotNull PsiElement elementAtPointer) {
|
||||
int textOffset = elementAtPointer.getTextOffset();
|
||||
final TextRange range = elementAtPointer.getTextRange();
|
||||
if (textOffset < range.getStartOffset() || textOffset < 0) {
|
||||
LOG.error("Invalid text offset " + textOffset + " of element " + elementAtPointer + " of " + elementAtPointer.getClass());
|
||||
textOffset = range.getStartOffset();
|
||||
}
|
||||
|
||||
return new TextRange(textOffset, range.getEndOffset());
|
||||
}
|
||||
|
||||
boolean isSimilarTo(@NotNull Info that) {
|
||||
|
||||
@@ -22,11 +22,11 @@ import com.intellij.featureStatistics.FeatureUsageTracker;
|
||||
import com.intellij.find.FindUtil;
|
||||
import com.intellij.ide.util.EditSourceUtil;
|
||||
import com.intellij.ide.util.PsiElementListCellRenderer;
|
||||
import com.intellij.ide.util.gotoByName.ChooseByNameBase;
|
||||
import com.intellij.navigation.ItemPresentation;
|
||||
import com.intellij.navigation.NavigationItem;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ex.util.EditorUtil;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
@@ -130,7 +130,7 @@ public abstract class GotoTargetHandler implements CodeInsightActionHandler {
|
||||
}
|
||||
};
|
||||
|
||||
list.setFont(ChooseByNameBase.getEditorFont());
|
||||
list.setFont(EditorUtil.getEditorFont());
|
||||
|
||||
list.setCellRenderer(new DefaultListCellRenderer() {
|
||||
@Override
|
||||
|
||||
@@ -19,7 +19,6 @@ package com.intellij.codeInsight.navigation;
|
||||
import com.intellij.ide.util.DefaultPsiElementCellRenderer;
|
||||
import com.intellij.ide.util.EditSourceUtil;
|
||||
import com.intellij.ide.util.PsiElementListCellRenderer;
|
||||
import com.intellij.ide.util.gotoByName.ChooseByNameBase;
|
||||
import com.intellij.navigation.GotoRelatedItem;
|
||||
import com.intellij.navigation.GotoRelatedProvider;
|
||||
import com.intellij.navigation.NavigationItem;
|
||||
@@ -27,6 +26,7 @@ import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ex.MarkupModelEx;
|
||||
import com.intellij.openapi.editor.ex.RangeHighlighterEx;
|
||||
import com.intellij.openapi.editor.ex.util.EditorUtil;
|
||||
import com.intellij.openapi.editor.impl.DocumentMarkupModel;
|
||||
import com.intellij.openapi.editor.markup.HighlighterTargetArea;
|
||||
import com.intellij.openapi.editor.markup.MarkupModel;
|
||||
@@ -116,7 +116,7 @@ public final class NavigationUtil {
|
||||
};
|
||||
list.setCellRenderer(renderer);
|
||||
|
||||
list.setFont(ChooseByNameBase.getEditorFont());
|
||||
list.setFont(EditorUtil.getEditorFont());
|
||||
|
||||
if (selection != null) {
|
||||
list.setSelectedValue(selection, true);
|
||||
|
||||
@@ -26,7 +26,6 @@ import com.intellij.ide.IdeEventQueue;
|
||||
import com.intellij.ide.actions.CopyReferenceAction;
|
||||
import com.intellij.ide.actions.GotoFileAction;
|
||||
import com.intellij.ide.actions.WindowAction;
|
||||
import com.intellij.ide.ui.UISettings;
|
||||
import com.intellij.ide.ui.laf.darcula.ui.DarculaTextBorder;
|
||||
import com.intellij.ide.ui.laf.darcula.ui.DarculaTextFieldUI;
|
||||
import com.intellij.openapi.Disposable;
|
||||
@@ -35,8 +34,7 @@ import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.editor.ex.util.EditorUtil;
|
||||
import com.intellij.openapi.fileTypes.UnknownFileType;
|
||||
import com.intellij.openapi.fileTypes.ex.FileTypeManagerEx;
|
||||
import com.intellij.openapi.keymap.Keymap;
|
||||
@@ -490,7 +488,7 @@ public abstract class ChooseByNameBase {
|
||||
myTextField.setActionMap(actionMap);
|
||||
|
||||
myTextFieldPanel.add(myTextField);
|
||||
Font editorFont = getEditorFont();
|
||||
Font editorFont = EditorUtil.getEditorFont();
|
||||
myTextField.setFont(editorFont);
|
||||
|
||||
if (checkBoxName != null) {
|
||||
@@ -1824,11 +1822,4 @@ public abstract class ChooseByNameBase {
|
||||
public JTextField getTextField() {
|
||||
return myTextField;
|
||||
}
|
||||
|
||||
public static Font getEditorFont() {
|
||||
EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme();
|
||||
int size = UISettings.getInstance().PRESENTATION_MODE
|
||||
? UISettings.getInstance().PRESENTATION_MODE_FONT_SIZE - 4 : scheme.getEditorFontSize();
|
||||
return new Font(scheme.getEditorFontName(), Font.PLAIN, size);
|
||||
}
|
||||
}
|
||||
|
||||
+6
-2
@@ -277,7 +277,9 @@ public class FileTypeConfigurable extends BaseConfigurable implements Searchable
|
||||
FileTypesBundle.message("filetype.edit.add.pattern.reassign.button"),
|
||||
CommonBundle.getCancelButtonText(), Messages.getQuestionIcon())) {
|
||||
myTempPatternsTable.removeAssociation(matcher, registeredFileType);
|
||||
myTempTemplateDataLanguages.removeAssociation(matcher, oldLanguage);
|
||||
if (oldLanguage != null) {
|
||||
myTempTemplateDataLanguages.removeAssociation(matcher, oldLanguage);
|
||||
}
|
||||
myReassigned.put(matcher, registeredFileType);
|
||||
}
|
||||
else {
|
||||
@@ -289,7 +291,9 @@ public class FileTypeConfigurable extends BaseConfigurable implements Searchable
|
||||
if (item != null) {
|
||||
final FileNameMatcher oldMatcher = FileTypeManager.parseFromString(item);
|
||||
myTempPatternsTable.removeAssociation(oldMatcher, type);
|
||||
myTempTemplateDataLanguages.removeAssociation(oldMatcher, oldLanguage);
|
||||
if (oldLanguage != null) {
|
||||
myTempTemplateDataLanguages.removeAssociation(oldMatcher, oldLanguage);
|
||||
}
|
||||
}
|
||||
myTempPatternsTable.addAssociation(matcher, type);
|
||||
myTempTemplateDataLanguages.addAssociation(matcher, dialog.getTemplateDataLanguage());
|
||||
|
||||
@@ -17,10 +17,12 @@ package com.intellij.openapi.editor.ex.util;
|
||||
|
||||
import com.intellij.diagnostic.Dumpable;
|
||||
import com.intellij.diagnostic.LogMessageEx;
|
||||
import com.intellij.ide.ui.UISettings;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.application.WriteAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.*;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.impl.ComplementaryFontsRegistry;
|
||||
@@ -899,6 +901,13 @@ public final class EditorUtil {
|
||||
}
|
||||
editor.getSelectionModel().setSelection(startOffset, endOffset);
|
||||
}
|
||||
|
||||
public static Font getEditorFont() {
|
||||
EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme();
|
||||
int size = UISettings.getInstance().PRESENTATION_MODE
|
||||
? UISettings.getInstance().PRESENTATION_MODE_FONT_SIZE - 4 : scheme.getEditorFontSize();
|
||||
return new Font(scheme.getEditorFontName(), Font.PLAIN, size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -299,7 +299,7 @@ public class AbstractProgressIndicatorExBase extends AbstractProgressIndicatorBa
|
||||
}
|
||||
}
|
||||
|
||||
private void delegateProgressChange(@NotNull IndicatorAction action) {
|
||||
protected void delegateProgressChange(@NotNull IndicatorAction action) {
|
||||
delegate(action);
|
||||
onProgressChange();
|
||||
}
|
||||
|
||||
@@ -16,11 +16,9 @@
|
||||
package com.intellij.openapi.project;
|
||||
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.ide.startup.StartupManagerEx;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.application.*;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
|
||||
import com.intellij.openapi.progress.*;
|
||||
@@ -63,6 +61,7 @@ public class DumbServiceImpl extends DumbService implements Disposable, Modifica
|
||||
private final Queue<Runnable> myRunWhenSmartQueue = new Queue<Runnable>(5);
|
||||
private final Project myProject;
|
||||
private final ThreadLocal<Integer> myAlternativeResolution = new ThreadLocal<Integer>();
|
||||
private final Map<ModalityState, DumbModePermission> myPermissions = ContainerUtil.newHashMap();
|
||||
|
||||
public DumbServiceImpl(Project project) {
|
||||
myProject = project;
|
||||
@@ -109,6 +108,23 @@ public class DumbServiceImpl extends DumbService implements Disposable, Modifica
|
||||
return myAlternativeResolution.get() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void allowStartingDumbModeInside(@NotNull DumbModePermission permission, @NotNull Runnable runnable) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
ModalityState modality = ModalityState.current();
|
||||
DumbModePermission prev = myPermissions.put(modality, permission);
|
||||
try {
|
||||
runnable.run();
|
||||
}
|
||||
finally {
|
||||
if (prev == null) {
|
||||
myPermissions.remove(modality);
|
||||
} else {
|
||||
myPermissions.put(modality, prev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlternativeResolveEnabled(boolean enabled) {
|
||||
Integer oldValue = myAlternativeResolution.get();
|
||||
@@ -151,7 +167,8 @@ public class DumbServiceImpl extends DumbService implements Disposable, Modifica
|
||||
}
|
||||
|
||||
private void scheduleCacheUpdate(@NotNull final DumbModeTask task, boolean forceDumbMode) {
|
||||
if (LOG.isDebugEnabled()) LOG.debug("Scheduling task " + task, new Throwable());
|
||||
final Throwable trace = new Throwable();
|
||||
if (LOG.isDebugEnabled()) LOG.debug("Scheduling task " + task, trace);
|
||||
final Application application = ApplicationManager.getApplication();
|
||||
|
||||
if (application.isUnitTestMode() ||
|
||||
@@ -181,13 +198,14 @@ public class DumbServiceImpl extends DumbService implements Disposable, Modifica
|
||||
if (myProject.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
final ProgressIndicatorBase indicator = new ProgressIndicatorBase() {
|
||||
@Override
|
||||
protected void delegateRunningChange(@NotNull AbstractProgressIndicatorExBase.IndicatorAction action) {
|
||||
// don't delegate lifecycle events to the global indicator as several independent tasks may run under it sequentially
|
||||
}
|
||||
};
|
||||
myProgresses.put(task, indicator);
|
||||
|
||||
ModalityState modality = ModalityState.current();
|
||||
final DumbModePermission permission = getDumbModePermission(modality);
|
||||
if (permission == null) {
|
||||
LOG.error("Dumb mode not permitted in modal envirnonment; please use DumbService.allowStartingDumbModeInside in your dialog or invokeLater(..., NON_MODAL)", trace);
|
||||
}
|
||||
|
||||
myProgresses.put(task, new ProgressIndicatorBase());
|
||||
Disposer.register(task, new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
@@ -200,37 +218,60 @@ public class DumbServiceImpl extends DumbService implements Disposable, Modifica
|
||||
if (!myDumb) {
|
||||
// always change dumb status inside write action.
|
||||
// This will ensure all active read actions are completed before the app goes dumb
|
||||
boolean startSuccess =
|
||||
application.runWriteAction(new Computable<Boolean>() {
|
||||
@Override
|
||||
public Boolean compute() {
|
||||
myDumb = true;
|
||||
myModificationCount++;
|
||||
try {
|
||||
myPublisher.enteredDumbMode();
|
||||
}
|
||||
catch (Throwable e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
|
||||
try {
|
||||
startBackgroundProcess();
|
||||
}
|
||||
catch (Throwable e) {
|
||||
LOG.error("Failed to start background index update task", e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
application.runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myDumb = true;
|
||||
myModificationCount++;
|
||||
try {
|
||||
myPublisher.enteredDumbMode();
|
||||
}
|
||||
});
|
||||
if (!startSuccess) {
|
||||
updateFinished();
|
||||
}
|
||||
catch (Throwable e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// later because we're likely in a write action and can't start a modal progress immediately
|
||||
// and for a background progress, it doesn't matter if it starts several milliseconds later; dumb mode is already on
|
||||
application.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
boolean modal = permission != DumbModePermission.MAY_START_BACKGROUND;
|
||||
boolean shouldFinish = modal;
|
||||
try {
|
||||
startBackgroundProcess(modal);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
shouldFinish = true;
|
||||
LOG.error("Failed to start background index update task", e);
|
||||
}
|
||||
finally {
|
||||
if (shouldFinish) {
|
||||
updateFinished();
|
||||
}
|
||||
}
|
||||
}
|
||||
}, modality, myProject.getDisposed());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private DumbModePermission getDumbModePermission(ModalityState modality) {
|
||||
DumbModePermission permission = myPermissions.get(modality);
|
||||
if (permission != null) {
|
||||
return permission;
|
||||
}
|
||||
|
||||
if (modality == ModalityState.NON_MODAL || !StartupManagerEx.getInstanceEx(myProject).postStartupActivityPassed()) {
|
||||
return DumbModePermission.MAY_START_BACKGROUND;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void updateFinished() {
|
||||
myDumb = false;
|
||||
myModificationCount++;
|
||||
@@ -349,7 +390,7 @@ public class DumbServiceImpl extends DumbService implements Disposable, Modifica
|
||||
}, modalityState, myProject.getDisposed());
|
||||
}
|
||||
|
||||
private void startBackgroundProcess() {
|
||||
private void startBackgroundProcess(final boolean modal) {
|
||||
ProgressManager.getInstance().run(new Task.Backgroundable(myProject, IdeBundle.message("progress.indexing"), false) {
|
||||
|
||||
@Override
|
||||
@@ -372,7 +413,13 @@ public class DumbServiceImpl extends DumbService implements Disposable, Modifica
|
||||
task = pair.first;
|
||||
ProgressIndicatorEx taskIndicator = pair.second;
|
||||
if (visibleIndicator instanceof ProgressIndicatorEx) {
|
||||
taskIndicator.addStateDelegate((ProgressIndicatorEx)visibleIndicator);
|
||||
taskIndicator.addStateDelegate(new AbstractProgressIndicatorExBase() {
|
||||
@Override
|
||||
protected void delegateProgressChange(@NotNull IndicatorAction action) {
|
||||
super.delegateProgressChange(action);
|
||||
action.execute((ProgressIndicatorEx)visibleIndicator);
|
||||
}
|
||||
});
|
||||
}
|
||||
runSingleTask(task, taskIndicator);
|
||||
}
|
||||
@@ -385,6 +432,15 @@ public class DumbServiceImpl extends DumbService implements Disposable, Modifica
|
||||
token.finish();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isConditionalModal() {
|
||||
return modal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldStartInBackground() {
|
||||
return !modal;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ title.edit.file.template=Edit File Template
|
||||
checkbox.reformat.according.to.style=Reformat according to style
|
||||
label.description=Description
|
||||
item.file.templates=File templates
|
||||
tab.filetemplates.templates=Templates
|
||||
tab.filetemplates.templates=Files
|
||||
tab.filetemplates.includes=Includes
|
||||
tab.filetemplates.code=Code
|
||||
tab.filetemplates.j2ee=Other
|
||||
|
||||
@@ -574,6 +574,7 @@
|
||||
<executor implementation="com.intellij.execution.executors.DefaultRunExecutor" order="first" id="run"/>
|
||||
<executionTargetProvider implementation="com.intellij.execution.DefaultExecutionTargetProvider"/>
|
||||
<projectService serviceImplementation="com.intellij.execution.RunConfigurationProducerService" />
|
||||
<configurationType implementation="com.intellij.execution.compound.CompoundRunConfigurationType"/>
|
||||
|
||||
<findUsagesHandlerFactory implementation="com.intellij.find.findUsages.DefaultFindUsagesHandlerFactory" id="default" order="last"/>
|
||||
<usageTargetProvider implementation="com.intellij.find.findUsages.DefaultUsageTargetProvider" id="default" order="last"/>
|
||||
|
||||
@@ -38,8 +38,8 @@
|
||||
text="Collapse All"
|
||||
icon="AllIcons.Actions.Collapseall"
|
||||
use-shortcut-of="CollapseAll"/>
|
||||
<action id="ExternalSystem.OpenProjectStructure" class="com.intellij.openapi.externalSystem.action.ExternalSystemOpenProjectStructureAction"
|
||||
text="Open Project Structure"
|
||||
<action id="ExternalSystem.SelectProjectDataToImport" class="com.intellij.openapi.externalSystem.action.ExternalSystemSelectProjectDataToImportAction"
|
||||
text="Select Project Data To import"
|
||||
icon="AllIcons.Modules.ModulesNode"/>
|
||||
|
||||
<action id="ExternalSystem.RunTask"
|
||||
@@ -132,7 +132,7 @@
|
||||
<separator/>
|
||||
<reference id="ExternalSystem.ExpandAll"/>
|
||||
<reference id="ExternalSystem.CollapseAll"/>
|
||||
<reference id="ExternalSystem.OpenProjectStructure"/>
|
||||
<reference id="ExternalSystem.SelectProjectDataToImport"/>
|
||||
</group>
|
||||
<group id="ExternalSystemView.ActionsToolbar.RightPanel">
|
||||
</group>
|
||||
|
||||
+1
-1
@@ -701,7 +701,7 @@ public abstract class ModuleManagerImpl extends ModuleManager implements Project
|
||||
@NotNull
|
||||
public Module newModule(@NotNull String filePath, @NotNull final String moduleTypeId, @Nullable final Map<String, String> options) {
|
||||
assertWritable();
|
||||
filePath = resolveShortWindowsName(filePath);
|
||||
filePath = FileUtil.toSystemIndependentName(resolveShortWindowsName(filePath));
|
||||
|
||||
ModuleEx module = getModuleByFilePath(filePath);
|
||||
if (module == null) {
|
||||
|
||||
+13
-11
@@ -362,18 +362,20 @@ public class UnnecessaryLocalVariableInspectionBase extends BaseInspection {
|
||||
return false;
|
||||
}
|
||||
boolean referenceFound = false;
|
||||
for (PsiResourceVariable resourceVariable : resourceList.getResourceVariables()) {
|
||||
final PsiExpression initializer = resourceVariable.getInitializer();
|
||||
if (!referenceFound && initializer instanceof PsiReferenceExpression) {
|
||||
final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)initializer;
|
||||
final PsiElement referent = referenceExpression.resolve();
|
||||
if (variable.equals(referent)) {
|
||||
referenceFound = true;
|
||||
continue;
|
||||
for (PsiResourceListElement resource : resourceList) {
|
||||
if (resource instanceof PsiResourceVariable) {
|
||||
final PsiExpression initializer = ((PsiResourceVariable)resource).getInitializer();
|
||||
if (!referenceFound && initializer instanceof PsiReferenceExpression) {
|
||||
final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)initializer;
|
||||
final PsiElement referent = referenceExpression.resolve();
|
||||
if (variable.equals(referent)) {
|
||||
referenceFound = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (VariableAccessUtils.variableIsUsed(variable, initializer)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (VariableAccessUtils.variableIsUsed(variable, initializer)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!referenceFound) {
|
||||
|
||||
+4
-9
@@ -77,6 +77,10 @@ public class EmptyFinallyBlockInspection extends BaseInspection {
|
||||
if (tryStatement == null) {
|
||||
return;
|
||||
}
|
||||
final PsiResourceList resources = tryStatement.getResourceList();
|
||||
if (resources != null) {
|
||||
return;
|
||||
}
|
||||
final PsiCodeBlock tryBlock = tryStatement.getTryBlock();
|
||||
if (tryBlock == null) {
|
||||
return;
|
||||
@@ -86,15 +90,6 @@ public class EmptyFinallyBlockInspection extends BaseInspection {
|
||||
return;
|
||||
}
|
||||
|
||||
final PsiResourceList resources = tryStatement.getResourceList();
|
||||
if (resources != null) {
|
||||
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
|
||||
for (PsiResourceVariable resource : resources.getResourceVariables()) {
|
||||
final PsiStatement statement = factory.createStatementFromText(resource.getText() + ";", parent);
|
||||
parent.addBefore(statement, tryStatement);
|
||||
}
|
||||
}
|
||||
|
||||
final PsiElement first = tryBlock.getFirstBodyElement();
|
||||
final PsiElement last = tryBlock.getLastBodyElement();
|
||||
if (first != null && last != null) {
|
||||
|
||||
+19
-7
@@ -17,6 +17,7 @@ package com.siyeh.ig.psiutils;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -206,16 +207,27 @@ public class EquivalenceChecker {
|
||||
if (resourceList1.getResourceVariablesCount() != resourceList2.getResourceVariablesCount()) {
|
||||
return false;
|
||||
}
|
||||
final List<PsiResourceVariable> resourceVariables1 = resourceList1.getResourceVariables();
|
||||
final List<PsiResourceVariable> resourceVariables2 = resourceList2.getResourceVariables();
|
||||
for (int i1 = 0, size = resourceVariables1.size(); i1 < size; i1++) {
|
||||
final PsiResourceVariable variable1 = resourceVariables1.get(i1);
|
||||
final PsiResourceVariable variable2 = resourceVariables2.get(i1);
|
||||
if (!localVariablesAreEquivalent(variable1, variable2)) {
|
||||
final List<PsiResourceListElement> resources1 = PsiTreeUtil.getChildrenOfTypeAsList(resourceList1, PsiResourceListElement.class);
|
||||
final List<PsiResourceListElement> resources2 = PsiTreeUtil.getChildrenOfTypeAsList(resourceList2, PsiResourceListElement.class);
|
||||
for (int i = 0, size = resources1.size(); i < size; i++) {
|
||||
final PsiResourceListElement resource1 = resources1.get(i);
|
||||
final PsiResourceListElement resource2 = resources2.get(i);
|
||||
if (resource1 instanceof PsiResourceVariable && resource2 instanceof PsiResourceVariable) {
|
||||
if (!localVariablesAreEquivalent((PsiLocalVariable)resource1, (PsiLocalVariable)resource2)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (resource1 instanceof PsiResourceExpression && resource2 instanceof PsiResourceExpression) {
|
||||
if (!expressionsAreEquivalent(((PsiResourceExpression)resource1).getExpression(), ((PsiResourceExpression)resource2).getExpression())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if (resourceList2 != null) {
|
||||
}
|
||||
else if (resourceList2 != null) {
|
||||
return false;
|
||||
}
|
||||
final PsiParameter[] catchParameters1 = statement1.getCatchBlockParameters();
|
||||
|
||||
+2
-2
@@ -47,8 +47,8 @@ public class ExceptionUtils {
|
||||
if (element == null) return out;
|
||||
if (element instanceof PsiResourceList) {
|
||||
final PsiResourceList resourceList = (PsiResourceList)element;
|
||||
for (PsiResourceVariable variable : resourceList.getResourceVariables()) {
|
||||
final PsiMethod method = PsiUtil.getResourceCloserMethod(variable);
|
||||
for (PsiResourceListElement resource : resourceList) {
|
||||
final PsiMethod method = PsiUtil.getResourceCloserMethod(resource);
|
||||
collectExceptionsThrown(method, out);
|
||||
}
|
||||
}
|
||||
|
||||
+6
-4
@@ -224,10 +224,12 @@ public class InitializationUtils {
|
||||
@NotNull Set<MethodSignature> checkedMethods, boolean strict) {
|
||||
final PsiResourceList resourceList = tryStatement.getResourceList();
|
||||
if (resourceList != null) {
|
||||
for (PsiResourceVariable resourceVariable : resourceList.getResourceVariables()) {
|
||||
final PsiExpression initializer = resourceVariable.getInitializer();
|
||||
if (expressionAssignsVariableOrFails(initializer, variable, checkedMethods, strict)) {
|
||||
return true;
|
||||
for (PsiResourceListElement resource : resourceList) {
|
||||
if (resource instanceof PsiResourceVariable) {
|
||||
final PsiExpression initializer = ((PsiResourceVariable)resource).getInitializer();
|
||||
if (expressionAssignsVariableOrFails(initializer, variable, checkedMethods, strict)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-6
@@ -22,7 +22,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class UninitializedReadCollector {
|
||||
@@ -222,11 +221,12 @@ public class UninitializedReadCollector {
|
||||
int stamp, @NotNull Set<MethodSignature> checkedMethods) {
|
||||
final PsiResourceList resourceList = tryStatement.getResourceList();
|
||||
if (resourceList != null) {
|
||||
final List<PsiResourceVariable> resourceVariables = resourceList.getResourceVariables();
|
||||
for (PsiResourceVariable resourceVariable : resourceVariables) {
|
||||
final PsiExpression initializer = resourceVariable.getInitializer();
|
||||
if (expressionAssignsVariable(initializer, variable, stamp, checkedMethods)) {
|
||||
return true;
|
||||
for (PsiResourceListElement resource : resourceList) {
|
||||
if (resource instanceof PsiResourceVariable) {
|
||||
final PsiExpression initializer = ((PsiResourceVariable)resource).getInitializer();
|
||||
if (expressionAssignsVariable(initializer, variable, stamp, checkedMethods)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+157
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.
|
||||
*/
|
||||
class C {
|
||||
void m() throws Exception {
|
||||
String <warning descr="Local variable 's1' is redundant">s1</warning> = null;
|
||||
String <warning descr="Local variable 's2' is redundant">s2</warning> = s1, s3 = null;
|
||||
System.out.println(s2 + s3);
|
||||
|
||||
AutoCloseable <warning descr="Local variable 'r1' is redundant">r1</warning> = null;
|
||||
try (AutoCloseable r2 = r1; AutoCloseable r3 = null) {
|
||||
System.out.println(r2.toString() + r3.toString());
|
||||
}
|
||||
}
|
||||
|
||||
void n() throws Exception {
|
||||
String s1 = null;
|
||||
String <warning descr="Local variable 's2' is redundant">s2</warning> = s1, <warning descr="Local variable 's3' is redundant">s3</warning> = s1;
|
||||
System.out.println(s2 + s3);
|
||||
|
||||
AutoCloseable r1 = null;
|
||||
try (AutoCloseable r2 = r1; AutoCloseable r3 = r1) {
|
||||
System.out.println(<error descr="Operator '+' cannot be applied to 'java.lang.AutoCloseable', 'java.lang.AutoCloseable'">r2 + r3</error>);
|
||||
}
|
||||
}
|
||||
|
||||
int boxing(Long l) {
|
||||
long ll = l;
|
||||
return (int) ll;
|
||||
}
|
||||
|
||||
public int foo() {
|
||||
int <warning descr="Local variable 'a' is redundant">a</warning> = 2;
|
||||
int <warning descr="Local variable 'b' is redundant">b</warning> = a;
|
||||
return b;
|
||||
}
|
||||
|
||||
public int bar() {
|
||||
int <warning descr="Local variable 'b' is redundant">b</warning> = 3;
|
||||
return b;
|
||||
}
|
||||
|
||||
public int bar2() throws Exception{
|
||||
final Exception <warning descr="Local variable 'b' is redundant">b</warning> = new Exception();
|
||||
throw b;
|
||||
}
|
||||
|
||||
public int baz() {
|
||||
int a;
|
||||
int <warning descr="Local variable 'b' is redundant">b</warning> = 3;
|
||||
a = b;
|
||||
return a;
|
||||
}
|
||||
|
||||
public int bazoom() {
|
||||
final int i = foo();
|
||||
bar();
|
||||
final int <warning descr="Local variable 'value' is redundant">value</warning> = i;
|
||||
System.out.println(value);
|
||||
return 3;
|
||||
}
|
||||
|
||||
double time() {
|
||||
double time = 0.0, dt = time - 1.0;
|
||||
System.out.println(time);
|
||||
return dt;
|
||||
}
|
||||
|
||||
double time2() {
|
||||
double time = 0.0, dt = time - 1.0;
|
||||
return time;
|
||||
}
|
||||
|
||||
void time3() {
|
||||
double time = 0.0, dt = time - 1.0;
|
||||
double time2 = time;
|
||||
time2 += 1;
|
||||
}
|
||||
|
||||
void through() throws Exception {
|
||||
Exception e2 = instance(), e3 = new RuntimeException(e2);
|
||||
throw e2;
|
||||
}
|
||||
|
||||
Exception instance() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void neededResourceVariable(java.io.InputStream in) throws java.io.IOException {
|
||||
try (java.io.InputStream inn = in) {
|
||||
final int read = inn.read();
|
||||
// do stuff with in
|
||||
}
|
||||
}
|
||||
|
||||
int parenthesized() {
|
||||
final int <warning descr="Local variable 'i' is redundant">i</warning> = 1 + 2;
|
||||
return (i);
|
||||
}
|
||||
|
||||
void parenthesized2() {
|
||||
final RuntimeException <warning descr="Local variable 't' is redundant">t</warning> = new RuntimeException();
|
||||
throw (t);
|
||||
}
|
||||
|
||||
void parenthesized3(int i) {
|
||||
int <warning descr="Local variable 'j' is redundant">j</warning> = (i);
|
||||
}
|
||||
|
||||
void parenthesized4(int k) {
|
||||
final int <warning descr="Local variable 'j' is redundant">j</warning> = 1;
|
||||
k = (j);
|
||||
}
|
||||
|
||||
void parenthesized5() {
|
||||
final int <warning descr="Local variable 'j' is redundant">j</warning> = 1;
|
||||
int <warning descr="Local variable 'k' is redundant">k</warning> = (j);
|
||||
System.out.println(k);
|
||||
}
|
||||
|
||||
void usedIn8Inner(int j) {
|
||||
for (int i = 0; i < 7; i++) {
|
||||
int k = i;
|
||||
int <warning descr="Local variable 'n' is redundant">n</warning> = j;
|
||||
class F {
|
||||
{
|
||||
System.out.println(k + n);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nameShadow(final String name) {
|
||||
final String child = name;
|
||||
class A {
|
||||
void foo(String s){}
|
||||
}
|
||||
|
||||
A a = new A() {
|
||||
void foo(String name) {
|
||||
System.out.println(child);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
-142
@@ -1,142 +0,0 @@
|
||||
class C {
|
||||
void m() throws Exception {
|
||||
String s1 = null;
|
||||
String s2 = s1, s3 = null;
|
||||
System.out.println(s2 + s3);
|
||||
|
||||
AutoCloseable r1 = null;
|
||||
try (AutoCloseable r2 = r1; AutoCloseable r3 = null) {
|
||||
System.out.println(r2.toString() + r3.toString());
|
||||
}
|
||||
}
|
||||
|
||||
void n() throws Exception {
|
||||
String s1 = null;
|
||||
String s2 = s1, s3 = s1;
|
||||
System.out.println(s2 + s3);
|
||||
|
||||
AutoCloseable r1 = null;
|
||||
try (AutoCloseable r2 = r1; AutoCloseable r3 = r1) {
|
||||
System.out.println(r2 + r3);
|
||||
}
|
||||
}
|
||||
|
||||
int boxing(Long l) {
|
||||
long ll = l;
|
||||
return (int) ll;
|
||||
}
|
||||
|
||||
public int foo() {
|
||||
int a = 2;
|
||||
int b = a;
|
||||
return b;
|
||||
}
|
||||
|
||||
public int bar() {
|
||||
int b = 3;
|
||||
return b;
|
||||
}
|
||||
|
||||
public int bar2() throws Exception{
|
||||
final Exception b = new Exception();
|
||||
throw b;
|
||||
}
|
||||
|
||||
public int baz() {
|
||||
int a;
|
||||
int b = 3;
|
||||
a = b;
|
||||
return a;
|
||||
}
|
||||
|
||||
public int bazoom() {
|
||||
final int i = foo();
|
||||
bar();
|
||||
final int value = i;
|
||||
System.out.println(value);
|
||||
return 3;
|
||||
}
|
||||
|
||||
double time() {
|
||||
double time = 0.0, dt = time - 1.0;
|
||||
System.out.println(time);
|
||||
return dt;
|
||||
}
|
||||
|
||||
double time2() {
|
||||
double time = 0.0, dt = time - 1.0;
|
||||
return time;
|
||||
}
|
||||
|
||||
void time3() {
|
||||
double time = 0.0, dt = time - 1.0;
|
||||
double time2 = time;
|
||||
time2 += 1;
|
||||
}
|
||||
|
||||
void through() throws Exception {
|
||||
Exception e2 = instance(), e3 = new RuntimeException(e2);
|
||||
throw e2;
|
||||
}
|
||||
|
||||
Exception instance() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void neededResourceVariable(java.io.InputStream in) throws java.io.IOException {
|
||||
try (java.io.InputStream inn = in) {
|
||||
final int read = inn.read();
|
||||
// do stuff with in
|
||||
}
|
||||
}
|
||||
|
||||
int parenthesized() {
|
||||
final int i = 1 + 2;
|
||||
return (i);
|
||||
}
|
||||
|
||||
void parenthesized2() {
|
||||
final RuntimeException t = new RuntimeException();
|
||||
throw (t);
|
||||
}
|
||||
|
||||
void parenthesized3(int i) {
|
||||
int j = (i);
|
||||
}
|
||||
|
||||
void parenthesized4(int k) {
|
||||
final int j = 1;
|
||||
k = (j);
|
||||
}
|
||||
|
||||
void parenthesized5() {
|
||||
final int j = 1;
|
||||
int k = (j);
|
||||
System.out.println(k);
|
||||
}
|
||||
|
||||
void usedIn8Inner(int j) {
|
||||
for (int i = 0; i < 7; i++) {
|
||||
int k = i;
|
||||
int n = j;
|
||||
class F {
|
||||
{
|
||||
System.out.println(k + n);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nameShadow(final String name) {
|
||||
final String child = name;
|
||||
class A {
|
||||
void foo(String s){}
|
||||
}
|
||||
|
||||
A a = new A() {
|
||||
void foo(String name) {
|
||||
System.out.println(child);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
-128
@@ -1,128 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
<problem>
|
||||
<file>C.java</file>
|
||||
<line>3</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Redundant local variable</problem_class>
|
||||
<description>Local variable <code>s1</code> is redundant #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>C.java</file>
|
||||
<line>4</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Redundant local variable</problem_class>
|
||||
<description>Local variable <code>s2</code> is redundant #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>C.java</file>
|
||||
<line>7</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Redundant local variable</problem_class>
|
||||
<description>Local variable <code>r1</code> is redundant #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>C.java</file>
|
||||
<line>15</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Redundant local variable</problem_class>
|
||||
<description>Local variable <code>s2</code> is redundant #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>C.java</file>
|
||||
<line>15</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Redundant local variable</problem_class>
|
||||
<description>Local variable <code>s3</code> is redundant #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>C.java</file>
|
||||
<line>30</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Redundant local variable</problem_class>
|
||||
<description>Local variable <code>a</code> is redundant #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>C.java</file>
|
||||
<line>31</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Redundant local variable</problem_class>
|
||||
<description>Local variable <code>b</code> is redundant #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>C.java</file>
|
||||
<line>36</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Redundant local variable</problem_class>
|
||||
<description>Local variable <code>b</code> is redundant #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>C.java</file>
|
||||
<line>41</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Redundant local variable</problem_class>
|
||||
<description>Local variable <code>b</code> is redundant #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>C.java</file>
|
||||
<line>47</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Redundant local variable</problem_class>
|
||||
<description>Local variable <code>b</code> is redundant #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>C.java</file>
|
||||
<line>55</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Redundant local variable</problem_class>
|
||||
<description>Local variable <code>value</code> is redundant #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>C.java</file>
|
||||
<line>94</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Redundant local variable</problem_class>
|
||||
<description>Local variable <code>i</code> is redundant #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>C.java</file>
|
||||
<line>99</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Redundant local variable</problem_class>
|
||||
<description>Local variable <code>t</code> is redundant #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>C.java</file>
|
||||
<line>108</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Redundant local variable</problem_class>
|
||||
<description>Local variable <code>j</code> is redundant #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>C.java</file>
|
||||
<line>104</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Redundant local variable</problem_class>
|
||||
<description>Local variable <code>j</code> is redundant #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>C.java</file>
|
||||
<line>113</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Redundant local variable</problem_class>
|
||||
<description>Local variable <code>j</code> is redundant #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>C.java</file>
|
||||
<line>114</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Redundant local variable</problem_class>
|
||||
<description>Local variable <code>k</code> is redundant #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>C.java</file>
|
||||
<line>121</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Redundant local variable</problem_class>
|
||||
<description>Local variable <code>n</code> is redundant #loc</description>
|
||||
</problem>
|
||||
</problems>
|
||||
+19
-8
@@ -1,22 +1,32 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.siyeh.igtest.initialization.instance_variable_uninitialized_use;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
|
||||
|
||||
class InstanceVariableUnitializedUse {
|
||||
|
||||
int i;
|
||||
InstanceVariableUnitializedUse() throws IOException {
|
||||
|
||||
InstanceVariableUnitializedUse() throws IOException {
|
||||
try (java.io.FileInputStream in = new java.io.FileInputStream("asdf" + (i=3) + "asdf")) {}
|
||||
System.out.println(i);
|
||||
|
||||
}
|
||||
}
|
||||
class InstanceFieldVsDoWhile {
|
||||
|
||||
class InstanceFieldVsDoWhile {
|
||||
private Object object;
|
||||
|
||||
public InstanceFieldVsDoWhile() {
|
||||
@@ -25,11 +35,12 @@ class InstanceFieldVsDoWhile {
|
||||
} while (object.hashCode() < 1000); // Instance field used before initialization
|
||||
}
|
||||
}
|
||||
|
||||
class FinalField {
|
||||
private final Object object;
|
||||
|
||||
FinalField() {
|
||||
System.out.println(object);
|
||||
System.out.println(<error descr="Variable 'object' might not have been initialized">object</error>);
|
||||
object = null;
|
||||
}
|
||||
}
|
||||
|
||||
-4
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
|
||||
</problems>
|
||||
+19
-4
@@ -1,22 +1,37 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.siyeh.igtest.initialization.static_variable_uninitialized_use;
|
||||
|
||||
public class StaticVariableUninitializedUse {
|
||||
|
||||
static Integer i;
|
||||
static String s;
|
||||
|
||||
static {
|
||||
System.out.println(StaticVariableUninitializedUse.s);
|
||||
System.out.println(<warning descr="Static field 'StaticVariableUninitializedUse.s' used before initialization">StaticVariableUninitializedUse.s</warning>);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
if (s instanceof Object) {}
|
||||
if (i == 42) {
|
||||
if (<warning descr="Static field 'i' used before initialization">i</warning> == 42) {
|
||||
System.out.println("Unbelievable");
|
||||
}
|
||||
System.out.println("only warn once in a method" + i);
|
||||
}
|
||||
|
||||
static int foo() {
|
||||
return i;
|
||||
return <warning descr="Static field 'i' used before initialization">i</warning>;
|
||||
}
|
||||
}
|
||||
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
|
||||
<problem>
|
||||
<file>StaticVariableUninitializedUse.java</file>
|
||||
<line>9</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Static field used before initialization</problem_class>
|
||||
<description>Static field <code>StaticVariableUninitializedUse.s</code> used before initialization #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>StaticVariableUninitializedUse.java</file>
|
||||
<line>13</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Static field used before initialization</problem_class>
|
||||
<description>Static field <code>i</code> used before initialization #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>StaticVariableUninitializedUse.java</file>
|
||||
<line>20</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Static field used before initialization</problem_class>
|
||||
<description>Static field <code>i</code> used before initialization #loc</description>
|
||||
</problem>
|
||||
</problems>
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,7 +19,6 @@ import com.intellij.codeInspection.InspectionProfileEntry;
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.intellij.lang.annotations.Language;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -44,26 +43,26 @@ public abstract class LightInspectionTestCase extends LightCodeInsightFixtureTes
|
||||
@Nullable
|
||||
protected abstract InspectionProfileEntry getInspection();
|
||||
|
||||
@NonNls
|
||||
@Language("JAVA")
|
||||
@SuppressWarnings("LanguageMismatch")
|
||||
protected String[] getEnvironmentClasses() {
|
||||
return ArrayUtil.EMPTY_STRING_ARRAY;
|
||||
}
|
||||
|
||||
protected void addEnvironmentClass(@Language("JAVA") @NotNull @NonNls String classText) {
|
||||
protected void addEnvironmentClass(@Language("JAVA") @NotNull String classText) {
|
||||
myFixture.addClass(classText);
|
||||
}
|
||||
|
||||
protected final void doStatementTest(@Language(value="JAVA", prefix="class X { void m() {", suffix="}}") @NotNull @NonNls String statementText) {
|
||||
protected final void doStatementTest(@Language(value="JAVA", prefix="class X { void m() {", suffix="}}") @NotNull String statementText) {
|
||||
doTest("class X { void m() {" + statementText + "}}");
|
||||
}
|
||||
|
||||
protected final void doMemberTest(@Language(value="JAVA", prefix="class X {", suffix="}") @NotNull @NonNls String memberText) {
|
||||
protected final void doMemberTest(@Language(value="JAVA", prefix="class X {", suffix="}") @NotNull String memberText) {
|
||||
doTest("class X {" + memberText + "}");
|
||||
}
|
||||
|
||||
protected final void doTest(@Language("JAVA") @NotNull @NonNls String classText) {
|
||||
@NonNls final StringBuilder newText = new StringBuilder();
|
||||
protected final void doTest(@Language("JAVA") @NotNull String classText) {
|
||||
final StringBuilder newText = new StringBuilder();
|
||||
int start = 0;
|
||||
int end = classText.indexOf("/*");
|
||||
while (end >= 0) {
|
||||
@@ -73,11 +72,15 @@ public abstract class LightInspectionTestCase extends LightCodeInsightFixtureTes
|
||||
if (end < 0) {
|
||||
throw new IllegalArgumentException("invalid class text");
|
||||
}
|
||||
final String warning = classText.substring(start, end);
|
||||
if (warning.isEmpty()) {
|
||||
final String text = classText.substring(start, end);
|
||||
if (text.isEmpty()) {
|
||||
newText.append("</warning>");
|
||||
} else {
|
||||
newText.append("<warning descr=\"").append(warning).append("\">");
|
||||
}
|
||||
else if ("_".equals(text)) {
|
||||
newText.append("<caret>");
|
||||
}
|
||||
else {
|
||||
newText.append("<warning descr=\"").append(text).append("\">");
|
||||
}
|
||||
start = end + 2;
|
||||
end = classText.indexOf("/*", end + 1);
|
||||
@@ -89,20 +92,19 @@ public abstract class LightInspectionTestCase extends LightCodeInsightFixtureTes
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
final Class<? extends InspectionProfileEntry> inspectionClass = getInspection().getClass();
|
||||
final String className = inspectionClass.getName();
|
||||
final InspectionProfileEntry inspection = getInspection();
|
||||
assertNotNull("File-based tests should either return an inspection or override this method", inspection);
|
||||
final String className = inspection.getClass().getName();
|
||||
final String[] words = className.split("\\.");
|
||||
@NonNls final StringBuilder basePath = new StringBuilder("/plugins/InspectionGadgets/test/");
|
||||
final StringBuilder basePath = new StringBuilder("/plugins/InspectionGadgets/test/");
|
||||
final int lastWordIndex = words.length - 1;
|
||||
for (int i = 0; i < lastWordIndex; i++) {
|
||||
final String word = words[i];
|
||||
String word = words[i];
|
||||
if (word.equals("ig")) {
|
||||
basePath.append("igtest");
|
||||
//noinspection SpellCheckingInspection
|
||||
word = "igtest";
|
||||
}
|
||||
else {
|
||||
basePath.append(word);
|
||||
}
|
||||
basePath.append('/');
|
||||
basePath.append(word).append('/');
|
||||
}
|
||||
String lastWord = words[lastWordIndex];
|
||||
if (lastWord.endsWith("Inspection")) {
|
||||
|
||||
+7
-15
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -15,22 +15,14 @@
|
||||
*/
|
||||
package com.siyeh.ig.dataflow;
|
||||
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.siyeh.ig.IGInspectionTestCase;
|
||||
import com.intellij.codeInspection.InspectionProfileEntry;
|
||||
import com.siyeh.ig.LightInspectionTestCase;
|
||||
|
||||
public class UnnecessaryLocalVariableInspectionTest extends IGInspectionTestCase {
|
||||
public class UnnecessaryLocalVariableInspectionTest extends LightInspectionTestCase {
|
||||
@Override
|
||||
protected Sdk getTestProjectSdk() {
|
||||
final Sdk sdk = IdeaTestUtil.getMockJdk17();
|
||||
LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.HIGHEST);
|
||||
return sdk;
|
||||
protected InspectionProfileEntry getInspection() {
|
||||
return new UnnecessaryLocalVariableInspection();
|
||||
}
|
||||
|
||||
public void test() throws Exception {
|
||||
doTest("com/siyeh/igtest/dataflow/unnecessary_local_vars",
|
||||
new UnnecessaryLocalVariableInspection());
|
||||
}
|
||||
public void test() { doNamedTest("C"); }
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.siyeh.ig.errorhandling;
|
||||
|
||||
import com.intellij.codeInspection.InspectionProfileEntry;
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
import com.siyeh.ig.LightInspectionTestCase;
|
||||
|
||||
public class EmptyFinallyBlockInspectionTest extends LightInspectionTestCase {
|
||||
@Override
|
||||
protected InspectionProfileEntry getInspection() {
|
||||
return new EmptyFinallyBlockInspection();
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyFinallyBlock")
|
||||
public void testSimple() {
|
||||
doTest("class C {\n" +
|
||||
" void m() throws Exception {\n" +
|
||||
" try { throw new Exception(); }\n" +
|
||||
" /*Empty 'finally' block*//*_*/finally/**/ { }\n" +
|
||||
" }\n" +
|
||||
"}");
|
||||
myFixture.findSingleIntention(InspectionGadgetsBundle.message("remove.try.finally.block.quickfix"));
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyFinallyBlock")
|
||||
public void testResources() {
|
||||
doTest("class C {\n" +
|
||||
" void m() throws Exception {\n" +
|
||||
" try (AutoCloseable r = null) { throw new Exception(); }\n" +
|
||||
" /*Empty 'finally' block*//*_*/finally/**/ { }\n" +
|
||||
" }\n" +
|
||||
"}");
|
||||
myFixture.findSingleIntention(InspectionGadgetsBundle.message("remove.finally.block.quickfix"));
|
||||
}
|
||||
}
|
||||
+23
-6
@@ -1,11 +1,28 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.siyeh.ig.initialization;
|
||||
|
||||
import com.siyeh.ig.IGInspectionTestCase;
|
||||
import com.intellij.codeInspection.InspectionProfileEntry;
|
||||
import com.siyeh.ig.LightInspectionTestCase;
|
||||
|
||||
public class InstanceVariableUninitializedUseInspectionTest
|
||||
extends IGInspectionTestCase {
|
||||
|
||||
public void test() throws Exception {
|
||||
doTest("com/siyeh/igtest/initialization/instance_variable_uninitialized_use", new InstanceVariableUninitializedUseInspection());
|
||||
public class InstanceVariableUninitializedUseInspectionTest extends LightInspectionTestCase {
|
||||
@Override
|
||||
protected InspectionProfileEntry getInspection() {
|
||||
return new InstanceVariableUninitializedUseInspection();
|
||||
}
|
||||
|
||||
public void test() { doNamedTest("InstanceVariableUninitializedUse"); }
|
||||
}
|
||||
|
||||
+23
-7
@@ -1,12 +1,28 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.siyeh.ig.initialization;
|
||||
|
||||
import com.siyeh.ig.IGInspectionTestCase;
|
||||
import com.intellij.codeInspection.InspectionProfileEntry;
|
||||
import com.siyeh.ig.LightInspectionTestCase;
|
||||
|
||||
public class StaticVariableUninitializedUseInspectionTest
|
||||
extends IGInspectionTestCase {
|
||||
|
||||
public void test() throws Exception {
|
||||
doTest("com/siyeh/igtest/initialization/static_variable_uninitialized_use",
|
||||
new StaticVariableUninitializedUseInspection());
|
||||
public class StaticVariableUninitializedUseInspectionTest extends LightInspectionTestCase {
|
||||
@Override
|
||||
protected InspectionProfileEntry getInspection() {
|
||||
return new StaticVariableUninitializedUseInspection();
|
||||
}
|
||||
|
||||
public void test() { doNamedTest("StaticVariableUninitializedUse"); }
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user