mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
+14
-1
@@ -225,7 +225,10 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool {
|
||||
try {
|
||||
final List<LocalQuickFix> fixes = new SmartList<LocalQuickFix>();
|
||||
|
||||
if (!(qualifier instanceof PsiLiteralExpression && ((PsiLiteralExpression)qualifier).getValue() == null)) {
|
||||
if (isVolatileFieldReference(qualifier)) {
|
||||
ContainerUtil.addIfNotNull(fixes, createIntroduceVariableFix(qualifier));
|
||||
}
|
||||
else if (!(qualifier instanceof PsiLiteralExpression && ((PsiLiteralExpression)qualifier).getValue() == null)) {
|
||||
if (PsiUtil.getLanguageLevel(qualifier).isAtLeast(LanguageLevel.JDK_1_4)) {
|
||||
final Project project = qualifier.getProject();
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory();
|
||||
@@ -250,6 +253,16 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected LocalQuickFixOnPsiElement createIntroduceVariableFix(PsiExpression expression) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isVolatileFieldReference(PsiExpression qualifier) {
|
||||
PsiElement target = qualifier instanceof PsiReferenceExpression ? ((PsiReferenceExpression)qualifier).resolve() : null;
|
||||
return target instanceof PsiField && ((PsiField)target).hasModifierProperty(PsiModifier.VOLATILE);
|
||||
}
|
||||
|
||||
protected LocalQuickFix createAssertFix(PsiBinaryExpression binary, PsiExpression expression) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -19,14 +19,18 @@ import com.intellij.codeInsight.NullableNotNullDialog;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.psi.JavaTokenType;
|
||||
import com.intellij.psi.PsiAssignmentExpression;
|
||||
import com.intellij.psi.PsiBinaryExpression;
|
||||
import com.intellij.psi.PsiExpression;
|
||||
import com.intellij.openapi.util.AsyncResult;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.refactoring.JavaRefactoringActionHandlerFactory;
|
||||
import com.intellij.refactoring.RefactoringActionHandler;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
@@ -64,6 +68,40 @@ public class DataFlowInspection extends DataFlowInspectionBase {
|
||||
return RefactoringUtil.getParentStatement(expression, false) == null ? null : new AddAssertStatementFix(binary);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LocalQuickFixOnPsiElement createIntroduceVariableFix(final PsiExpression expression) {
|
||||
return new LocalQuickFixOnPsiElement(expression) {
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return "Introduce Local Variable";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull final Project project,
|
||||
@NotNull PsiFile file,
|
||||
@NotNull final PsiElement startElement,
|
||||
@NotNull PsiElement endElement) {
|
||||
final RefactoringActionHandler handler = JavaRefactoringActionHandlerFactory.getInstance().createIntroduceVariableHandler();
|
||||
final AsyncResult<DataContext> dataContextContainer = DataManager.getInstance().getDataContextFromFocus();
|
||||
dataContextContainer.doWhenDone(new Consumer<DataContext>() {
|
||||
@Override
|
||||
public void consume(DataContext dataContext) {
|
||||
handler.invoke(project, new PsiElement[]{startElement}, dataContext);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return getText();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private class OptionsPanel extends JPanel {
|
||||
private final JCheckBox myIgnoreAssertions;
|
||||
private final JCheckBox myReportConstantReferences;
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
class Test {
|
||||
@Nullable volatile String x;
|
||||
|
||||
public void foo() {
|
||||
if (x != null) {
|
||||
System.out.println(<warning descr="Method invocation 'x.substring(1)' may produce 'java.lang.NullPointerException'">x.sub<caret>string(1)</warning>);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -376,6 +376,13 @@ public class DataFlowInspectionTest extends LightCodeInsightFixtureTestCase {
|
||||
assertEmpty(myFixture.filterAvailableIntentions("Simplify"));
|
||||
}
|
||||
|
||||
public void testVolatileFieldNPEFixes() {
|
||||
doTest();
|
||||
assertEmpty(myFixture.filterAvailableIntentions("Surround"));
|
||||
assertEmpty(myFixture.filterAvailableIntentions("Assert"));
|
||||
assertNotEmpty(myFixture.filterAvailableIntentions("Introduce Local Variable"));
|
||||
}
|
||||
|
||||
public void testAssertThat() {
|
||||
myFixture.addClass("package org.hamcrest; public class CoreMatchers { " +
|
||||
"public static <T> Matcher<T> notNullValue() {}\n" +
|
||||
|
||||
+2
-7
@@ -34,7 +34,6 @@ import java.util.*;
|
||||
* @author peter
|
||||
*/
|
||||
public abstract class GrMapType extends GrLiteralClassType {
|
||||
private final String myJavaClassName;
|
||||
|
||||
private final VolatileNotNullLazyValue<PsiType[]> myParameters = new VolatileNotNullLazyValue<PsiType[]>() {
|
||||
@NotNull
|
||||
@@ -58,22 +57,18 @@ public abstract class GrMapType extends GrLiteralClassType {
|
||||
GlobalSearchScope scope,
|
||||
LanguageLevel languageLevel) {
|
||||
super(languageLevel, scope, facade);
|
||||
|
||||
myJavaClassName = facade.findClass(
|
||||
GroovyCommonClassNames.JAVA_UTIL_LINKED_HASH_MAP, scope) != null ? GroovyCommonClassNames.JAVA_UTIL_LINKED_HASH_MAP
|
||||
: CommonClassNames.JAVA_UTIL_MAP;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected String getJavaClassName() {
|
||||
return myJavaClassName;
|
||||
return GroovyCommonClassNames.JAVA_UTIL_LINKED_HASH_MAP;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getClassName() {
|
||||
return StringUtil.getShortName(myJavaClassName);
|
||||
return "LinkedHashMap";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
-1
@@ -192,7 +192,6 @@ public class GrListOrMapImpl extends GrExpressionImpl implements GrListOrMap {
|
||||
GlobalSearchScope scope = listOrMap.getResolveScope();
|
||||
JavaPsiFacade facade = JavaPsiFacade.getInstance(listOrMap.getProject());
|
||||
PsiClass hashMap = facade.findClass(GroovyCommonClassNames.JAVA_UTIL_LINKED_HASH_MAP, scope);
|
||||
if (hashMap == null) hashMap = facade.findClass(CommonClassNames.JAVA_UTIL_MAP, scope);
|
||||
if (hashMap != null) {
|
||||
PsiSubstitutor mapSubstitutor = PsiSubstitutor.EMPTY.
|
||||
put(hashMap.getTypeParameters()[0], com.intellij.psi.util.PsiUtil.substituteTypeParameter(lType, CommonClassNames.JAVA_UTIL_MAP, 0, false)).
|
||||
|
||||
Reference in New Issue
Block a user