mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-20 05:21:29 +07:00
added create property quick fix
This commit is contained in:
@@ -19,6 +19,9 @@ ACT.from.some.module.import=Import from ...
|
||||
QFIX.add.parameter.self=Add parameter ''{0}''
|
||||
QFIX.add.super=Add super class call
|
||||
|
||||
QFIX.add.property=Add property for the field
|
||||
QFIX.use.property=Use property for the field
|
||||
|
||||
QFIX.add.encoding=Add encoding declaration
|
||||
|
||||
QFIX.NAME.parameters=Parameters of functions and methods
|
||||
|
||||
@@ -77,8 +77,6 @@ public class PyMethodMayBeStaticInspection extends PyInspection {
|
||||
if (property != null) return;
|
||||
|
||||
final PyStatementList statementList = node.getStatementList();
|
||||
if (statementList == null) return;
|
||||
|
||||
final PyStatement[] statements = statementList.getStatements();
|
||||
|
||||
if (statements.length == 1 && statements[0] instanceof PyPassStatement) return;
|
||||
|
||||
@@ -16,8 +16,11 @@
|
||||
package com.jetbrains.python.inspections;
|
||||
|
||||
import com.intellij.codeInspection.LocalInspectionToolSession;
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemHighlightType;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.PsiReference;
|
||||
@@ -26,9 +29,11 @@ import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
|
||||
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
|
||||
import com.jetbrains.python.codeInsight.stdlib.PyNamedTupleType;
|
||||
import com.jetbrains.python.inspections.quickfix.PyAddPropertyForFieldQuickFix;
|
||||
import com.jetbrains.python.psi.PyClass;
|
||||
import com.jetbrains.python.psi.PyExpression;
|
||||
import com.jetbrains.python.psi.PyReferenceExpression;
|
||||
import com.jetbrains.python.psi.PyTargetExpression;
|
||||
import com.jetbrains.python.psi.types.PyModuleType;
|
||||
import com.jetbrains.python.psi.types.PyType;
|
||||
import com.jetbrains.python.testing.pytest.PyTestUtil;
|
||||
@@ -37,6 +42,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* User: ktisha
|
||||
@@ -75,29 +82,40 @@ public class PyProtectedMemberInspection extends PyInspection {
|
||||
if (qualifier == null || PyNames.CANONICAL_SELF.equals(qualifier.getText())) return;
|
||||
if (myTypeEvalContext.getType(qualifier) instanceof PyNamedTupleType) return;
|
||||
final String name = node.getName();
|
||||
final List<LocalQuickFix> quickFixes = new ArrayList<LocalQuickFix>();
|
||||
quickFixes.add(new PyRenameElementQuickFix());
|
||||
|
||||
if (name != null && name.startsWith("_") && !name.startsWith("__") && !name.endsWith("__")) {
|
||||
final PsiReference reference = node.getReference(getResolveContext());
|
||||
if (reference == null) return;
|
||||
final PsiElement resolvedExpression = reference.resolve();
|
||||
if (resolvedExpression instanceof PyTargetExpression) {
|
||||
final PyClass containingClass = ((PyTargetExpression)resolvedExpression).getContainingClass();
|
||||
if (containingClass != null) {
|
||||
final String qFixName = containingClass.getProperties().containsKey(StringUtil.trimLeading(name, '_')) ?
|
||||
PyBundle.message("QFIX.use.property") : PyBundle.message("QFIX.add.property");
|
||||
quickFixes.add(new PyAddPropertyForFieldQuickFix(qFixName));
|
||||
}
|
||||
}
|
||||
|
||||
final PyClass parentClass = getClassOwner(node);
|
||||
if (parentClass != null) {
|
||||
if (PyTestUtil.isPyTestClass(parentClass) && ignoreTestFunctions) return;
|
||||
final PsiReference reference = node.getReference(getResolveContext());
|
||||
if (reference != null) {
|
||||
final PsiElement resolvedExpression = reference.resolve();
|
||||
final PyClass resolvedClass = getClassOwner(resolvedExpression);
|
||||
if (parentClass.isSubclass(resolvedClass))
|
||||
final PyClass resolvedClass = getClassOwner(resolvedExpression);
|
||||
if (parentClass.isSubclass(resolvedClass))
|
||||
return;
|
||||
|
||||
PyClass outerClass = getClassOwner(parentClass);
|
||||
while (outerClass != null) {
|
||||
if (outerClass.isSubclass(resolvedClass))
|
||||
return;
|
||||
|
||||
PyClass outerClass = getClassOwner(parentClass);
|
||||
while (outerClass != null) {
|
||||
if (outerClass.isSubclass(resolvedClass))
|
||||
return;
|
||||
|
||||
outerClass = getClassOwner(outerClass);
|
||||
}
|
||||
outerClass = getClassOwner(outerClass);
|
||||
}
|
||||
}
|
||||
final PyType type = myTypeEvalContext.getType(qualifier);
|
||||
final String bundleKey = type instanceof PyModuleType ? "INSP.protected.member.$0.access.module" : "INSP.protected.member.$0.access";
|
||||
registerProblem(node, PyBundle.message(bundleKey, name), new PyRenameElementQuickFix());
|
||||
registerProblem(node, PyBundle.message(bundleKey, name), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, null, quickFixes.toArray(new LocalQuickFix[quickFixes.size()-1]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2000-2013 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.jetbrains.python.inspections.quickfix;
|
||||
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class PyAddPropertyForFieldQuickFix implements LocalQuickFix {
|
||||
private String myName = PyBundle.message("QFIX.add.property");
|
||||
|
||||
public PyAddPropertyForFieldQuickFix(String name) {
|
||||
myName = name;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return myName;
|
||||
}
|
||||
|
||||
@NonNls
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) {
|
||||
final PsiElement element = descriptor.getPsiElement();
|
||||
if (element instanceof PyReferenceExpression) {
|
||||
final PsiReference reference = element.getReference();
|
||||
if (reference == null) return;
|
||||
final PsiElement resolved = reference.resolve();
|
||||
if (resolved instanceof PyTargetExpression) {
|
||||
PyTargetExpression target = (PyTargetExpression)resolved;
|
||||
final PyClass containingClass = target.getContainingClass();
|
||||
if (containingClass != null) {
|
||||
final String name = target.getName();
|
||||
if (name == null) return;
|
||||
String propertyName = StringUtil.trimStart(name, "_");
|
||||
final Map<String,Property> properties = containingClass.getProperties();
|
||||
final PyElementGenerator generator = PyElementGenerator.getInstance(project);
|
||||
if (!properties.containsKey(propertyName)) {
|
||||
String propertyText = "@property\ndef " + propertyName + "(self):\n\t return self." + name;
|
||||
final PyFunction property = generator.createFromText(LanguageLevel.forElement(containingClass), PyFunction.class, propertyText);
|
||||
PyUtil.addElementToStatementList(property, containingClass.getStatementList());
|
||||
}
|
||||
final PyExpression qualifier = ((PyReferenceExpression)element).getQualifier();
|
||||
if (qualifier != null) {
|
||||
String newElementText = qualifier.getText() + "." + propertyName;
|
||||
final PyExpression newElement = generator.createExpressionFromText(LanguageLevel.forElement(containingClass), newElementText);
|
||||
element.replace(newElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
class A:
|
||||
def __init__(self):
|
||||
self._x = 1
|
||||
|
||||
def _foo(self):
|
||||
print(self._x)
|
||||
|
||||
a = A()
|
||||
a._f<caret>oo()
|
||||
|
||||
print(a._x)
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
class A:
|
||||
def __init__(self):
|
||||
self._x = 1
|
||||
|
||||
def _foo(self):
|
||||
print(self._x)
|
||||
|
||||
a = A()
|
||||
a._foo()
|
||||
|
||||
print(a._<caret>x)
|
||||
@@ -0,0 +1,16 @@
|
||||
|
||||
class A:
|
||||
@property
|
||||
def x(self):
|
||||
return self._x
|
||||
|
||||
def __init__(self):
|
||||
self._x = 1
|
||||
|
||||
def _foo(self):
|
||||
print(self._x)
|
||||
|
||||
a = A()
|
||||
a._foo()
|
||||
|
||||
print(a.x)
|
||||
@@ -0,0 +1,16 @@
|
||||
class A:
|
||||
@property
|
||||
def x(self):
|
||||
return self._x
|
||||
|
||||
def __init__(self):
|
||||
self._x = 1
|
||||
|
||||
def _foo(self):
|
||||
print(self._x)
|
||||
|
||||
a = A()
|
||||
a._foo()
|
||||
|
||||
print(a.x)
|
||||
print(a._<caret>x)
|
||||
@@ -0,0 +1,16 @@
|
||||
class A:
|
||||
@property
|
||||
def x(self):
|
||||
return self._x
|
||||
|
||||
def __init__(self):
|
||||
self._x = 1
|
||||
|
||||
def _foo(self):
|
||||
print(self._x)
|
||||
|
||||
a = A()
|
||||
a._foo()
|
||||
|
||||
print(a.x)
|
||||
print(a.x)
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2000-2013 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.jetbrains.python.quickFixes;
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PyQuickFixTestCase;
|
||||
import com.jetbrains.python.inspections.PyProtectedMemberInspection;
|
||||
|
||||
/**
|
||||
* User: ktisha
|
||||
*/
|
||||
@TestDataPath("$CONTENT_ROOT/../testData/quickFixes/PyAddPropertyForFieldQuickFixTest")
|
||||
public class PyAddPropertyForFieldQuickFixTest extends PyQuickFixTestCase {
|
||||
public void testProtectedMember() {
|
||||
doQuickFixTest(PyProtectedMemberInspection.class, PyBundle.message("QFIX.add.property"));
|
||||
}
|
||||
|
||||
public void testUseProperty() {
|
||||
doQuickFixTest(PyProtectedMemberInspection.class, PyBundle.message("QFIX.use.property"));
|
||||
}
|
||||
|
||||
public void testProtectedFunction() {
|
||||
final String testFileName = getTestName(true);
|
||||
myFixture.enableInspections(PyProtectedMemberInspection.class);
|
||||
myFixture.configureByFile(testFileName + ".py");
|
||||
myFixture.checkHighlighting(true, false, false);
|
||||
final IntentionAction intentionAction = myFixture.getAvailableIntention(PyBundle.message("QFIX.add.property"));
|
||||
assertNull(intentionAction);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user