use of com.jetbrains.python.psi.types.PyType in project intellij-community by JetBrains.
the class AddFunctionQuickFix method applyFix.
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
try {
final PsiElement problemElement = descriptor.getPsiElement();
if (!(problemElement instanceof PyQualifiedExpression))
return;
final PyExpression qualifier = ((PyQualifiedExpression) problemElement).getQualifier();
if (qualifier == null)
return;
final PyType type = TypeEvalContext.userInitiated(problemElement.getProject(), problemElement.getContainingFile()).getType(qualifier);
if (!(type instanceof PyModuleType))
return;
final PyFile file = ((PyModuleType) type).getModule();
sure(file);
sure(FileModificationService.getInstance().preparePsiElementForWrite(file));
// try to at least match parameter count
// TODO: get parameter style from code style
PyFunctionBuilder builder = new PyFunctionBuilder(myIdentifier, problemElement);
PsiElement problemParent = problemElement.getParent();
if (problemParent instanceof PyCallExpression) {
PyArgumentList arglist = ((PyCallExpression) problemParent).getArgumentList();
if (arglist == null)
return;
final PyExpression[] args = arglist.getArguments();
for (PyExpression arg : args) {
if (arg instanceof PyKeywordArgument) {
// foo(bar) -> def foo(bar_1)
builder.parameter(((PyKeywordArgument) arg).getKeyword());
} else if (arg instanceof PyReferenceExpression) {
PyReferenceExpression refex = (PyReferenceExpression) arg;
builder.parameter(refex.getReferencedName());
} else {
// use a boring name
builder.parameter("param");
}
}
} else if (problemParent != null) {
for (PyInspectionExtension extension : Extensions.getExtensions(PyInspectionExtension.EP_NAME)) {
List<String> params = extension.getFunctionParametersFromUsage(problemElement);
if (params != null) {
for (String param : params) {
builder.parameter(param);
}
break;
}
}
}
// else: no arglist, use empty args
PyFunction function = builder.buildFunction(project, LanguageLevel.forElement(file));
// add to the bottom
function = (PyFunction) file.add(function);
showTemplateBuilder(function, file);
} catch (IncorrectOperationException ignored) {
// we failed. tell about this
PyUtil.showBalloon(project, PyBundle.message("QFIX.failed.to.add.function"), MessageType.ERROR);
}
}
use of com.jetbrains.python.psi.types.PyType in project intellij-community by JetBrains.
the class PyUsageTypeProvider method getUsageType.
public UsageType getUsageType(PsiElement element, @NotNull UsageTarget[] targets) {
if (element instanceof PyElement) {
if (PsiTreeUtil.getParentOfType(element, PyImportStatementBase.class) != null) {
return IN_IMPORT;
}
if (element instanceof PyQualifiedExpression) {
final PyExpression qualifier = ((PyQualifiedExpression) element).getQualifier();
if (qualifier != null) {
final TypeEvalContext context = TypeEvalContext.userInitiated(element.getProject(), element.getContainingFile());
final PyType type = context.getType(qualifier);
if (type == null || type instanceof PyStructuralType) {
return UNTYPED;
}
}
}
if (element instanceof PyReferenceExpression) {
final PyCallExpression call = PsiTreeUtil.getParentOfType(element, PyCallExpression.class);
if (call != null && call.isCalleeText(PyNames.ISINSTANCE)) {
final PyExpression[] args = call.getArguments();
if (args.length == 2) {
PyExpression typeExpression = args[1];
if (element == typeExpression) {
return USAGE_IN_ISINSTANCE;
}
typeExpression = PyPsiUtils.flattenParens(typeExpression);
if (typeExpression instanceof PySequenceExpression && element.getParent() == typeExpression) {
return USAGE_IN_ISINSTANCE;
}
}
}
final PyClass pyClass = PsiTreeUtil.getParentOfType(element, PyClass.class);
if (pyClass != null && PsiTreeUtil.isAncestor(pyClass.getSuperClassExpressionList(), element, true)) {
return USAGE_IN_SUPERCLASS;
}
}
}
return null;
}
use of com.jetbrains.python.psi.types.PyType in project intellij-community by JetBrains.
the class PyDictKeyNamesCompletionContributor method addDictConstructorKeys.
/**
* add keys to completion result from dict constructor
*/
private static void addDictConstructorKeys(final PyCallExpression dictConstructor, final CompletionResultSet result) {
final PyExpression callee = dictConstructor.getCallee();
if (callee == null)
return;
final String name = callee.getText();
if ("dict".equals(name)) {
final TypeEvalContext context = TypeEvalContext.codeCompletion(callee.getProject(), callee.getContainingFile());
final PyType type = context.getType(dictConstructor);
if (type != null && type.isBuiltin()) {
final PyArgumentList list = dictConstructor.getArgumentList();
if (list == null)
return;
final PyExpression[] argumentList = list.getArguments();
for (final PyExpression argument : argumentList) {
if (argument instanceof PyKeywordArgument) {
result.addElement(createElement("'" + ((PyKeywordArgument) argument).getKeyword() + "'"));
}
}
}
}
}
use of com.jetbrains.python.psi.types.PyType in project intellij-community by JetBrains.
the class IntroduceHandler method generateSuggestedNames.
protected Collection<String> generateSuggestedNames(PyExpression expression) {
Collection<String> candidates = new LinkedHashSet<String>() {
@Override
public boolean add(String s) {
if (PyNames.isReserved(s)) {
return false;
}
return super.add(s);
}
};
String text = expression.getText();
final Pair<PsiElement, TextRange> selection = expression.getUserData(PyReplaceExpressionUtil.SELECTION_BREAKS_AST_NODE);
if (selection != null) {
text = selection.getSecond().substring(selection.getFirst().getText());
}
if (expression instanceof PyCallExpression) {
final PyExpression callee = ((PyCallExpression) expression).getCallee();
if (callee != null) {
text = callee.getText();
}
}
if (text != null) {
candidates.addAll(NameSuggesterUtil.generateNames(text));
}
final TypeEvalContext context = TypeEvalContext.userInitiated(expression.getProject(), expression.getContainingFile());
PyType type = context.getType(expression);
if (type != null && type != PyNoneType.INSTANCE) {
String typeName = type.getName();
if (typeName != null) {
if (type.isBuiltin()) {
typeName = typeName.substring(0, 1);
}
candidates.addAll(NameSuggesterUtil.generateNamesByType(typeName));
}
}
final PyKeywordArgument kwArg = PsiTreeUtil.getParentOfType(expression, PyKeywordArgument.class);
if (kwArg != null && kwArg.getValueExpression() == expression) {
candidates.add(kwArg.getKeyword());
}
Optional.ofNullable(PsiTreeUtil.getParentOfType(expression, PyArgumentList.class)).map(PyArgumentList::getCallExpression).ifPresent(call -> StreamEx.of(call.multiMapArguments(PyResolveContext.noImplicits())).map(mapping -> mapping.getMappedParameters().get(expression)).nonNull().map(PyNamedParameter::getName).forEach(candidates::add));
return candidates;
}
use of com.jetbrains.python.psi.types.PyType in project intellij-community by JetBrains.
the class NumpyDocStringTypeProvider method getCallType.
@Nullable
@Override
public Ref<PyType> getCallType(@NotNull PyFunction function, @Nullable PyCallSiteExpression callSite, @NotNull TypeEvalContext context) {
if (isApplicable(function)) {
final PyExpression callee = callSite instanceof PyCallExpression ? ((PyCallExpression) callSite).getCallee() : null;
final NumpyDocString docString = forFunction(function, callee);
if (docString != null) {
final List<SectionField> returns = docString.getReturnFields();
final PyPsiFacade facade = getPsiFacade(function);
switch(returns.size()) {
case 0:
return null;
case 1:
// Function returns single value
return Optional.ofNullable(returns.get(0).getType()).filter(StringUtil::isNotEmpty).map(typeName -> isUfuncType(function, typeName) ? facade.parseTypeAnnotation("T", function) : parseNumpyDocType(function, typeName)).map(Ref::create).orElse(null);
default:
// Function returns a tuple
final List<PyType> unionMembers = new ArrayList<>();
final List<PyType> members = new ArrayList<>();
for (int i = 0; i < returns.size(); i++) {
final String memberTypeName = returns.get(i).getType();
final PyType returnType = StringUtil.isNotEmpty(memberTypeName) ? parseNumpyDocType(function, memberTypeName) : null;
final boolean isOptional = StringUtil.isNotEmpty(memberTypeName) && memberTypeName.contains("optional");
if (isOptional && i != 0) {
if (members.size() > 1) {
unionMembers.add(facade.createTupleType(members, function));
} else if (members.size() == 1) {
unionMembers.add(members.get(0));
}
}
members.add(returnType);
if (i == returns.size() - 1 && isOptional) {
unionMembers.add(facade.createTupleType(members, function));
}
}
final PyType type = unionMembers.isEmpty() ? facade.createTupleType(members, function) : facade.createUnionType(unionMembers);
return Ref.create(type);
}
}
}
return null;
}
Aggregations