mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-08 15:09:39 +07:00
added create property quick fix for the property access inspection
This commit is contained in:
@@ -92,6 +92,8 @@ public abstract class PyElementGenerator {
|
||||
|
||||
public abstract PyImportElement createImportElement(final LanguageLevel languageLevel, String name);
|
||||
|
||||
public abstract PyFunction createProperty(final LanguageLevel languageLevel, String propertyName, String fieldName, AccessDirection accessDirection);
|
||||
|
||||
@NotNull
|
||||
public abstract <T> T createFromText(LanguageLevel langLevel, Class<T> aClass, final String text);
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@ QFIX.use.property=Use property for the field
|
||||
|
||||
QFIX.make.public=Make public
|
||||
|
||||
QFIX.create.property=Create property
|
||||
|
||||
QFIX.add.encoding=Add encoding declaration
|
||||
|
||||
QFIX.NAME.parameters=Parameters of functions and methods
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.inspections.quickfix.PyCreatePropertyQuickFix;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.types.PyClassType;
|
||||
import com.jetbrains.python.psi.types.PyType;
|
||||
@@ -117,7 +118,7 @@ public class PyPropertyAccessInspection extends PyInspection {
|
||||
else {
|
||||
message = PyBundle.message("INSP.property.$0.cant.be.read", name);
|
||||
}
|
||||
registerProblem(node, message);
|
||||
registerProblem(node, message, new PyCreatePropertyQuickFix(dir));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -62,9 +62,8 @@ public class PyAddPropertyForFieldQuickFix implements LocalQuickFix {
|
||||
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 PyFunction property = generator.createProperty(LanguageLevel.forElement(containingClass), propertyName, name, AccessDirection.READ);
|
||||
PyUtil.addElementToStatementList(property, containingClass.getStatementList(), false);
|
||||
}
|
||||
final PyExpression qualifier = ((PyReferenceExpression)element).getQualifier();
|
||||
if (qualifier != null) {
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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.psi.PsiElement;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.types.PyClassType;
|
||||
import com.jetbrains.python.psi.types.PyType;
|
||||
import com.jetbrains.python.psi.types.TypeEvalContext;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class PyCreatePropertyQuickFix implements LocalQuickFix {
|
||||
private final AccessDirection myAccessDirection;
|
||||
|
||||
public PyCreatePropertyQuickFix(AccessDirection dir) {
|
||||
myAccessDirection = dir;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return PyBundle.message("QFIX.create.property");
|
||||
}
|
||||
|
||||
@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 PyQualifiedExpression) {
|
||||
final PyExpression qualifier = ((PyQualifiedExpression)element).getQualifier();
|
||||
if (qualifier != null) {
|
||||
final PyType type = TypeEvalContext.codeAnalysis(element.getContainingFile()).getType(qualifier);
|
||||
if (type instanceof PyClassType) {
|
||||
final PyClass cls = ((PyClassType)type).getPyClass();
|
||||
final String propertyName = ((PyQualifiedExpression)element).getName();
|
||||
if (propertyName == null) return;
|
||||
final String fieldName = "_" + propertyName;
|
||||
final PyElementGenerator generator = PyElementGenerator.getInstance(project);
|
||||
final PyFunction property = generator.createProperty(LanguageLevel.forElement(cls), propertyName, fieldName, myAccessDirection);
|
||||
PyUtil.addElementToStatementList(property, cls.getStatementList(), myAccessDirection == AccessDirection.READ);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,7 +42,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.CharsetEncoder;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Deque;
|
||||
import java.util.Formatter;
|
||||
|
||||
@@ -291,6 +290,24 @@ public class PyElementGeneratorImpl extends PyElementGenerator {
|
||||
return createFromText(languageLevel, PyImportElement.class, "from foo import " + name, new int[]{0, 6});
|
||||
}
|
||||
|
||||
@Override
|
||||
public PyFunction createProperty(LanguageLevel languageLevel,
|
||||
String propertyName,
|
||||
String fieldName,
|
||||
AccessDirection accessDirection) {
|
||||
String propertyText;
|
||||
if (accessDirection == AccessDirection.DELETE) {
|
||||
propertyText = "@" + propertyName +".deleter\ndef " + propertyName + "(self):\n del self." + fieldName;
|
||||
}
|
||||
else if (accessDirection == AccessDirection.WRITE) {
|
||||
propertyText = "@" + propertyName + ".setter\ndef " + propertyName + "(self, value):\n self." + fieldName + " = value";
|
||||
}
|
||||
else {
|
||||
propertyText = "@property\ndef " + propertyName + "(self):\n return self." + fieldName;
|
||||
}
|
||||
return createFromText(languageLevel, PyFunction.class, propertyText);
|
||||
}
|
||||
|
||||
static final int[] FROM_ROOT = new int[]{0};
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
|
||||
class A:
|
||||
@property
|
||||
def x(self):
|
||||
return self._x
|
||||
|
||||
def __init__(self):
|
||||
self._x = 1
|
||||
|
||||
def _foo(self):
|
||||
print(self._x)
|
||||
|
||||
@property
|
||||
def x(self):
|
||||
return self._x
|
||||
|
||||
|
||||
a = A()
|
||||
a._foo()
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
|
||||
class C(object):
|
||||
def __init__(self):
|
||||
self._x = None
|
||||
|
||||
@property
|
||||
def x(self):
|
||||
"""I'm the 'x' property."""
|
||||
return self._x
|
||||
|
||||
|
||||
c = C()
|
||||
print(c.x)
|
||||
del <warning descr="Property 'x' cannot be deleted">c.<caret>x</warning>
|
||||
|
||||
<warning descr="Property 'x' cannot be set">c.x</warning> = 1
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
class C(object):
|
||||
def __init__(self):
|
||||
self._x = None
|
||||
|
||||
@property
|
||||
def x(self):
|
||||
"""I'm the 'x' property."""
|
||||
return self._x
|
||||
|
||||
@x.deleter
|
||||
def x(self):
|
||||
del self._x
|
||||
|
||||
|
||||
c = C()
|
||||
print(c.x)
|
||||
del c.x
|
||||
|
||||
c.x = 1
|
||||
@@ -0,0 +1,14 @@
|
||||
|
||||
class C(object):
|
||||
def __init__(self):
|
||||
self._x = None
|
||||
|
||||
@x.setter
|
||||
def x(self, value):
|
||||
self._x = value
|
||||
|
||||
c = C()
|
||||
print(<warning descr="Property 'x' cannot be read">c.<caret>x</warning>)
|
||||
del <warning descr="Property 'x' cannot be deleted">c.x</warning>
|
||||
|
||||
c.x = 1
|
||||
@@ -0,0 +1,18 @@
|
||||
|
||||
class C(object):
|
||||
@property
|
||||
def x(self):
|
||||
return self._x
|
||||
|
||||
def __init__(self):
|
||||
self._x = None
|
||||
|
||||
@x.setter
|
||||
def x(self, value):
|
||||
self._x = value
|
||||
|
||||
c = C()
|
||||
print(c.x)
|
||||
del c.x
|
||||
|
||||
c.x = 1
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
class C(object):
|
||||
def __init__(self):
|
||||
self._x = None
|
||||
|
||||
@property
|
||||
def x(self):
|
||||
"""I'm the 'x' property."""
|
||||
return self._x
|
||||
|
||||
c = C()
|
||||
print(c.x)
|
||||
del <warning descr="Property 'x' cannot be deleted">c.x</warning>
|
||||
|
||||
<warning descr="Property 'x' cannot be set">c.<caret>x</warning> = 1
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
class C(object):
|
||||
def __init__(self):
|
||||
self._x = None
|
||||
|
||||
@property
|
||||
def x(self):
|
||||
"""I'm the 'x' property."""
|
||||
return self._x
|
||||
|
||||
@x.setter
|
||||
def x(self, value):
|
||||
self._x = value
|
||||
|
||||
|
||||
c = C()
|
||||
print(c.x)
|
||||
del c.x
|
||||
|
||||
c.x = 1
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.testFramework.TestDataPath;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PyQuickFixTestCase;
|
||||
import com.jetbrains.python.inspections.PyPropertyAccessInspection;
|
||||
|
||||
@TestDataPath("$CONTENT_ROOT/../testData/quickFixes/PyCreatePropertyQuickFixTest")
|
||||
public class PyCreatePropertyQuickFixTest extends PyQuickFixTestCase {
|
||||
public void testSetter() {
|
||||
doQuickFixTest(PyPropertyAccessInspection.class, PyBundle.message("QFIX.create.property"));
|
||||
}
|
||||
|
||||
public void testDeleter() {
|
||||
doQuickFixTest(PyPropertyAccessInspection.class, PyBundle.message("QFIX.create.property"));
|
||||
}
|
||||
|
||||
public void testGetter() {
|
||||
doQuickFixTest(PyPropertyAccessInspection.class, PyBundle.message("QFIX.create.property"));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user