Merge remote-tracking branch 'origin/master'

This commit is contained in:
Konstantin Bulenkov
2015-07-22 19:11:09 +02:00
127 changed files with 1956 additions and 1255 deletions
@@ -219,4 +219,7 @@ public abstract class TestDiscoveryConfiguration extends JavaTestConfigurationBa
public String getChangeList() {
return myChangeList;
}
@NotNull
public abstract String getFrameworkPrefix();
}
@@ -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;
@@ -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();
@@ -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;
@@ -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;
}
}
});
}
});
@@ -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;
}
@@ -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) {
@@ -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);
}
}
}
@@ -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) {
@@ -380,6 +380,7 @@ public class ExtractMethodSignatureSuggester {
myDuplicatesNumber = duplicatesNumber;
setTitle("Extract Parameters to Replace Duplicates");
setOKButtonText("Accept Signature Change");
setCancelButtonText("Keep Original Signature");
init();
}
@@ -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();
}
}
@@ -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;
@@ -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);
@@ -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";
}
}
@@ -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) {}
@@ -0,0 +1,8 @@
class MyClass {
void f() {
String response;
AutoCloseable resource;
try (re<caret>) {
}
}
}
@@ -0,0 +1,8 @@
class MyClass {
void f() {
String response;
AutoCloseable resource;
try (resource<caret>) {
}
}
}
@@ -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")) { }
}
}
@@ -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);
}
}
}
@@ -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>() { }
}
@@ -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('}')
@@ -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")
@@ -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); }
}
@@ -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);
@@ -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){
@@ -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;
@@ -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
@@ -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();
}
}
@@ -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();
@@ -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,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"/>
@@ -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);
@@ -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);
}
@@ -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) {
@@ -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) {
@@ -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);
}
}
@@ -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);
}
}
@@ -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>
@@ -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) {
@@ -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) {
@@ -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) {
@@ -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();
@@ -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);
}
}
@@ -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;
}
}
}
}
@@ -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;
}
}
}
}
@@ -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);
}
};
}
}
@@ -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);
}
};
}
}
@@ -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 &lt;code&gt;s1&lt;/code&gt; 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 &lt;code&gt;s2&lt;/code&gt; 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 &lt;code&gt;r1&lt;/code&gt; 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 &lt;code&gt;s2&lt;/code&gt; 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 &lt;code&gt;s3&lt;/code&gt; 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 &lt;code&gt;a&lt;/code&gt; 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 &lt;code&gt;b&lt;/code&gt; 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 &lt;code&gt;b&lt;/code&gt; 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 &lt;code&gt;b&lt;/code&gt; 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 &lt;code&gt;b&lt;/code&gt; 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 &lt;code&gt;value&lt;/code&gt; 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 &lt;code&gt;i&lt;/code&gt; 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 &lt;code&gt;t&lt;/code&gt; 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 &lt;code&gt;j&lt;/code&gt; 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 &lt;code&gt;j&lt;/code&gt; 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 &lt;code&gt;j&lt;/code&gt; 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 &lt;code&gt;k&lt;/code&gt; 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 &lt;code&gt;n&lt;/code&gt; is redundant #loc</description>
</problem>
</problems>
@@ -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;
}
}
@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<problems>
</problems>
@@ -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>;
}
}
@@ -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 &lt;code&gt;StaticVariableUninitializedUse.s&lt;/code&gt; 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 &lt;code&gt;i&lt;/code&gt; 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 &lt;code&gt;i&lt;/code&gt; 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")) {
@@ -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"); }
}
@@ -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"));
}
}
@@ -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"); }
}
@@ -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