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:
@@ -389,6 +389,7 @@
|
||||
<xml.xmlExtension implementation="com.jetbrains.pyramid.templates.highlighting.ChameleonXmlExtension" order="first"/>
|
||||
<highlightErrorFilter implementation="com.jetbrains.pyramid.templates.highlighting.ChameleonErrorFilter"/>
|
||||
<psi.fileReferenceHelper implementation="com.jetbrains.pyramid.templates.ref.PyramidStaticFileReferenceHelper"/>
|
||||
<lang.commenter language="Chameleon" implementationClass="com.jetbrains.pyramid.templates.editor.ChameleonCommenter"/>
|
||||
</extensions>
|
||||
|
||||
<extensionPoints>
|
||||
|
||||
@@ -39,7 +39,9 @@ public class PyParameterInfoHandler implements ParameterInfoHandler<PyArgumentLi
|
||||
public PyArgumentList findElementForParameterInfo(final CreateParameterInfoContext context) {
|
||||
PyArgumentList arglist = findArgumentList(context);
|
||||
if (arglist != null) {
|
||||
CallArgumentsMapping result = arglist.analyzeCall(PyResolveContext.noImplicits());
|
||||
final TypeEvalContext typeEvalContext = TypeEvalContext.userInitiated(arglist.getContainingFile());
|
||||
final PyResolveContext resolveContext = PyResolveContext.noImplicits().withTypeEvalContext(typeEvalContext);
|
||||
CallArgumentsMapping result = arglist.analyzeCall(resolveContext);
|
||||
if (result.getMarkedCallee() != null) {
|
||||
context.setItemsToShow(new Object[] { result });
|
||||
return arglist;
|
||||
|
||||
@@ -3,18 +3,20 @@ package com.jetbrains.python.inspections;
|
||||
import com.intellij.codeInspection.LocalInspectionToolSession;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.inspections.quickfix.AddMethodQuickFix;
|
||||
import com.jetbrains.python.psi.PyClass;
|
||||
import com.jetbrains.python.psi.PyExpression;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
import com.jetbrains.python.psi.types.PyClassLikeType;
|
||||
import com.jetbrains.python.psi.types.PyClassType;
|
||||
import com.jetbrains.python.psi.types.PyClassTypeImpl;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* User: ktisha
|
||||
* See pylint W0232
|
||||
@@ -42,12 +44,14 @@ public class PyClassHasNoInitInspection extends PyInspection {
|
||||
|
||||
@Override
|
||||
public void visitPyClass(PyClass node) {
|
||||
final PyExpression[] classes = node.getSuperClassExpressions();
|
||||
for (PyExpression pyClass : classes) {
|
||||
final PsiReference reference = pyClass.getReference();
|
||||
if (reference == null || reference.resolve() == null) return;
|
||||
if (reference.getCanonicalText().contains(PyNames.TEST_CASE)) return;
|
||||
final List<PyClassLikeType> types = node.getSuperClassTypes(myTypeEvalContext);
|
||||
for (PyClassLikeType type : types) {
|
||||
if (type == null) return;
|
||||
final String qName = type.getClassQName();
|
||||
if (qName != null && qName.contains(PyNames.TEST_CASE)) return;
|
||||
if (!(type instanceof PyClassType)) return;
|
||||
}
|
||||
|
||||
final PyFunction init = node.findInitOrNew(true);
|
||||
if (init == null) {
|
||||
registerProblem(node.getNameIdentifier(), PyBundle.message("INSP.class.has.no.init"),
|
||||
|
||||
@@ -62,6 +62,7 @@ public class PyOldStyleClassesInspection extends PyInspection {
|
||||
if (klass != null && !klass.isNewStyleClass()) {
|
||||
final List<PyClassLikeType> types = klass.getSuperClassTypes(myTypeEvalContext);
|
||||
for (PyClassLikeType type : types) {
|
||||
if (type == null) return;
|
||||
final String qName = type.getClassQName();
|
||||
if (qName != null && qName.contains("PyQt")) return;
|
||||
if (!(type instanceof PyClassType)) return;
|
||||
|
||||
@@ -79,12 +79,12 @@ public class CallArgumentsMappingImpl implements CallArgumentsMapping {
|
||||
PyNamedParameter kwd_par = null; // **param
|
||||
PyNamedParameter tuple_par = null; // *param
|
||||
Set<PyExpression> mapped_args = new HashSet<PyExpression>();
|
||||
final int implicit_offset = resolved_callee.getImplicitOffset();
|
||||
final int implicitOffset = resolved_callee.getImplicitOffset();
|
||||
int positional_index = 0; // up to this index parameters are positional
|
||||
// check positional arguments, fill slots
|
||||
int i = 0;
|
||||
for (PyParameter par : parameters) {
|
||||
if (tuple_par == null && kwd_par == null && positional_index < implicit_offset) {
|
||||
if (tuple_par == null && kwd_par == null && positional_index < implicitOffset) {
|
||||
positional_index += 1;
|
||||
continue;
|
||||
}
|
||||
@@ -107,14 +107,14 @@ public class CallArgumentsMappingImpl implements CallArgumentsMapping {
|
||||
i += 1;
|
||||
}
|
||||
// rule out 'self' or other implicit params
|
||||
for (i=0; i < implicit_offset && i < parameters.size(); i+=1) {
|
||||
for (i=0; i < implicitOffset && i < parameters.size(); i+=1) {
|
||||
slots.remove(parameters.get(i).getAsNamed());
|
||||
positional_index += 1;
|
||||
}
|
||||
// now params to the left of positional_index are positional.
|
||||
// map positional args to positional params.
|
||||
// we assume that implicitly skipped parameters are never nested tuples. no idea when they could ever be.
|
||||
int cnt = implicit_offset;
|
||||
int cnt = implicitOffset;
|
||||
int positional_bound = arguments.length; // to the right of this pos args are verboten
|
||||
ListIterator<PyExpression> unmatched_arg_iter = unmatched_args.listIterator();
|
||||
while (unmatched_arg_iter.hasNext()) {
|
||||
@@ -290,10 +290,12 @@ public class CallArgumentsMappingImpl implements CallArgumentsMapping {
|
||||
}
|
||||
// map unmapped named params to **kwarg
|
||||
if (myKwdArg != null) {
|
||||
for (PyParameter par : parameters) {
|
||||
PyNamedParameter n_par = par.getAsNamed();
|
||||
if (n_par != null && !n_par.isKeywordContainer() && !n_par.isPositionalContainer() && slots.get(n_par) == null) {
|
||||
slots.put(n_par, myKwdArg);
|
||||
for (int j = implicitOffset; j != parameters.size(); ++j) {
|
||||
final PyParameter par = parameters.get(j);
|
||||
final PyNamedParameter namedParameter = par.getAsNamed();
|
||||
if (namedParameter != null && !namedParameter.isKeywordContainer()
|
||||
&& !namedParameter.isPositionalContainer() && slots.get(namedParameter) == null) {
|
||||
slots.put(namedParameter, myKwdArg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
class A:
|
||||
def foo(self, e):
|
||||
self.kw = {}
|
||||
self.add_comm(**self<arg1>.kw)
|
||||
|
||||
|
||||
def add_comm(self, **kw):
|
||||
self.kw = []
|
||||
|
||||
@@ -132,6 +132,11 @@ public class PyParameterInfoTest extends LightMarkedTestCase {
|
||||
feignCtrlP(marks.get("<arg2a>").getTextOffset()).check("a, b, c", new String[]{"b, ","c"});
|
||||
}
|
||||
|
||||
public void testKwdArgInClass() {
|
||||
Map<String, PsiElement> marks = loadTest(1);
|
||||
feignCtrlP(marks.get("<arg1>").getTextOffset()).check("self, **kw", new String[]{"**kw"}, new String[]{"self, "});
|
||||
}
|
||||
|
||||
public void testKwdArgOutOfOrder() {
|
||||
Map<String, PsiElement> marks = loadTest(3);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user