mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Missing type hints inspection
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<body>
|
||||
<span style="font-family: verdana,serif;">
|
||||
This inspection detects lack of type hints for function declaration in
|
||||
one of the two formats: parameter annotations or a type comment
|
||||
</body>
|
||||
</html>
|
||||
@@ -380,6 +380,8 @@
|
||||
<localInspection language="Python" shortName="PyPep8NamingInspection" suppressId="PyPep8Naming" displayName="PEP 8 naming convention violation" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WEAK WARNING" implementationClass="com.jetbrains.python.inspections.PyPep8NamingInspection"/>
|
||||
<localInspection language="Python" shortName="PyAssignmentToLoopOrWithParameterInspection" suppressId="PyAssignmentToLoopOrWithParameter" displayName="Assignment to 'for' loop or 'with' statement parameter" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WEAK WARNING" implementationClass="com.jetbrains.python.inspections.PyAssignmentToLoopOrWithParameterInspection"/>
|
||||
|
||||
<localInspection language="Python" shortName="PyMissingTypeHintsInspection" suppressId="PyMissingTypeHints" displayName="Type hinting is missing for function definition" groupKey="INSP.GROUP.python" enabledByDefault="false" level="WEAK WARNING" implementationClass="com.jetbrains.python.inspections.PyMissingTypeHintsInspection"/>
|
||||
|
||||
<defaultLiveTemplatesProvider implementation="com.jetbrains.python.codeInsight.liveTemplates.PyDefaultLiveTemplatesProvider"/>
|
||||
<liveTemplateContext implementation="com.jetbrains.python.codeInsight.liveTemplates.PythonTemplateContextType$General"/>
|
||||
<liveTemplateContext implementation="com.jetbrains.python.codeInsight.liveTemplates.PythonTemplateContextType$Class"/>
|
||||
|
||||
+14
-8
@@ -82,17 +82,21 @@ public class PyAnnotateTypesIntention implements IntentionAction {
|
||||
final PsiElement elementAt = PyUtil.findNonWhitespaceAtOffset(file, editor.getCaretModel().getOffset());
|
||||
final PyCallable callable = getCallable(elementAt);
|
||||
|
||||
if (isPy3k(file)) {
|
||||
generatePy3kTypeAnnotations(project, editor, elementAt, callable);
|
||||
annotateTypes(editor, callable);
|
||||
}
|
||||
|
||||
public static void annotateTypes(Editor editor, PyCallable callable) {
|
||||
if (isPy3k(callable.getContainingFile())) {
|
||||
generatePy3kTypeAnnotations(callable.getProject(), editor, callable);
|
||||
}
|
||||
else {
|
||||
if (callable instanceof PyFunction) {
|
||||
generateTypeCommentAnnotations(project, editor, elementAt, (PyFunction)callable);
|
||||
generateTypeCommentAnnotations(callable.getProject(), (PyFunction)callable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void generateTypeCommentAnnotations(Project project, Editor editor, PsiElement at, PyFunction function) {
|
||||
private static void generateTypeCommentAnnotations(Project project, PyFunction function) {
|
||||
|
||||
StringBuilder replacementTextBuilder = new StringBuilder("# type: (");
|
||||
|
||||
@@ -181,13 +185,15 @@ public class PyAnnotateTypesIntention implements IntentionAction {
|
||||
return LanguageLevel.forElement(file).isPy3K();
|
||||
}
|
||||
|
||||
private static void generatePy3kTypeAnnotations(@NotNull Project project, Editor editor, PsiElement elementAt, PyCallable callable) {
|
||||
private static void generatePy3kTypeAnnotations(@NotNull Project project, Editor editor, PyCallable callable) {
|
||||
final TemplateBuilder builder = TemplateBuilderFactory.getInstance().createTemplateBuilder(callable);
|
||||
|
||||
PyExpression returnType = annotateReturnType(project, editor.getDocument(), elementAt, false);
|
||||
if (callable instanceof PyFunction) {
|
||||
PyExpression returnType = annotateReturnType(project, (PyFunction) callable, false);
|
||||
|
||||
if (returnType != null) {
|
||||
builder.replaceElement(returnType, returnType.getText());
|
||||
if (returnType != null) {
|
||||
builder.replaceElement(returnType, returnType.getText());
|
||||
}
|
||||
}
|
||||
|
||||
if (callable instanceof PyFunction) {
|
||||
|
||||
+50
-56
@@ -76,14 +76,17 @@ public class SpecifyTypeInPy3AnnotationsIntention extends TypeIntention {
|
||||
annotateParameter(project, editor, parameter, true);
|
||||
}
|
||||
else {
|
||||
annotateReturnType(project, editor.getDocument(), elementAt, true);
|
||||
PyCallable callable = getCallable(elementAt);
|
||||
if (callable instanceof PyFunction) {
|
||||
annotateReturnType(project, (PyFunction)callable, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static PyNamedParameter annotateParameter(Project project,
|
||||
Editor editor,
|
||||
@NotNull PyNamedParameter parameter,
|
||||
boolean createTemplate) {
|
||||
Editor editor,
|
||||
@NotNull PyNamedParameter parameter,
|
||||
boolean createTemplate) {
|
||||
final PyExpression defaultParamValue = parameter.getDefaultValue();
|
||||
|
||||
final String paramName = StringUtil.notNullize(parameter.getName());
|
||||
@@ -93,7 +96,6 @@ public class SpecifyTypeInPy3AnnotationsIntention extends TypeIntention {
|
||||
|
||||
String paramType = parameterType(parameter);
|
||||
|
||||
|
||||
|
||||
final PyNamedParameter namedParameter = elementGenerator.createParameter(paramName, defaultParamText, paramType,
|
||||
LanguageLevel.forElement(parameter));
|
||||
@@ -119,7 +121,7 @@ public class SpecifyTypeInPy3AnnotationsIntention extends TypeIntention {
|
||||
|
||||
static String parameterType(PyParameter parameter) {
|
||||
String paramType = PyNames.OBJECT;
|
||||
|
||||
|
||||
PyFunction function = PsiTreeUtil.getParentOfType(parameter, PyFunction.class);
|
||||
if (function != null) {
|
||||
final PySignature signature = PySignatureCacheManager.getInstance(parameter.getProject()).findSignature(
|
||||
@@ -143,65 +145,57 @@ public class SpecifyTypeInPy3AnnotationsIntention extends TypeIntention {
|
||||
return returnType;
|
||||
}
|
||||
|
||||
public static PyExpression annotateReturnType(Project project, Document document, PsiElement resolved, boolean createTemplate) {
|
||||
PyCallable callable = getCallable(resolved);
|
||||
public static PyExpression annotateReturnType(Project project, PyFunction function, boolean createTemplate) {
|
||||
String returnType = returnType(function);
|
||||
|
||||
if (callable instanceof PyFunction) {
|
||||
PyFunction function = (PyFunction)callable;
|
||||
final String annotationText = " -> " + returnType;
|
||||
|
||||
String returnType = returnType(function);
|
||||
final PsiElement prevElem = PyPsiUtils.getPrevNonCommentSibling(function.getStatementList(), true);
|
||||
assert prevElem != null;
|
||||
|
||||
final String annotationText = " -> " + returnType;
|
||||
|
||||
final PsiElement prevElem = PyPsiUtils.getPrevNonCommentSibling(((PyFunction)callable).getStatementList(), true);
|
||||
assert prevElem != null;
|
||||
|
||||
final PsiDocumentManager manager = PsiDocumentManager.getInstance(project);
|
||||
Document documentWithCallable = manager.getDocument(callable.getContainingFile());
|
||||
if (documentWithCallable != null) {
|
||||
try {
|
||||
final TextRange range = prevElem.getTextRange();
|
||||
manager.doPostponedOperationsAndUnblockDocument(documentWithCallable);
|
||||
if (prevElem.getNode().getElementType() == PyTokenTypes.COLON) {
|
||||
documentWithCallable.insertString(range.getStartOffset(), annotationText);
|
||||
}
|
||||
else {
|
||||
documentWithCallable.insertString(range.getEndOffset(), annotationText + ":");
|
||||
}
|
||||
final PsiDocumentManager manager = PsiDocumentManager.getInstance(project);
|
||||
Document documentWithCallable = manager.getDocument(function.getContainingFile());
|
||||
if (documentWithCallable != null) {
|
||||
try {
|
||||
final TextRange range = prevElem.getTextRange();
|
||||
manager.doPostponedOperationsAndUnblockDocument(documentWithCallable);
|
||||
if (prevElem.getNode().getElementType() == PyTokenTypes.COLON) {
|
||||
documentWithCallable.insertString(range.getStartOffset(), annotationText);
|
||||
}
|
||||
finally {
|
||||
manager.commitDocument(documentWithCallable);
|
||||
else {
|
||||
documentWithCallable.insertString(range.getEndOffset(), annotationText + ":");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
callable = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(callable);
|
||||
final PyAnnotation annotation = ((PyFunction)callable).getAnnotation();
|
||||
assert annotation != null;
|
||||
final PyExpression annotationValue = annotation.getValue();
|
||||
assert annotationValue != null : "Generated function must have annotation";
|
||||
|
||||
if (createTemplate) {
|
||||
final int offset = annotationValue.getTextOffset();
|
||||
|
||||
final TemplateBuilder builder = TemplateBuilderFactory.getInstance().createTemplateBuilder(annotationValue);
|
||||
builder.replaceRange(TextRange.create(0, returnType.length()), returnType);
|
||||
final Template template = ((TemplateBuilderImpl)builder).buildInlineTemplate();
|
||||
final OpenFileDescriptor descriptor = new OpenFileDescriptor(
|
||||
project,
|
||||
callable.getContainingFile().getVirtualFile(),
|
||||
offset
|
||||
);
|
||||
final Editor targetEditor = FileEditorManager.getInstance(project).openTextEditor(descriptor, true);
|
||||
if (targetEditor != null) {
|
||||
targetEditor.getCaretModel().moveToOffset(offset);
|
||||
TemplateManager.getInstance(project).startTemplate(targetEditor, template);
|
||||
}
|
||||
finally {
|
||||
manager.commitDocument(documentWithCallable);
|
||||
}
|
||||
return annotationValue;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
function = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(function);
|
||||
final PyAnnotation annotation = function.getAnnotation();
|
||||
assert annotation != null;
|
||||
final PyExpression annotationValue = annotation.getValue();
|
||||
assert annotationValue != null : "Generated function must have annotation";
|
||||
|
||||
if (createTemplate) {
|
||||
final int offset = annotationValue.getTextOffset();
|
||||
|
||||
final TemplateBuilder builder = TemplateBuilderFactory.getInstance().createTemplateBuilder(annotationValue);
|
||||
builder.replaceRange(TextRange.create(0, returnType.length()), returnType);
|
||||
final Template template = ((TemplateBuilderImpl)builder).buildInlineTemplate();
|
||||
final OpenFileDescriptor descriptor = new OpenFileDescriptor(
|
||||
project,
|
||||
function.getContainingFile().getVirtualFile(),
|
||||
offset
|
||||
);
|
||||
final Editor targetEditor = FileEditorManager.getInstance(project).openTextEditor(descriptor, true);
|
||||
if (targetEditor != null) {
|
||||
targetEditor.getCaretModel().moveToOffset(offset);
|
||||
TemplateManager.getInstance(project).startTemplate(targetEditor, template);
|
||||
}
|
||||
}
|
||||
return annotationValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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;
|
||||
|
||||
import com.intellij.codeInspection.LocalInspectionToolSession;
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.codeInsight.intentions.PyAnnotateTypesIntention;
|
||||
import com.jetbrains.python.inspections.quickfix.PyQuickFixUtil;
|
||||
import com.jetbrains.python.psi.PyElementVisitor;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
import com.jetbrains.python.psi.PyNamedParameter;
|
||||
import com.jetbrains.python.psi.PyParameter;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author traff
|
||||
*/
|
||||
public class PyMissingTypeHintsInspection extends PyInspection{
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly, @NotNull LocalInspectionToolSession session) {
|
||||
return new PyElementVisitor() {
|
||||
@Override
|
||||
public void visitPyFunction(PyFunction function) {
|
||||
if (!(typeCommentExists(function) || typeAnnotationsExist(function))) {
|
||||
ASTNode nameNode = function.getNameNode();
|
||||
if (nameNode != null) {
|
||||
holder.registerProblem(nameNode.getPsi(), "Type hinting is missing for function definition", new AddTypeHintsQuickFix(function));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static boolean typeCommentExists(PyFunction function) {
|
||||
ASTNode node = function.getStatementList().getNode().getFirstChildNode();
|
||||
|
||||
while (node != null && node.getElementType() != PyTokenTypes.END_OF_LINE_COMMENT) {
|
||||
node = node.getTreeNext();
|
||||
}
|
||||
if (node != null) {
|
||||
return isTypeComment(node);
|
||||
}
|
||||
|
||||
node = function.getStatementList().getPrevSibling().getNode();
|
||||
|
||||
while (node != null && node.getElementType() != PyTokenTypes.COLON && node.getElementType() != PyTokenTypes.END_OF_LINE_COMMENT) {
|
||||
node = node.getTreePrev();
|
||||
}
|
||||
|
||||
if (node != null && node.getElementType() == PyTokenTypes.END_OF_LINE_COMMENT) {
|
||||
return isTypeComment(node);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isTypeComment(ASTNode node) {
|
||||
String commentText = node.getText();
|
||||
int startInd = commentText.indexOf('#');
|
||||
if (startInd != -1) {
|
||||
commentText = commentText.substring(startInd+1).trim();
|
||||
if (commentText.startsWith("type:")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean typeAnnotationsExist(PyFunction function) {
|
||||
for (PyParameter param: function.getParameterList().getParameters()) {
|
||||
PyNamedParameter namedParameter = param.getAsNamed();
|
||||
if (namedParameter != null) {
|
||||
if (namedParameter.getAnnotation() != null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (function.getAnnotation() != null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static class AddTypeHintsQuickFix implements LocalQuickFix {
|
||||
private PyFunction myFunction;
|
||||
|
||||
public AddTypeHintsQuickFix(@NotNull PyFunction function) {
|
||||
myFunction = function;
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Add type hinting for '" + myFunction.getName() + "'";
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "Add type hinting";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
PyAnnotateTypesIntention.annotateTypes(PyQuickFixUtil.getEditor(myFunction), myFunction);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,12 +17,7 @@ package com.jetbrains.python.inspections.quickfix;
|
||||
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.EditorFactory;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.SmartPointerManager;
|
||||
import com.intellij.psi.SmartPsiElementPointer;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
@@ -73,20 +68,6 @@ public class DocstringQuickFix implements LocalQuickFix {
|
||||
return "Fix docstring";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Editor getEditor(@NotNull PsiElement element) {
|
||||
Document document = PsiDocumentManager.getInstance(element.getProject()).getDocument(element.getContainingFile());
|
||||
if (document != null) {
|
||||
final EditorFactory instance = EditorFactory.getInstance();
|
||||
if (instance == null) return null;
|
||||
Editor[] editors = instance.getEditors(document);
|
||||
if (editors.length > 0) {
|
||||
return editors[0];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
PyDocStringOwner docStringOwner = PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PyDocStringOwner.class);
|
||||
if (docStringOwner == null) return;
|
||||
@@ -113,7 +94,7 @@ public class DocstringQuickFix implements LocalQuickFix {
|
||||
private static void addEmptyDocstring(@NotNull PyDocStringOwner docStringOwner) {
|
||||
if (docStringOwner instanceof PyFunction ||
|
||||
docStringOwner instanceof PyClass && ((PyClass)docStringOwner).findInitOrNew(false, null) != null) {
|
||||
PyGenerateDocstringIntention.generateDocstring(docStringOwner, getEditor(docStringOwner));
|
||||
PyGenerateDocstringIntention.generateDocstring(docStringOwner, PyQuickFixUtil.getEditor(docStringOwner));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-19
@@ -17,11 +17,8 @@ package com.jetbrains.python.inspections.quickfix;
|
||||
|
||||
import com.intellij.codeInspection.LocalQuickFixOnPsiElement;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.EditorFactory;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
@@ -31,7 +28,6 @@ import com.jetbrains.python.psi.PyClass;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Set;
|
||||
@@ -62,7 +58,7 @@ public class PyImplementMethodsQuickFix extends LocalQuickFixOnPsiElement {
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, @NotNull PsiFile file, @NotNull PsiElement startElement, @NotNull PsiElement endElement) {
|
||||
final Editor editor = getEditor(project, file);
|
||||
final Editor editor = PyQuickFixUtil.getEditor(file);
|
||||
|
||||
if (editor != null && startElement instanceof PyClass) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
@@ -81,18 +77,4 @@ public class PyImplementMethodsQuickFix extends LocalQuickFixOnPsiElement {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Editor getEditor(Project project, PsiFile file) {
|
||||
Document document = PsiDocumentManager.getInstance(project).getDocument(file);
|
||||
if (document != null) {
|
||||
final EditorFactory instance = EditorFactory.getInstance();
|
||||
if (instance == null) return null;
|
||||
Editor[] editors = instance.getEditors(document);
|
||||
if (editors.length > 0) {
|
||||
return editors[0];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.EditorFactory;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author traff
|
||||
*/
|
||||
public class PyQuickFixUtil {
|
||||
@Nullable
|
||||
public static Editor getEditor(@NotNull PsiElement element) {
|
||||
Document document = PsiDocumentManager.getInstance(element.getProject()).getDocument(element.getContainingFile());
|
||||
if (document != null) {
|
||||
final EditorFactory instance = EditorFactory.getInstance();
|
||||
if (instance == null) return null;
|
||||
Editor[] editors = instance.getEditors(document);
|
||||
if (editors.length > 0) {
|
||||
return editors[0];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
def <weak_warning descr="Type hinting is missing for function definition">foo</weak_warning>(x, y):
|
||||
pass
|
||||
@@ -0,0 +1,2 @@
|
||||
def foo(x: int, y: int) -> str:
|
||||
pass
|
||||
@@ -0,0 +1,3 @@
|
||||
def foo(x):
|
||||
# type: (int) -> int
|
||||
pass
|
||||
@@ -0,0 +1,2 @@
|
||||
def foo(x): # type: (int) -> int
|
||||
pass
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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;
|
||||
|
||||
import com.jetbrains.python.fixtures.PyTestCase;
|
||||
import com.jetbrains.python.psi.LanguageLevel;
|
||||
import com.jetbrains.python.psi.impl.PythonLanguageLevelPusher;
|
||||
|
||||
/**
|
||||
* @author traff
|
||||
*/
|
||||
public class PyMissingTypeHintsInspectionTest extends PyTestCase {
|
||||
public void testPy3kAnnotations() {
|
||||
doTest(LanguageLevel.PYTHON35);
|
||||
}
|
||||
|
||||
public void testNoAnnotations() {
|
||||
doTest(LanguageLevel.PYTHON35);
|
||||
}
|
||||
|
||||
public void testTypeComment() {
|
||||
doTest(LanguageLevel.PYTHON27);
|
||||
}
|
||||
|
||||
public void testTypeCommentOnTheSameLine() {
|
||||
doTest(LanguageLevel.PYTHON27);
|
||||
}
|
||||
|
||||
private void doTest(LanguageLevel languageLevel) {
|
||||
PythonLanguageLevelPusher.setForcedLanguageLevel(myFixture.getProject(), languageLevel);
|
||||
try {
|
||||
myFixture.configureByFile("inspections/PyMissingTypeHintsInspection/" + getTestName(true) + ".py");
|
||||
myFixture.enableInspections(PyMissingTypeHintsInspection.class);
|
||||
myFixture.checkHighlighting(false, false, true);
|
||||
}
|
||||
finally {
|
||||
PythonLanguageLevelPusher.setForcedLanguageLevel(myFixture.getProject(), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user