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:
@@ -56,11 +56,11 @@
|
||||
<orderEntry type="module" module-name="java-structure-view" exported="" />
|
||||
<orderEntry type="module" module-name="spellchecker" />
|
||||
<orderEntry type="library" name="nekohtml" level="project" />
|
||||
<orderEntry type="module" module-name="built-in-server" />
|
||||
</component>
|
||||
<component name="copyright">
|
||||
<Base>
|
||||
<setting name="state" value="1" />
|
||||
</Base>
|
||||
</component>
|
||||
</module>
|
||||
|
||||
</module>
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* 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.
|
||||
@@ -50,11 +50,14 @@ import com.intellij.psi.util.PsiFormatUtil;
|
||||
import com.intellij.psi.util.PsiFormatUtilBase;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.Url;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.builtInWebServer.BuiltInWebBrowserUrlProvider;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
@@ -684,7 +687,7 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static List<String> findUrlForClass(PsiClass aClass) {
|
||||
public static List<String> findUrlForClass(@NotNull PsiClass aClass) {
|
||||
String qName = aClass.getQualifiedName();
|
||||
if (qName == null) return null;
|
||||
|
||||
@@ -696,18 +699,18 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext
|
||||
|
||||
String packageName = ((PsiJavaFile)file).getPackageName();
|
||||
String relPath;
|
||||
if (packageName.length() > 0) {
|
||||
relPath = packageName.replace('.', '/') + '/' + qName.substring(packageName.length() + 1) + HTML_EXTENSION;
|
||||
if (packageName.isEmpty()) {
|
||||
relPath = qName + HTML_EXTENSION;
|
||||
}
|
||||
else {
|
||||
relPath = qName + HTML_EXTENSION;
|
||||
relPath = packageName.replace('.', '/') + '/' + qName.substring(packageName.length() + 1) + HTML_EXTENSION;
|
||||
}
|
||||
|
||||
return findUrlForVirtualFile(file.getProject(), virtualFile, relPath);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static List<String> findUrlForVirtualFile(final Project project, final VirtualFile virtualFile, final String relPath) {
|
||||
public static List<String> findUrlForVirtualFile(@NotNull Project project, @NotNull VirtualFile virtualFile, @NotNull String relPath) {
|
||||
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
|
||||
Module module = fileIndex.getModuleForFile(virtualFile);
|
||||
if (module == null) {
|
||||
@@ -728,11 +731,25 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext
|
||||
}
|
||||
}
|
||||
|
||||
final List<OrderEntry> orderEntries = fileIndex.getOrderEntriesForFile(virtualFile);
|
||||
for (OrderEntry orderEntry : orderEntries) {
|
||||
final String[] files = JavadocOrderRootType.getUrls(orderEntry);
|
||||
final List<String> httpRoot = PlatformDocumentationUtil.getHttpRoots(files, relPath);
|
||||
if (httpRoot != null) return httpRoot;
|
||||
for (OrderEntry orderEntry : fileIndex.getOrderEntriesForFile(virtualFile)) {
|
||||
for (VirtualFile root : orderEntry.getFiles(JavadocOrderRootType.getInstance())) {
|
||||
if (root.getFileSystem() == JarFileSystem.getInstance()) {
|
||||
VirtualFile file = root.findFileByRelativePath(relPath);
|
||||
List<Url> urls = file == null ? null : BuiltInWebBrowserUrlProvider.getUrls(file, project, null);
|
||||
if (!ContainerUtil.isEmpty(urls)) {
|
||||
List<String> result = new SmartList<String>();
|
||||
for (Url url : urls) {
|
||||
result.add(url.toExternalForm());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<String> httpRoot = PlatformDocumentationUtil.getHttpRoots(JavadocOrderRootType.getUrls(orderEntry), relPath);
|
||||
if (httpRoot != null) {
|
||||
return httpRoot;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
+57
-1
@@ -33,6 +33,8 @@ import com.intellij.openapi.util.NotNullLazyValue;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.JarFileSystem;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.PairFunction;
|
||||
import com.intellij.util.PlatformUtils;
|
||||
@@ -207,7 +209,8 @@ final class DefaultWebServerRootsProvider extends WebServerRootsProvider {
|
||||
DirectoryInfo info = directoryIndex.getInfoForFile(file);
|
||||
// we serve excluded files
|
||||
if (!info.isExcluded() && !info.isInProject()) {
|
||||
return null;
|
||||
// javadoc jars is "not under project", but actually is, so, let's check project library table
|
||||
return file.getFileSystem() == JarFileSystem.getInstance() ? getInfoForDocJar(file, project) : null;
|
||||
}
|
||||
|
||||
VirtualFile root = info.getSourceRoot();
|
||||
@@ -245,6 +248,59 @@ final class DefaultWebServerRootsProvider extends WebServerRootsProvider {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PathInfo getInfoForDocJar(@NotNull final VirtualFile file, @NotNull Project project) {
|
||||
final OrderRootType javaDocRootType = JavadocOrderRootType.getInstance();
|
||||
if (javaDocRootType == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
class LibraryProcessor implements Processor<Library> {
|
||||
PathInfo result;
|
||||
String moduleName;
|
||||
|
||||
@Override
|
||||
public boolean process(Library library) {
|
||||
for (VirtualFile root : library.getFiles(javaDocRootType)) {
|
||||
if (VfsUtilCore.isAncestor(root, file, false)) {
|
||||
result = new PathInfo(file, root, moduleName, true);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
LibraryProcessor processor = new LibraryProcessor();
|
||||
AccessToken token = ReadAction.start();
|
||||
try {
|
||||
ModuleManager moduleManager = ModuleManager.getInstance(project);
|
||||
for (Module module : moduleManager.getModules()) {
|
||||
if (module.isDisposed()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
processor.moduleName = module.getName();
|
||||
ModuleRootManager.getInstance(module).orderEntries().forEachLibrary(processor);
|
||||
if (processor.result != null) {
|
||||
return processor.result;
|
||||
}
|
||||
}
|
||||
|
||||
processor.moduleName = null;
|
||||
for (Library library : LibraryTablesRegistrar.getInstance().getLibraryTable(project).getLibraries()) {
|
||||
if (!processor.process(library)) {
|
||||
return processor.result;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
token.finish();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getModuleNameQualifier(@NotNull Project project, @Nullable Module module) {
|
||||
if (module != null &&
|
||||
|
||||
+12
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* 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.
|
||||
@@ -19,10 +19,11 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.openapi.vfs.ex.http.HttpFileSystem;
|
||||
import com.intellij.util.SmartList;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
@@ -30,7 +31,6 @@ import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
public class PlatformDocumentationUtil {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.documentation.PlatformDocumentationUtil");
|
||||
|
||||
private static final @NonNls Pattern ourLtFixupPattern = Pattern.compile("<([^/^\\w^!])");
|
||||
@@ -38,19 +38,23 @@ public class PlatformDocumentationUtil {
|
||||
private static final @NonNls String LT_ENTITY = "<";
|
||||
|
||||
@Nullable
|
||||
public static List<String> getHttpRoots(final String[] roots, String relPath) {
|
||||
final ArrayList<String> result = new ArrayList<String>();
|
||||
public static List<String> getHttpRoots(@NotNull String[] roots, String relPath) {
|
||||
List<String> result = new SmartList<String>();
|
||||
for (String root : roots) {
|
||||
final VirtualFile virtualFile = VirtualFileManager.getInstance().findFileByUrl(root);
|
||||
VirtualFile virtualFile = VirtualFileManager.getInstance().findFileByUrl(root);
|
||||
if (virtualFile != null) {
|
||||
if (virtualFile.getFileSystem() instanceof HttpFileSystem) {
|
||||
String url = virtualFile.getUrl();
|
||||
if (!url.endsWith("/")) url += "/";
|
||||
if (!url.endsWith("/")) {
|
||||
url += "/";
|
||||
}
|
||||
result.add(url + relPath);
|
||||
}
|
||||
else {
|
||||
VirtualFile file = virtualFile.findFileByRelativePath(relPath);
|
||||
if (file != null) result.add(file.getUrl());
|
||||
if (file != null) {
|
||||
result.add(file.getUrl());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+25
-23
@@ -705,33 +705,35 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
if (myElement != null) {
|
||||
final PsiElement element = myElement.getElement();
|
||||
final DocumentationProvider provider = DocumentationManager.getProviderFromElement(element);
|
||||
final PsiElement originalElement = DocumentationManager.getOriginalElement(element);
|
||||
boolean processed = false;
|
||||
if (provider instanceof CompositeDocumentationProvider) {
|
||||
for (DocumentationProvider p : ((CompositeDocumentationProvider)provider).getAllProviders()) {
|
||||
if (p instanceof ExternalDocumentationHandler && ((ExternalDocumentationHandler)p).handleExternal(element, originalElement)) {
|
||||
processed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (myElement == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!processed) {
|
||||
final Component component = PlatformDataKeys.CONTEXT_COMPONENT.getData(e.getDataContext());
|
||||
final List<String> urls;
|
||||
if (!StringUtil.isEmptyOrSpaces(myEffectiveExternalUrl)) {
|
||||
urls = Collections.singletonList(myEffectiveExternalUrl);
|
||||
} else {
|
||||
urls = provider.getUrlFor(element, originalElement);
|
||||
assert urls != null : provider;
|
||||
assert !urls.isEmpty() : provider;
|
||||
final PsiElement element = myElement.getElement();
|
||||
final DocumentationProvider provider = DocumentationManager.getProviderFromElement(element);
|
||||
final PsiElement originalElement = DocumentationManager.getOriginalElement(element);
|
||||
boolean processed = false;
|
||||
if (provider instanceof CompositeDocumentationProvider) {
|
||||
for (DocumentationProvider p : ((CompositeDocumentationProvider)provider).getAllProviders()) {
|
||||
if (p instanceof ExternalDocumentationHandler && ((ExternalDocumentationHandler)p).handleExternal(element, originalElement)) {
|
||||
processed = true;
|
||||
break;
|
||||
}
|
||||
ExternalJavaDocAction.showExternalJavadoc(urls, component);
|
||||
}
|
||||
}
|
||||
|
||||
if (!processed) {
|
||||
List<String> urls;
|
||||
if (!StringUtil.isEmptyOrSpaces(myEffectiveExternalUrl)) {
|
||||
urls = Collections.singletonList(myEffectiveExternalUrl);
|
||||
}
|
||||
else {
|
||||
urls = provider.getUrlFor(element, originalElement);
|
||||
assert urls != null : provider;
|
||||
assert !urls.isEmpty() : provider;
|
||||
}
|
||||
ExternalJavaDocAction.showExternalJavadoc(urls, PlatformDataKeys.CONTEXT_COMPONENT.getData(e.getDataContext()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* 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.
|
||||
@@ -35,11 +35,13 @@ import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class ExternalJavaDocAction extends AnAction {
|
||||
|
||||
@@ -90,8 +92,8 @@ public class ExternalJavaDocAction extends AnAction {
|
||||
}
|
||||
}
|
||||
|
||||
public static void showExternalJavadoc(List<String> urls, Component component) {
|
||||
final HashSet<String> set = new HashSet<String>(urls);
|
||||
public static void showExternalJavadoc(@NotNull List<String> urls, Component component) {
|
||||
Set<String> set = new THashSet<String>(urls);
|
||||
if (set.size() > 1) {
|
||||
JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep<String>("Choose external documentation root", ArrayUtil.toStringArray(set)) {
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* 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.
|
||||
@@ -137,10 +137,6 @@ public class BrowserLauncherAppless extends BrowserLauncher {
|
||||
private void openOrBrowse(@NotNull String url, boolean browse, @Nullable Project project) {
|
||||
url = url.trim();
|
||||
|
||||
if (url.startsWith("jar:")) {
|
||||
return;
|
||||
}
|
||||
|
||||
URI uri;
|
||||
if (BrowserUtil.isAbsoluteURL(url)) {
|
||||
uri = VfsUtil.toUri(url);
|
||||
|
||||
+5
-1
@@ -35,7 +35,7 @@ import java.util.Locale;
|
||||
)
|
||||
public class KeyboardSettingsExternalizable implements PersistentStateComponent<KeyboardSettingsExternalizable.OptionSet> {
|
||||
|
||||
private static final String [] supportedNonEnglishLanguages = {"de", "fr", "it"};
|
||||
private static final String [] supportedNonEnglishLanguages = {"de", "fr", "it", "uk"};
|
||||
|
||||
public static boolean isSupportedKeyboardLayout(@NotNull Component component) {
|
||||
if (SystemInfo.isMac) return false;
|
||||
@@ -92,6 +92,10 @@ public class KeyboardSettingsExternalizable implements PersistentStateComponent<
|
||||
myOptions = state;
|
||||
}
|
||||
|
||||
public boolean isUkrainianKeyboard (Component c) {
|
||||
return c!=null && "uk".equals(c.getInputContext().getLocale().getLanguage());
|
||||
}
|
||||
|
||||
public boolean isNonEnglishKeyboardSupportEnabled () {
|
||||
return myOptions.USE_NON_ENGLISH_KEYBOARD;
|
||||
}
|
||||
|
||||
@@ -416,20 +416,8 @@ public class IdeEventQueue extends EventQueue {
|
||||
if (e instanceof KeyEvent) {
|
||||
KeyEvent ke = (KeyEvent)e;
|
||||
|
||||
// Alt,keyChar=Undefined keyChar,modifiers=Ctrl+Alt,extModifiers=Ctrl+Alt+Button5,keyLocation=KEY_LOCATION_RIGHT
|
||||
|
||||
//if (ke.getKeyCode() == KeyEvent.VK_ALT && ke.getID() == KeyEvent.KEY_PRESSED) {
|
||||
//
|
||||
// if (ke.getKeyLocation() == KeyEvent.KEY_LOCATION_RIGHT) {
|
||||
// if ((ke.getModifiersEx() & (InputEvent.ALT_DOWN_MASK | InputEvent.CTRL_DOWN_MASK)) != (InputEvent.ALT_DOWN_MASK | InputEvent.CTRL_DOWN_MASK))
|
||||
// {
|
||||
// altGrIsPressed = true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//} else {
|
||||
// altGrIsPressed = false;
|
||||
//}
|
||||
// Try to get it from editor
|
||||
Component sourceComponent = WindowManagerEx.getInstanceEx().getMostRecentFocusedWindow();
|
||||
|
||||
if (ke.getID() == KeyEvent.KEY_PRESSED) {
|
||||
switch (ke.getKeyCode()) {
|
||||
@@ -459,8 +447,15 @@ public class IdeEventQueue extends EventQueue {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!leftAltIsPressed && KeyboardSettingsExternalizable.getInstance().isUkrainianKeyboard(sourceComponent) ) {
|
||||
if ('ґ' == ke.getKeyChar() || ke.getKeyCode() == KeyEvent.VK_U) {
|
||||
ke = new KeyEvent(ke.getComponent(), ke.getID(), ke.getWhen(), 0,
|
||||
KeyEvent.VK_UNDEFINED, 'ґ', ke.getKeyLocation());
|
||||
ke.setKeyCode(KeyEvent.VK_U);
|
||||
ke.setKeyChar('ґ');
|
||||
return ke;
|
||||
}
|
||||
}
|
||||
|
||||
Integer keyCodeFromChar = CharToVKeyMap.get(ke.getKeyChar());
|
||||
if (keyCodeFromChar != null) {
|
||||
@@ -469,15 +464,12 @@ public class IdeEventQueue extends EventQueue {
|
||||
ke.setKeyCode(keyCodeFromChar);
|
||||
}
|
||||
|
||||
// Try to get it from editor
|
||||
Component sourceComponent = WindowManagerEx.getInstanceEx().getMostRecentFocusedWindow();
|
||||
|
||||
//for (int i = 0; sourceComponent == null && i < WindowManagerEx.getInstanceEx().getAllProjectFrames().length; i++) {
|
||||
// sourceComponent = WindowManagerEx.getInstanceEx().getAllProjectFrames()[i].getComponent();
|
||||
//}
|
||||
|
||||
if (sourceComponent != null) {
|
||||
if (sourceComponent.getInputContext().getLocale().getLanguage().equals("de")) {
|
||||
if (KeyboardSettingsExternalizable.isSupportedKeyboardLayout(sourceComponent)) {
|
||||
if ((ke.getModifiersEx() & (InputEvent.ALT_DOWN_MASK | InputEvent.CTRL_DOWN_MASK)) != 0 /*&& ke.getKeyLocation() == KeyEvent.KEY_LOCATION_RIGHT*/) {
|
||||
// On German keyboard layout on Windows we are getting on key press
|
||||
// ctrl + alt instead of AltGr
|
||||
|
||||
@@ -18,7 +18,10 @@ 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.Couple;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.psi.*;
|
||||
@@ -26,16 +29,15 @@ import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* For:
|
||||
* class B(A):
|
||||
* def __init__(self):
|
||||
* A.__init__(self) # inserted
|
||||
* print "Constructor B was called"
|
||||
*
|
||||
* def __init__(self):
|
||||
* A.__init__(self) # inserted
|
||||
* print "Constructor B was called"
|
||||
* <p/>
|
||||
* User: catherine
|
||||
*/
|
||||
public class AddCallSuperQuickFix implements LocalQuickFix {
|
||||
@@ -52,7 +54,7 @@ public class AddCallSuperQuickFix implements LocalQuickFix {
|
||||
}
|
||||
|
||||
public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) {
|
||||
PyFunction problemFunction = PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PyFunction.class);
|
||||
final PyFunction problemFunction = PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PyFunction.class);
|
||||
if (problemFunction == null) return;
|
||||
final StringBuilder superCall = new StringBuilder();
|
||||
final PyClass klass = problemFunction.getContainingClass();
|
||||
@@ -63,35 +65,56 @@ public class AddCallSuperQuickFix implements LocalQuickFix {
|
||||
final PyClass superClass = superClasses[0];
|
||||
final PyFunction superInit = superClass.findMethodByName(PyNames.INIT, true);
|
||||
if (superInit == null) return;
|
||||
boolean addComma = true;
|
||||
final boolean addComma;
|
||||
if (klass.isNewStyleClass()) {
|
||||
addComma = false;
|
||||
if (LanguageLevel.forElement(klass).isPy3K())
|
||||
if (LanguageLevel.forElement(klass).isPy3K()) {
|
||||
superCall.append("super().__init__(");
|
||||
else
|
||||
}
|
||||
else {
|
||||
superCall.append("super(").append(klass.getName()).append(", self).__init__(");
|
||||
}
|
||||
}
|
||||
else {
|
||||
addComma = true;
|
||||
superCall.append(superClass.getName());
|
||||
superCall.append(".__init__(self");
|
||||
}
|
||||
StringBuilder newFunction = new StringBuilder("def __init__(self");
|
||||
final StringBuilder newFunction = new StringBuilder("def __init__(self");
|
||||
|
||||
buildParameterList(problemFunction, superInit, superCall, newFunction, addComma);
|
||||
final Couple<List<String>> couple = buildNewFunctionParamsAndSuperInitCallArgs(problemFunction, superInit);
|
||||
|
||||
final List<String> newParameters = couple.getFirst();
|
||||
if (!newParameters.isEmpty()) {
|
||||
newFunction.append(", ");
|
||||
}
|
||||
StringUtil.join(newParameters, ", ", newFunction);
|
||||
newFunction.append(")");
|
||||
if (problemFunction.getAnnotation() != null) {
|
||||
newFunction.append(problemFunction.getAnnotation().getText());
|
||||
}
|
||||
newFunction.append(":\n\t");
|
||||
|
||||
final List<String> superCallArguments = couple.getSecond();
|
||||
if (addComma && !superCallArguments.isEmpty()) {
|
||||
superCall.append(", ");
|
||||
}
|
||||
StringUtil.join(superCallArguments, ", ", superCall);
|
||||
superCall.append(")");
|
||||
|
||||
final PyStatementList statementList = problemFunction.getStatementList();
|
||||
PyExpression docstring = null;
|
||||
final PyStatement[] statements = statementList.getStatements();
|
||||
if (statements.length != 0 && statements[0] instanceof PyExpressionStatement) {
|
||||
PyExpressionStatement st = (PyExpressionStatement)statements[0];
|
||||
if (st.getExpression() instanceof PyStringLiteralExpression)
|
||||
final PyExpressionStatement st = (PyExpressionStatement)statements[0];
|
||||
if (st.getExpression() instanceof PyStringLiteralExpression) {
|
||||
docstring = st.getExpression();
|
||||
}
|
||||
}
|
||||
|
||||
newFunction.append("):\n\t");
|
||||
if (docstring != null)
|
||||
if (docstring != null) {
|
||||
newFunction.append(docstring.getText()).append("\n\t");
|
||||
}
|
||||
newFunction.append(superCall).append("\n\t");
|
||||
boolean first = true;
|
||||
for (PyStatement statement : statements) {
|
||||
@@ -102,89 +125,249 @@ public class AddCallSuperQuickFix implements LocalQuickFix {
|
||||
newFunction.append(statement.getText()).append("\n\t");
|
||||
}
|
||||
|
||||
problemFunction.replace(
|
||||
PyElementGenerator.getInstance(project).createFromText(LanguageLevel.forElement(problemFunction), PyFunction.class,
|
||||
newFunction.toString()));
|
||||
final PyElementGenerator generator = PyElementGenerator.getInstance(project);
|
||||
problemFunction.replace(generator.createFromText(LanguageLevel.forElement(problemFunction), PyFunction.class, newFunction.toString()));
|
||||
}
|
||||
|
||||
private static void buildParameterList(@NotNull final PyFunction problemFunction,
|
||||
@NotNull final PyFunction superInit,
|
||||
@NotNull final StringBuilder superCall,
|
||||
@NotNull final StringBuilder newFunction, boolean addComma) {
|
||||
final PyParameter[] parameters = problemFunction.getParameterList().getParameters();
|
||||
final List<String> problemParams = new ArrayList<String>();
|
||||
final List<String> functionParams = new ArrayList<String>();
|
||||
String starName = null;
|
||||
String doubleStarName = null;
|
||||
for (int i = 1; i != parameters.length; i++) {
|
||||
PyParameter p = parameters[i];
|
||||
functionParams.add(p.getName());
|
||||
if (p.getText().startsWith("**")) {
|
||||
doubleStarName = p.getText();
|
||||
continue;
|
||||
@NotNull
|
||||
private static Couple<List<String>> buildNewFunctionParamsAndSuperInitCallArgs(@NotNull PyFunction origInit,
|
||||
@NotNull PyFunction superInit) {
|
||||
final List<String> newFunctionParams = new ArrayList<String>();
|
||||
final List<String> superCallArgs = new ArrayList<String>();
|
||||
|
||||
final ParametersInfo origInfo = new ParametersInfo(origInit.getParameterList());
|
||||
final ParametersInfo superInfo = new ParametersInfo(superInit.getParameterList());
|
||||
|
||||
// Required parameters (not-keyword)
|
||||
for (PyParameter param : origInfo.getRequiredParameters()) {
|
||||
newFunctionParams.add(param.getText());
|
||||
}
|
||||
for (PyParameter param : superInfo.getRequiredParameters()) {
|
||||
// Special case as if base class has constructor __init__((a, b), c) and
|
||||
// subclass has constructor __init__(a, (b, c))
|
||||
final PyTupleParameter tupleParam = param.getAsTuple();
|
||||
if (tupleParam != null) {
|
||||
final List<String> uniqueNames = collectParameterNames(tupleParam);
|
||||
final boolean hasDuplicates = uniqueNames.removeAll(origInfo.getAllParameterNames());
|
||||
if (hasDuplicates) {
|
||||
newFunctionParams.addAll(uniqueNames);
|
||||
}
|
||||
else {
|
||||
newFunctionParams.add(param.getText());
|
||||
}
|
||||
// Retain original structure of tuple parameter.
|
||||
// Note that tuple parameters cannot have annotations or nested default values, so it's syntactically safe
|
||||
superCallArgs.add(param.getText());
|
||||
}
|
||||
if (p.getText().startsWith("*")) {
|
||||
starName = p.getText();
|
||||
continue;
|
||||
else {
|
||||
if (!origInfo.getAllParameterNames().contains(param.getName())) {
|
||||
newFunctionParams.add(param.getText());
|
||||
}
|
||||
superCallArgs.add(param.getName());
|
||||
}
|
||||
if (p.getDefaultValue() != null) {
|
||||
problemParams.add(p.getText());
|
||||
continue;
|
||||
}
|
||||
newFunction.append(",").append(p.getText());
|
||||
}
|
||||
|
||||
addParametersFromSuper(superInit, superCall, newFunction, addComma, problemParams, functionParams, starName, doubleStarName);
|
||||
// Optional parameters (not-keyword)
|
||||
for (PyParameter param : origInfo.getOptionalParameters()) {
|
||||
newFunctionParams.add(param.getText());
|
||||
}
|
||||
|
||||
// Positional vararg
|
||||
PyParameter starredParam = null;
|
||||
if (origInfo.getPositionalContainerParameter() != null) {
|
||||
starredParam = origInfo.getPositionalContainerParameter();
|
||||
}
|
||||
else if (superInfo.getPositionalContainerParameter() != null) {
|
||||
starredParam = superInfo.getPositionalContainerParameter();
|
||||
}
|
||||
else if (origInfo.getSingleStarParameter() != null) {
|
||||
starredParam = origInfo.getSingleStarParameter();
|
||||
}
|
||||
else if (superInfo.getSingleStarParameter() != null) {
|
||||
starredParam = superInfo.getSingleStarParameter();
|
||||
}
|
||||
if (starredParam != null) {
|
||||
newFunctionParams.add(starredParam.getText());
|
||||
if (superInfo.getPositionalContainerParameter() != null) {
|
||||
superCallArgs.add("*" + starredParam.getName());
|
||||
}
|
||||
}
|
||||
|
||||
// Required keyword-only parameters
|
||||
for (PyParameter param : origInfo.getRequiredKeywordOnlyParameters()) {
|
||||
newFunctionParams.add(param.getText());
|
||||
}
|
||||
for (PyParameter param : superInfo.getRequiredKeywordOnlyParameters()) {
|
||||
if (!origInfo.getAllParameterNames().contains(param.getName())) {
|
||||
newFunctionParams.add(param.getText());
|
||||
}
|
||||
superCallArgs.add(param.getName() + "=" + param.getName());
|
||||
}
|
||||
|
||||
// Optional keyword-only parameters
|
||||
for (PyParameter param : origInfo.getOptionalKeywordOnlyParameters()) {
|
||||
newFunctionParams.add(param.getText());
|
||||
}
|
||||
|
||||
// Keyword vararg
|
||||
PyParameter doubleStarredParam = null;
|
||||
if (origInfo.getKeywordContainerParameter() != null) {
|
||||
doubleStarredParam = origInfo.getKeywordContainerParameter();
|
||||
}
|
||||
else if (superInfo.getKeywordContainerParameter() != null) {
|
||||
doubleStarredParam = superInfo.getKeywordContainerParameter();
|
||||
}
|
||||
if (doubleStarredParam != null) {
|
||||
newFunctionParams.add(doubleStarredParam.getText());
|
||||
if (superInfo.getKeywordContainerParameter() != null) {
|
||||
superCallArgs.add("**" + doubleStarredParam.getName());
|
||||
}
|
||||
}
|
||||
return Couple.of(newFunctionParams, superCallArgs);
|
||||
}
|
||||
|
||||
private static void addParametersFromSuper(@NotNull final PyFunction superInit, @NotNull final StringBuilder superCall,
|
||||
@NotNull final StringBuilder newFunction, boolean addComma,
|
||||
@NotNull final List<String> problemParams, @NotNull final List<String> functionParams,
|
||||
@Nullable String starName, @Nullable String doubleStarName) {
|
||||
final PyParameterList paramList = superInit.getParameterList();
|
||||
PyParameter[] parameters = paramList.getParameters();
|
||||
boolean addDouble = false;
|
||||
boolean addStar = false;
|
||||
for (int i = 1; i != parameters.length; i++) {
|
||||
PyParameter p = parameters[i];
|
||||
if (p.getDefaultValue() != null) continue;
|
||||
final String param = p.getName();
|
||||
String paramText = p.getText();
|
||||
if (paramText.startsWith("**")) {
|
||||
addDouble = true;
|
||||
if (doubleStarName == null)
|
||||
doubleStarName = p.getText();
|
||||
continue;
|
||||
private static class ParametersInfo {
|
||||
|
||||
private final PyParameter mySelfParam;
|
||||
/**
|
||||
* Parameters without default value that come before first "*..." parameter.
|
||||
*/
|
||||
private final List<PyParameter> myRequiredParams = new ArrayList<PyParameter>();
|
||||
/**
|
||||
* Parameters with default value that come before first "*..." parameter.
|
||||
*/
|
||||
private final List<PyParameter> myOptionalParams = new ArrayList<PyParameter>();
|
||||
/**
|
||||
* Parameter of form "*args" (positional vararg), not the same as single "*".
|
||||
*/
|
||||
private final PyParameter myPositionalContainerParam;
|
||||
/**
|
||||
* Parameter "*", that is used to delimit normal and keyword-only parameters.
|
||||
*/
|
||||
private final PyParameter mySingleStarParam;
|
||||
/**
|
||||
* Parameters without default value that come after first "*..." parameter.
|
||||
*/
|
||||
private final List<PyParameter> myRequiredKwOnlyParams = new ArrayList<PyParameter>();
|
||||
/**
|
||||
* Parameters with default value that come after first "*..." parameter.
|
||||
*/
|
||||
private final List<PyParameter> myOptionalKwOnlyParams = new ArrayList<PyParameter>();
|
||||
/**
|
||||
* Parameter of form "**kwargs" (keyword vararg).
|
||||
*/
|
||||
private final PyParameter myKeywordContainerParam;
|
||||
|
||||
private final Set<String> myAllParameterNames = new LinkedHashSet<String>();
|
||||
|
||||
public ParametersInfo(@NotNull PyParameterList parameterList) {
|
||||
PyParameter positionalContainer = null;
|
||||
PyParameter singleStarParam = null;
|
||||
PyParameter keywordContainer = null;
|
||||
PyParameter selfParam = null;
|
||||
|
||||
for (PyParameter param : parameterList.getParameters()) {
|
||||
myAllParameterNames.addAll(collectParameterNames(param));
|
||||
|
||||
if (param.isSelf()) {
|
||||
selfParam = param;
|
||||
}
|
||||
else if (param.getText().equals("*")) {
|
||||
singleStarParam = param;
|
||||
}
|
||||
else if (param.getText().startsWith("**")) {
|
||||
keywordContainer = param;
|
||||
}
|
||||
else if (param.getText().startsWith("*")) {
|
||||
positionalContainer = param;
|
||||
}
|
||||
else if (positionalContainer == null && singleStarParam == null) {
|
||||
if (param.hasDefaultValue()) {
|
||||
myOptionalParams.add(param);
|
||||
}
|
||||
else {
|
||||
myRequiredParams.add(param);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (param.hasDefaultValue()) {
|
||||
myOptionalKwOnlyParams.add(param);
|
||||
}
|
||||
else {
|
||||
myRequiredKwOnlyParams.add(param);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (paramText.startsWith("*")) {
|
||||
addStar = true;
|
||||
if (starName == null)
|
||||
starName = p.getText();
|
||||
continue;
|
||||
}
|
||||
if (addComma)
|
||||
superCall.append(",");
|
||||
superCall.append(param);
|
||||
if (!functionParams.contains(param))
|
||||
newFunction.append(",").append(param);
|
||||
addComma = true;
|
||||
|
||||
mySelfParam = selfParam;
|
||||
myPositionalContainerParam = positionalContainer;
|
||||
mySingleStarParam = singleStarParam;
|
||||
myKeywordContainerParam = keywordContainer;
|
||||
}
|
||||
for(String p : problemParams)
|
||||
newFunction.append(",").append(p);
|
||||
if (starName != null) {
|
||||
newFunction.append(",").append(starName);
|
||||
if (addStar) {
|
||||
if (addComma) superCall.append(",");
|
||||
superCall.append(starName);
|
||||
addComma = true;
|
||||
|
||||
@Nullable
|
||||
public PyParameter getSelfParameter() {
|
||||
return mySelfParam;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<PyParameter> getRequiredParameters() {
|
||||
return Collections.unmodifiableList(myRequiredParams);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<PyParameter> getOptionalParameters() {
|
||||
return Collections.unmodifiableList(myOptionalParams);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PyParameter getPositionalContainerParameter() {
|
||||
return myPositionalContainerParam;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PyParameter getSingleStarParameter() {
|
||||
return mySingleStarParam;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<PyParameter> getRequiredKeywordOnlyParameters() {
|
||||
return Collections.unmodifiableList(myRequiredKwOnlyParams);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<PyParameter> getOptionalKeywordOnlyParameters() {
|
||||
return Collections.unmodifiableList(myOptionalKwOnlyParams);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PyParameter getKeywordContainerParameter() {
|
||||
return myKeywordContainerParam;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<String> getAllParameterNames() {
|
||||
return Collections.unmodifiableSet(myAllParameterNames);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<String> collectParameterNames(@NotNull PyParameter param) {
|
||||
final List<String> result = new ArrayList<String>();
|
||||
collectParameterNames(param, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private static void collectParameterNames(@NotNull PyParameter param, @NotNull Collection<String> acc) {
|
||||
final PyTupleParameter tupleParam = param.getAsTuple();
|
||||
if (tupleParam != null) {
|
||||
for (PyParameter subParam : tupleParam.getContents()) {
|
||||
collectParameterNames(subParam, acc);
|
||||
}
|
||||
}
|
||||
if (doubleStarName != null) {
|
||||
newFunction.append(",").append(doubleStarName);
|
||||
if (addDouble) {
|
||||
if (addComma) superCall.append(",");
|
||||
superCall.append(doubleStarName);
|
||||
}
|
||||
else {
|
||||
ContainerUtil.addIfNotNull(acc, param.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
class Example1:
|
||||
def __init__(self, field1: str):
|
||||
self.field1 = field1
|
||||
|
||||
|
||||
class Example2(Example1):
|
||||
def <warning descr="Call to __init__ of super class is missed">__i<caret>nit__</warning>(self): ## Missed call to __init__ of super class
|
||||
pass
|
||||
@@ -1,8 +0,0 @@
|
||||
class Example1:
|
||||
def __init__(self, field1: str):
|
||||
self.field1 = field1
|
||||
|
||||
|
||||
class Example2(Example1):
|
||||
def __init__(self, field1):
|
||||
super().__init__(field1)
|
||||
@@ -0,0 +1,7 @@
|
||||
class A:
|
||||
def __init__(self, (a, (b, c)), (d, e)):
|
||||
pass
|
||||
|
||||
class B(A):
|
||||
def <warning descr="Call to __init__ of super class is missed">__init_<caret>_</warning>(self, (a, b), c, e):
|
||||
pass
|
||||
@@ -0,0 +1,7 @@
|
||||
class A:
|
||||
def __init__(self, (a, (b, c)), (d, e)):
|
||||
pass
|
||||
|
||||
class B(A):
|
||||
def __init__(self, (a, b), c, e, d):
|
||||
A.__init__(self, (a, (b, c)), (d, e))
|
||||
@@ -0,0 +1,7 @@
|
||||
class A:
|
||||
def __init__(self, a):
|
||||
pass
|
||||
|
||||
class B(A):
|
||||
def <warning descr="Call to __init__ of super class is missed">__i<caret>nit__</warning>(self, b, c=1, *args, kw_only):
|
||||
pass
|
||||
@@ -0,0 +1,7 @@
|
||||
class A:
|
||||
def __init__(self, a):
|
||||
pass
|
||||
|
||||
class B(A):
|
||||
def __init__(self, b, a, c=1, *args, kw_only):
|
||||
super().__init__(a)
|
||||
@@ -0,0 +1,8 @@
|
||||
class A:
|
||||
def __init__(self, a, b=1, *args, kw_only):
|
||||
pass
|
||||
|
||||
|
||||
class B(A):
|
||||
def <warning descr="Call to __init__ of super class is missed">__i<caret>nit__</warning>(self, c):
|
||||
pass
|
||||
@@ -0,0 +1,8 @@
|
||||
class A:
|
||||
def __init__(self, a, b=1, *args, kw_only):
|
||||
pass
|
||||
|
||||
|
||||
class B(A):
|
||||
def __init__(self, c, a, *args, kw_only):
|
||||
super().__init__(a, *args, kw_only=kw_only)
|
||||
@@ -0,0 +1,8 @@
|
||||
class A:
|
||||
def __init__(self, a):
|
||||
pass
|
||||
|
||||
|
||||
class B(A):
|
||||
def <warning descr="Call to __init__ of super class is missed">__init_<caret>_</warning>(self, a=1):
|
||||
pass
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
class A:
|
||||
def __init__(self, a):
|
||||
pass
|
||||
|
||||
|
||||
class B(A):
|
||||
def __init__(self, a=1):
|
||||
A.__init__(self, a)
|
||||
@@ -0,0 +1,7 @@
|
||||
class A:
|
||||
def __init__(self, *, kw_only, optional_kw_only=None):
|
||||
pass
|
||||
|
||||
class B(A):
|
||||
def <warning descr="Call to __init__ of super class is missed">__i<caret>nit__</warning>(self):
|
||||
pass
|
||||
@@ -0,0 +1,7 @@
|
||||
class A:
|
||||
def __init__(self, *, kw_only):
|
||||
pass
|
||||
|
||||
class B(A):
|
||||
def <warning descr="Call to __init__ of super class is missed">__i<caret>nit__</warning>(self, *args, another_kw_only):
|
||||
pass
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
class A:
|
||||
def __init__(self, *, kw_only):
|
||||
pass
|
||||
|
||||
class B(A):
|
||||
def __init__(self, *args, another_kw_only, kw_only):
|
||||
super().__init__(kw_only=kw_only)
|
||||
@@ -0,0 +1,7 @@
|
||||
class A:
|
||||
def __init__(self, *, kw_only, optional_kw_only=None):
|
||||
pass
|
||||
|
||||
class B(A):
|
||||
def __init__(self, *, kw_only):
|
||||
super().__init__(kw_only=kw_only)
|
||||
@@ -0,0 +1,7 @@
|
||||
class A:
|
||||
def __init__(self, a:int, b:float, *args:tuple, c:complex, **kwargs:dict) -> None:
|
||||
pass
|
||||
|
||||
class B(A):
|
||||
def <warning descr="Call to __init__ of super class is missed">__i<caret>nit__</warning>(self, d:str, *, e:bytes) -> list:
|
||||
pass
|
||||
@@ -0,0 +1,7 @@
|
||||
class A:
|
||||
def __init__(self, a:int, b:float, *args:tuple, c:complex, **kwargs:dict) -> None:
|
||||
pass
|
||||
|
||||
class B(A):
|
||||
def __init__(self, d:str, a:int, b:float, *args:tuple, e:bytes, c:complex, **kwargs:dict) -> list:
|
||||
super().__init__(a, b, *args, c=c, **kwargs)
|
||||
@@ -24,6 +24,7 @@ import com.jetbrains.python.inspections.PyMissingConstructorInspection;
|
||||
import com.jetbrains.python.inspections.PyStatementEffectInspection;
|
||||
import com.jetbrains.python.psi.LanguageLevel;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@TestDataPath("$CONTENT_ROOT/../testData/inspections/")
|
||||
public class Py3QuickFixTest extends PyTestCase {
|
||||
@@ -32,39 +33,107 @@ public class Py3QuickFixTest extends PyTestCase {
|
||||
return PyTestCase.ourPy3Descriptor;
|
||||
}
|
||||
|
||||
// PY-13685
|
||||
public void testReplacePrintEnd() {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON34, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
doInspectionTest("ReplacePrintEnd.py", PyStatementEffectInspection.class, PyBundle.message("QFIX.statement.effect"), true, true);
|
||||
}});
|
||||
doInspectionTest(PyStatementEffectInspection.class, PyBundle.message("QFIX.statement.effect"), true, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// PY-13685
|
||||
public void testReplacePrintComment() {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON34, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
doInspectionTest("ReplacePrintComment.py", PyStatementEffectInspection.class, PyBundle.message("QFIX.statement.effect"), true,
|
||||
true);
|
||||
}});
|
||||
doInspectionTest(PyStatementEffectInspection.class, PyBundle.message("QFIX.statement.effect"), true, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// PY-13685
|
||||
public void testReplaceExecComment() {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON34, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
doInspectionTest("ReplaceExecComment.py", PyStatementEffectInspection.class, PyBundle.message("QFIX.statement.effect"), true,
|
||||
true);
|
||||
}});
|
||||
doInspectionTest(PyStatementEffectInspection.class, PyBundle.message("QFIX.statement.effect"), true, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testAddCallSuperAnnotations() {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON33, new Runnable() {
|
||||
// PY-15867
|
||||
public void testAddCallSuperKeywordOnlyParamInSuperInit() {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON30, new Runnable() {
|
||||
public void run() {
|
||||
doInspectionTest(PyMissingConstructorInspection.class, PyBundle.message("QFIX.add.super"), true, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// PY-15867
|
||||
public void testAddCallSuperKeywordOnlyParamInInit() {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON30, new Runnable() {
|
||||
public void run() {
|
||||
doInspectionTest(PyMissingConstructorInspection.class, PyBundle.message("QFIX.add.super"), true, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// PY-15867
|
||||
public void testAddCallSuperSingleStarParamInSuperInit() {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON30, new Runnable() {
|
||||
public void run() {
|
||||
doInspectionTest(PyMissingConstructorInspection.class, PyBundle.message("QFIX.add.super"), true, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// PY-15867
|
||||
public void testAddCallSuperSingleStarParamInSuperInitAndVarargInInit() {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON30, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
doInspectionTest("AddCallSuperAnnotations.py",
|
||||
PyMissingConstructorInspection.class,
|
||||
PyBundle.message("QFIX.add.super"), true, true);
|
||||
doInspectionTest(PyMissingConstructorInspection.class, PyBundle.message("QFIX.add.super"), true, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// PY-11561
|
||||
public void testAddCallSuperTypeAnnotationsPreserved() {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON30, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
doInspectionTest(PyMissingConstructorInspection.class, PyBundle.message("QFIX.add.super"), true, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// PY-8991
|
||||
public void testRemoveUnicodePrefixFromGluedStringNodesWithSlash() {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON32, new Runnable() {
|
||||
public void run() {
|
||||
myFixture.configureByFile(getTestName(false) + ".py");
|
||||
myFixture.checkHighlighting(true, false, false);
|
||||
final IntentionAction intentionAction = myFixture.findSingleIntention(PyBundle.message("INTN.remove.leading.$0", "U"));
|
||||
assertNotNull(intentionAction);
|
||||
myFixture.launchAction(intentionAction);
|
||||
myFixture.checkResultByFile(getTestName(false) + "_after.py");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// PY-8990
|
||||
public void testRemoveUnicodePrefixFromGluedStringNodesInParenthesis() {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON32, new Runnable() {
|
||||
public void run() {
|
||||
myFixture.configureByFile(getTestName(false) + ".py");
|
||||
myFixture.checkHighlighting(true, false, false);
|
||||
final IntentionAction intentionAction = myFixture.findSingleIntention(PyBundle.message("INTN.remove.leading.$0", "U"));
|
||||
assertNotNull(intentionAction);
|
||||
myFixture.launchAction(intentionAction);
|
||||
myFixture.checkResultByFile(getTestName(false) + "_after.py");
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -75,9 +144,16 @@ public class Py3QuickFixTest extends PyTestCase {
|
||||
return PythonTestUtil.getTestDataPath() + "/inspections/";
|
||||
}
|
||||
|
||||
protected void doInspectionTest(@TestDataFile @NonNls String testFileName,
|
||||
final Class inspectionClass,
|
||||
@NonNls String quickFixName,
|
||||
private void doInspectionTest(@NotNull Class inspectionClass,
|
||||
@NotNull String quickFixName,
|
||||
boolean applyFix,
|
||||
boolean available) {
|
||||
doInspectionTest(getTestName(false) + ".py", inspectionClass, quickFixName, applyFix, available);
|
||||
}
|
||||
|
||||
protected void doInspectionTest(@TestDataFile @NonNls @NotNull String testFileName,
|
||||
@NotNull Class inspectionClass,
|
||||
@NonNls @NotNull String quickFixName,
|
||||
boolean applyFix,
|
||||
boolean available) {
|
||||
doInspectionTest(new String[]{testFileName}, inspectionClass, quickFixName, applyFix, available);
|
||||
@@ -93,9 +169,9 @@ public class Py3QuickFixTest extends PyTestCase {
|
||||
* @param available true if the fix should be available, false if it should be explicitly not available.
|
||||
* @throws Exception
|
||||
*/
|
||||
protected void doInspectionTest(@NonNls String[] testFiles,
|
||||
final Class inspectionClass,
|
||||
@NonNls String quickFixName,
|
||||
protected void doInspectionTest(@NonNls @NotNull String[] testFiles,
|
||||
@NotNull Class inspectionClass,
|
||||
@NonNls @NotNull String quickFixName,
|
||||
boolean applyFix,
|
||||
boolean available) {
|
||||
myFixture.enableInspections(inspectionClass);
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.jetbrains.python.inspections.*;
|
||||
import com.jetbrains.python.inspections.unresolvedReference.PyUnresolvedReferencesInspection;
|
||||
import com.jetbrains.python.psi.LanguageLevel;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author dcheryasov
|
||||
@@ -47,15 +48,19 @@ public class PyQuickFixTest extends PyTestCase {
|
||||
}
|
||||
|
||||
public void testAddImport() {
|
||||
doInspectionTest(new String[] { "AddImport.py", "ImportTarget.py" }, PyUnresolvedReferencesInspection.class, "Import 'ImportTarget'", true, true);
|
||||
doInspectionTest(new String[]{"AddImport.py", "ImportTarget.py"}, PyUnresolvedReferencesInspection.class,
|
||||
"Import 'ImportTarget'", true, true);
|
||||
}
|
||||
|
||||
public void testAddImportDoc() {
|
||||
doInspectionTest(new String[] { "AddImportDoc.py", "ImportTarget.py" }, PyUnresolvedReferencesInspection.class, "Import 'ImportTarget'", true, true);
|
||||
doInspectionTest(new String[]{"AddImportDoc.py", "ImportTarget.py"}, PyUnresolvedReferencesInspection.class,
|
||||
"Import 'ImportTarget'", true, true);
|
||||
}
|
||||
|
||||
public void testAddImportDocComment() { // PY-728
|
||||
doInspectionTest(new String[] { "AddImportDocComment.py", "ImportTarget.py" }, PyUnresolvedReferencesInspection.class, "Import 'ImportTarget'", true, true);
|
||||
// PY-728
|
||||
public void testAddImportDocComment() {
|
||||
doInspectionTest(new String[]{"AddImportDocComment.py", "ImportTarget.py"}, PyUnresolvedReferencesInspection.class,
|
||||
"Import 'ImportTarget'", true, true);
|
||||
}
|
||||
|
||||
public void testImportFromModule() {
|
||||
@@ -73,7 +78,8 @@ public class PyQuickFixTest extends PyTestCase {
|
||||
assertEquals("Import 'module.MyOldStyleClass'", intention.getText());
|
||||
}
|
||||
|
||||
public void testImportFromModuleStar() { // PY-6302
|
||||
// PY-6302
|
||||
public void testImportFromModuleStar() {
|
||||
myFixture.enableInspections(PyUnresolvedReferencesInspection.class);
|
||||
myFixture.copyDirectoryToProject("importFromModuleStar", "");
|
||||
myFixture.configureFromTempProjectFile("source.py");
|
||||
@@ -91,7 +97,8 @@ public class PyQuickFixTest extends PyTestCase {
|
||||
settings.PREFER_FROM_IMPORT = false;
|
||||
settings.HIGHLIGHT_UNUSED_IMPORTS = false;
|
||||
try {
|
||||
doInspectionTest(new String[]{"QualifyByImport.py", "QualifyByImportFoo.py"}, PyUnresolvedReferencesInspection.class, PyBundle.message("ACT.qualify.with.module"), true, true);
|
||||
doInspectionTest(new String[]{"QualifyByImport.py", "QualifyByImportFoo.py"}, PyUnresolvedReferencesInspection.class,
|
||||
PyBundle.message("ACT.qualify.with.module"), true, true);
|
||||
}
|
||||
finally {
|
||||
settings.PREFER_FROM_IMPORT = oldPreferFrom;
|
||||
@@ -104,7 +111,8 @@ public class PyQuickFixTest extends PyTestCase {
|
||||
boolean oldHighlightUnused = settings.HIGHLIGHT_UNUSED_IMPORTS;
|
||||
settings.HIGHLIGHT_UNUSED_IMPORTS = false;
|
||||
try {
|
||||
doInspectionTest(new String[]{"AddToImportFromList.py", "AddToImportFromFoo.py"}, PyUnresolvedReferencesInspection.class, "Import 'foo(a) from AddToImportFromFoo'", true, true);
|
||||
doInspectionTest(new String[]{"AddToImportFromList.py", "AddToImportFromFoo.py"}, PyUnresolvedReferencesInspection.class,
|
||||
"Import 'foo(a) from AddToImportFromFoo'", true, true);
|
||||
}
|
||||
finally {
|
||||
settings.HIGHLIGHT_UNUSED_IMPORTS = oldHighlightUnused;
|
||||
@@ -115,90 +123,86 @@ public class PyQuickFixTest extends PyTestCase {
|
||||
// TODO: add tests for stub indexes-based autoimport of unimported somehow.
|
||||
|
||||
public void testAddSelf() {
|
||||
doInspectionTest("AddSelf.py", PyMethodParametersInspection.class, PyBundle.message("QFIX.add.parameter.self", "self"), true, true);
|
||||
doInspectionTest(PyMethodParametersInspection.class, PyBundle.message("QFIX.add.parameter.self", "self"), true, true);
|
||||
}
|
||||
|
||||
public void testReplacePrint() {
|
||||
doInspectionTest("ReplacePrint.py", PyCompatibilityInspection.class, PyBundle.message("QFIX.statement.effect"), true, true);
|
||||
doInspectionTest(PyCompatibilityInspection.class, PyBundle.message("QFIX.statement.effect"), true, true);
|
||||
}
|
||||
|
||||
public void testAddSelfFunction() { //PY-4556
|
||||
doInspectionTest("AddSelfFunction.py",
|
||||
PyUnresolvedReferencesInspection.class, PyBundle.message("QFIX.unresolved.reference", "get_a", "self"), true, true);
|
||||
// PY-4556
|
||||
public void testAddSelfFunction() {
|
||||
doInspectionTest("AddSelfFunction.py", PyUnresolvedReferencesInspection.class,
|
||||
PyBundle.message("QFIX.unresolved.reference", "get_a", "self"), true, true);
|
||||
}
|
||||
|
||||
public void testAddSelfToClassmethod() { //PY-9721
|
||||
doInspectionTest("AddSelfToClassmethod.py",
|
||||
PyUnresolvedReferencesInspection.class, PyBundle.message("QFIX.unresolved.reference", "foo", "cls"), true, true);
|
||||
// PY-9721
|
||||
public void testAddSelfToClassmethod() {
|
||||
doInspectionTest("AddSelfToClassmethod.py", PyUnresolvedReferencesInspection.class,
|
||||
PyBundle.message("QFIX.unresolved.reference", "foo", "cls"), true, true);
|
||||
}
|
||||
|
||||
public void testAddCls() {
|
||||
doInspectionTest("AddCls.py", PyMethodParametersInspection.class, PyBundle.message("QFIX.add.parameter.self", "cls"), true, true);
|
||||
doInspectionTest(PyMethodParametersInspection.class, PyBundle.message("QFIX.add.parameter.self", "cls"), true, true);
|
||||
}
|
||||
|
||||
public void testRenameToSelf() {
|
||||
doInspectionTest("RenameToSelf.py", PyMethodParametersInspection.class, PyBundle.message("QFIX.rename.parameter.to.$0", "self"), true,
|
||||
true);
|
||||
doInspectionTest(PyMethodParametersInspection.class, PyBundle.message("QFIX.rename.parameter.to.$0", "self"), true, true);
|
||||
}
|
||||
|
||||
public void testRemoveTrailingSemicolon() {
|
||||
doInspectionTest("RemoveTrailingSemicolon.py", PyTrailingSemicolonInspection.class, PyBundle.message("QFIX.remove.trailing.semicolon"),
|
||||
true, true);
|
||||
doInspectionTest(PyTrailingSemicolonInspection.class, PyBundle.message("QFIX.remove.trailing.semicolon"), true, true);
|
||||
}
|
||||
|
||||
public void testDictCreation() {
|
||||
doInspectionTest("DictCreation.py", PyDictCreationInspection.class, PyBundle.message("QFIX.dict.creation"), true, true);
|
||||
doInspectionTest(PyDictCreationInspection.class, PyBundle.message("QFIX.dict.creation"), true, true);
|
||||
}
|
||||
|
||||
public void testDictCreationTuple() { //PY-6283
|
||||
doInspectionTest("DictCreationTuple.py", PyDictCreationInspection.class, PyBundle.message("QFIX.dict.creation"), true, true);
|
||||
// PY-6283
|
||||
public void testDictCreationTuple() {
|
||||
doInspectionTest(PyDictCreationInspection.class, PyBundle.message("QFIX.dict.creation"), true, true);
|
||||
}
|
||||
|
||||
public void testDictCreationDuplicate() { //PY-7318
|
||||
doInspectionTest("DictCreationDuplicate.py", PyDictCreationInspection.class, PyBundle.message("QFIX.dict.creation"), true, true);
|
||||
// PY-7318
|
||||
public void testDictCreationDuplicate() {
|
||||
doInspectionTest(PyDictCreationInspection.class, PyBundle.message("QFIX.dict.creation"), true, true);
|
||||
}
|
||||
|
||||
public void testTransformClassicClass() {
|
||||
doInspectionTest("TransformClassicClass.py", PyClassicStyleClassInspection.class,
|
||||
PyBundle.message("QFIX.classic.class.transform"), true, true);
|
||||
doInspectionTest(PyClassicStyleClassInspection.class, PyBundle.message("QFIX.classic.class.transform"), true, true);
|
||||
}
|
||||
|
||||
public void testAddGlobalQuickFix() {
|
||||
doInspectionTest("AddGlobalStatement.py", PyUnboundLocalVariableInspection.class,
|
||||
PyBundle.message("QFIX.add.global"), true, true);
|
||||
public void testAddGlobalStatement() {
|
||||
doInspectionTest(PyUnboundLocalVariableInspection.class, PyBundle.message("QFIX.add.global"), true, true);
|
||||
}
|
||||
|
||||
public void testAddGlobalExistingQuickFix() {
|
||||
doInspectionTest("AddGlobalExistingStatement.py", PyUnboundLocalVariableInspection.class,
|
||||
PyBundle.message("QFIX.add.global"), true, true);
|
||||
public void testAddGlobalExistingStatement() {
|
||||
doInspectionTest(PyUnboundLocalVariableInspection.class, PyBundle.message("QFIX.add.global"), true, true);
|
||||
}
|
||||
|
||||
public void testSimplifyBooleanCheckQuickFix() {
|
||||
doInspectionTest("SimplifyBooleanCheck.py", PySimplifyBooleanCheckInspection.class,
|
||||
PyBundle.message("QFIX.simplify.$0", "b"), true, true);
|
||||
public void testSimplifyBooleanCheck() {
|
||||
doInspectionTest(PySimplifyBooleanCheckInspection.class, PyBundle.message("QFIX.simplify.$0", "b"), true, true);
|
||||
}
|
||||
|
||||
public void testFromFutureImportQuickFix() {
|
||||
doInspectionTest("MoveFromFutureImport.py", PyFromFutureImportInspection.class,
|
||||
PyBundle.message("QFIX.move.from.future.import"), true, true);
|
||||
public void testMoveFromFutureImport() {
|
||||
doInspectionTest(PyFromFutureImportInspection.class, PyBundle.message("QFIX.move.from.future.import"), true, true);
|
||||
}
|
||||
|
||||
public void testFromFutureImportQuickFixDocString() { // PY-10080
|
||||
doInspectionTest("MoveFromFutureImportDocString.py", PyFromFutureImportInspection.class,
|
||||
PyBundle.message("QFIX.move.from.future.import"), true, true);
|
||||
// PY-10080
|
||||
public void testMoveFromFutureImportDocString() {
|
||||
doInspectionTest(PyFromFutureImportInspection.class, PyBundle.message("QFIX.move.from.future.import"), true, true);
|
||||
}
|
||||
|
||||
public void testComparisonWithNoneQuickFix() {
|
||||
doInspectionTest("ComparisonWithNone.py", PyComparisonWithNoneInspection.class,
|
||||
PyBundle.message("QFIX.replace.equality"), true, true);
|
||||
public void testComparisonWithNone() {
|
||||
doInspectionTest(PyComparisonWithNoneInspection.class, PyBundle.message("QFIX.replace.equality"), true, true);
|
||||
}
|
||||
|
||||
public void testAddClassFix() {
|
||||
doInspectionTest("AddClass.py", PyUnresolvedReferencesInspection.class, "Create class 'Xyzzy'", true, true);
|
||||
}
|
||||
|
||||
|
||||
public void testAddFunctionToModule() { // PY-1602
|
||||
// PY-1602
|
||||
public void testAddFunctionToModule() {
|
||||
doInspectionTest(
|
||||
"AddFunctionToModule.py",
|
||||
PyUnresolvedReferencesInspection.class,
|
||||
@@ -207,7 +211,8 @@ public class PyQuickFixTest extends PyTestCase {
|
||||
);
|
||||
}
|
||||
|
||||
public void testRedundantParentheses() { // PY-1470
|
||||
// PY-1470
|
||||
public void testRedundantParentheses() {
|
||||
String[] testFiles = new String[]{"RedundantParentheses.py"};
|
||||
myFixture.enableInspections(PyRedundantParenthesesInspection.class);
|
||||
myFixture.configureByFiles(testFiles);
|
||||
@@ -216,88 +221,86 @@ public class PyQuickFixTest extends PyTestCase {
|
||||
assertNotNull(intentionAction);
|
||||
myFixture.launchAction(intentionAction);
|
||||
myFixture.checkResultByFile(graftBeforeExt(testFiles[0], "_after"));
|
||||
|
||||
}
|
||||
|
||||
public void testRedundantParenthesesBoolean() { // PY-3095
|
||||
doInspectionTest("RedundantParenthesesBoolean.py", PyRedundantParenthesesInspection.class,
|
||||
PyBundle.message("QFIX.redundant.parentheses"), true, true);
|
||||
// PY-3095
|
||||
public void testRedundantParenthesesBoolean() {
|
||||
doInspectionTest(PyRedundantParenthesesInspection.class, PyBundle.message("QFIX.redundant.parentheses"), true, true);
|
||||
}
|
||||
|
||||
public void testRedundantParenthesesMore() { // PY-3239
|
||||
doInspectionTest("RedundantParenthesesMore.py", PyRedundantParenthesesInspection.class,
|
||||
PyBundle.message("QFIX.redundant.parentheses"), true, true);
|
||||
// PY-3239
|
||||
public void testRedundantParenthesesMore() {
|
||||
doInspectionTest(PyRedundantParenthesesInspection.class, PyBundle.message("QFIX.redundant.parentheses"), true, true);
|
||||
}
|
||||
|
||||
public void testRedundantParenthesesParenthesizedExpression() { // PY-12679
|
||||
doInspectionTest("RedundantParenthesesParenthesizedExpression.py", PyRedundantParenthesesInspection.class,
|
||||
PyBundle.message("QFIX.redundant.parentheses"), true, true);
|
||||
// PY-12679
|
||||
public void testRedundantParenthesesParenthesizedExpression() {
|
||||
doInspectionTest(PyRedundantParenthesesInspection.class, PyBundle.message("QFIX.redundant.parentheses"), true, true);
|
||||
}
|
||||
|
||||
// PY-15506
|
||||
public void testEmptyListOfBaseClasses() {
|
||||
doInspectionTest("EmptyListOfBaseClasses.py", PyRedundantParenthesesInspection.class,
|
||||
PyBundle.message("QFIX.redundant.parentheses"), true, true);
|
||||
doInspectionTest(PyRedundantParenthesesInspection.class, PyBundle.message("QFIX.redundant.parentheses"), true, true);
|
||||
}
|
||||
|
||||
public void testChainedComparisons() { // PY-1020
|
||||
doInspectionTest("ChainedComparisons.py", PyChainedComparisonsInspection.class,
|
||||
PyBundle.message("QFIX.chained.comparison"), true, true);
|
||||
// PY-1020
|
||||
public void testChainedComparisons() {
|
||||
doInspectionTest(PyChainedComparisonsInspection.class, PyBundle.message("QFIX.chained.comparison"), true, true);
|
||||
}
|
||||
|
||||
public void testChainedComparison1() { // PY-3126
|
||||
doInspectionTest("ChainedComparison1.py", PyChainedComparisonsInspection.class,
|
||||
PyBundle.message("QFIX.chained.comparison"), true, true);
|
||||
// PY-3126
|
||||
public void testChainedComparison1() {
|
||||
doInspectionTest(PyChainedComparisonsInspection.class, PyBundle.message("QFIX.chained.comparison"), true, true);
|
||||
}
|
||||
|
||||
public void testChainedComparison2() { // PY-3126
|
||||
doInspectionTest("ChainedComparison2.py", PyChainedComparisonsInspection.class,
|
||||
PyBundle.message("QFIX.chained.comparison"), true, true);
|
||||
// PY-3126
|
||||
public void testChainedComparison2() {
|
||||
doInspectionTest(PyChainedComparisonsInspection.class, PyBundle.message("QFIX.chained.comparison"), true, true);
|
||||
}
|
||||
|
||||
public void testChainedComparison3() { // PY-3126
|
||||
doInspectionTest("ChainedComparison3.py", PyChainedComparisonsInspection.class,
|
||||
PyBundle.message("QFIX.chained.comparison"), true, true);
|
||||
// PY-3126
|
||||
public void testChainedComparison3() {
|
||||
doInspectionTest(PyChainedComparisonsInspection.class, PyBundle.message("QFIX.chained.comparison"), true, true);
|
||||
}
|
||||
|
||||
public void testChainedComparison4() { // PY-5623
|
||||
doInspectionTest("ChainedComparison4.py", PyChainedComparisonsInspection.class,
|
||||
PyBundle.message("QFIX.chained.comparison"), true, true);
|
||||
// PY-5623
|
||||
public void testChainedComparison4() {
|
||||
doInspectionTest(PyChainedComparisonsInspection.class, PyBundle.message("QFIX.chained.comparison"), true, true);
|
||||
}
|
||||
|
||||
public void testChainedComparison5() { // PY-6467
|
||||
doInspectionTest("ChainedComparison5.py", PyChainedComparisonsInspection.class,
|
||||
PyBundle.message("QFIX.chained.comparison"), true, true);
|
||||
// PY-6467
|
||||
public void testChainedComparison5() {
|
||||
doInspectionTest(PyChainedComparisonsInspection.class, PyBundle.message("QFIX.chained.comparison"), true, true);
|
||||
}
|
||||
|
||||
// PY-14002
|
||||
public void testChainedComparisonWithCommonBinaryExpression() {
|
||||
doInspectionTest("ChainedComparisonWithCommonBinaryExpression.py", PyChainedComparisonsInspection.class,
|
||||
PyBundle.message("QFIX.chained.comparison"), true, true);
|
||||
doInspectionTest(PyChainedComparisonsInspection.class, PyBundle.message("QFIX.chained.comparison"), true, true);
|
||||
}
|
||||
|
||||
public void testStatementEffect() { // PY-1362, PY-2585
|
||||
doInspectionTest("StatementEffect.py", PyStatementEffectInspection.class,
|
||||
PyBundle.message("QFIX.statement.effect"), true, true);
|
||||
// PY-1362, PY-2585
|
||||
public void testStatementEffect() {
|
||||
doInspectionTest(PyStatementEffectInspection.class, PyBundle.message("QFIX.statement.effect"), true, true);
|
||||
}
|
||||
|
||||
public void testStatementEffectIntroduceVariable() { // PY-1265
|
||||
doInspectionTest("StatementEffectIntroduceVariable.py", PyStatementEffectInspection.class,
|
||||
PyBundle.message("QFIX.statement.effect.introduce.variable"), true, true);
|
||||
// PY-1265
|
||||
public void testStatementEffectIntroduceVariable() {
|
||||
doInspectionTest(PyStatementEffectInspection.class, PyBundle.message("QFIX.statement.effect.introduce.variable"), true, true);
|
||||
}
|
||||
|
||||
public void testUnresolvedWith() { // PY-2083
|
||||
// PY-2083
|
||||
public void testUnresolvedWith() {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON25, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
doInspectionTest("UnresolvedWith.py", PyUnresolvedReferencesInspection.class,
|
||||
PyBundle.message("QFIX.unresolved.reference.add.future"), true, true);
|
||||
doInspectionTest(PyUnresolvedReferencesInspection.class, PyBundle.message("QFIX.unresolved.reference.add.future"), true, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testUnresolvedRefCreateFunction() { // PY-2092
|
||||
doInspectionTest("UnresolvedRefCreateFunction.py", PyUnresolvedReferencesInspection.class,
|
||||
// PY-2092
|
||||
public void testUnresolvedRefCreateFunction() {
|
||||
doInspectionTest(PyUnresolvedReferencesInspection.class,
|
||||
PyBundle.message("QFIX.unresolved.reference.create.function.$0", "ref"), true, true);
|
||||
}
|
||||
|
||||
@@ -305,109 +308,113 @@ public class PyQuickFixTest extends PyTestCase {
|
||||
myFixture.enableInspections(PyUnresolvedReferencesInspection.class);
|
||||
myFixture.configureByFile("UnresolvedRefNoCreateFunction.py");
|
||||
myFixture.checkHighlighting(true, false, false);
|
||||
final IntentionAction intentionAction = myFixture.getAvailableIntention(
|
||||
PyBundle.message("QFIX.unresolved.reference.create.function.$0", "ref"));
|
||||
final IntentionAction intentionAction = myFixture.getAvailableIntention(PyBundle.message("QFIX.unresolved.reference.create.function.$0", "ref"));
|
||||
assertNull(intentionAction);
|
||||
}
|
||||
|
||||
public void testReplaceNotEqOperator() {
|
||||
doInspectionTest("ReplaceNotEqOperator.py", PyCompatibilityInspection.class,
|
||||
PyBundle.message("INTN.replace.noteq.operator"), true, true);
|
||||
doInspectionTest(PyCompatibilityInspection.class, PyBundle.message("INTN.replace.noteq.operator"), true, true);
|
||||
}
|
||||
|
||||
public void testListCreation() {
|
||||
doInspectionTest("ListCreation.py", PyListCreationInspection.class,
|
||||
PyBundle.message("QFIX.list.creation"), true, true);
|
||||
doInspectionTest(PyListCreationInspection.class, PyBundle.message("QFIX.list.creation"), true, true);
|
||||
}
|
||||
|
||||
public void testConvertSingleQuotedDocstring() { //PY-1445
|
||||
doInspectionTest("ConvertSingleQuotedDocstring.py", PySingleQuotedDocstringInspection.class,
|
||||
PyBundle.message("QFIX.convert.single.quoted.docstring"), true, true);
|
||||
// PY-1445
|
||||
public void testConvertSingleQuotedDocstring() {
|
||||
doInspectionTest(PySingleQuotedDocstringInspection.class, PyBundle.message("QFIX.convert.single.quoted.docstring"), true, true);
|
||||
}
|
||||
|
||||
public void testConvertSingleQuotedDocstringEscape() { //PY-8926
|
||||
doInspectionTest("ConvertSingleQuotedDocstringEscape.py", PySingleQuotedDocstringInspection.class,
|
||||
PyBundle.message("QFIX.convert.single.quoted.docstring"), true, true);
|
||||
// PY-8926
|
||||
public void testConvertSingleQuotedDocstringEscape() {
|
||||
doInspectionTest(PySingleQuotedDocstringInspection.class, PyBundle.message("QFIX.convert.single.quoted.docstring"), true, true);
|
||||
}
|
||||
|
||||
public void testDefaultArgument() { //PY-3127
|
||||
doInspectionTest("DefaultArgument.py", PyDefaultArgumentInspection.class,
|
||||
PyBundle.message("QFIX.default.argument"), true, true);
|
||||
// PY-3127
|
||||
public void testDefaultArgument() {
|
||||
doInspectionTest(PyDefaultArgumentInspection.class, PyBundle.message("QFIX.default.argument"), true, true);
|
||||
}
|
||||
|
||||
public void testDefaultArgumentEmptyList() {
|
||||
doInspectionTest("DefaultArgumentEmptyList.py", PyDefaultArgumentInspection.class,
|
||||
PyBundle.message("QFIX.default.argument"), true, true);
|
||||
doInspectionTest(PyDefaultArgumentInspection.class, PyBundle.message("QFIX.default.argument"), true, true);
|
||||
}
|
||||
|
||||
public void testPyArgumentEqualDefault() { //PY-3125
|
||||
doInspectionTest("ArgumentEqualDefault.py", PyArgumentEqualDefaultInspection.class,
|
||||
PyBundle.message("QFIX.remove.argument.equal.default"), true, true);
|
||||
// PY-3125
|
||||
public void testArgumentEqualDefault() {
|
||||
doInspectionTest(PyArgumentEqualDefaultInspection.class, PyBundle.message("QFIX.remove.argument.equal.default"), true, true);
|
||||
}
|
||||
|
||||
public void testAddCallSuper() { //PY-3315
|
||||
doInspectionTest("AddCallSuper.py", PyMissingConstructorInspection.class,
|
||||
PyBundle.message("QFIX.add.super"), true, true);
|
||||
// PY-3315
|
||||
public void testAddCallSuper() {
|
||||
doInspectionTest(PyMissingConstructorInspection.class, PyBundle.message("QFIX.add.super"), true, true);
|
||||
}
|
||||
|
||||
public void testAddCallSuper1() { //PY-4017
|
||||
doInspectionTest("AddCallSuper1.py", PyMissingConstructorInspection.class,
|
||||
PyBundle.message("QFIX.add.super"), true, true);
|
||||
// PY-4017
|
||||
public void testAddCallSuper1() {
|
||||
doInspectionTest(PyMissingConstructorInspection.class, PyBundle.message("QFIX.add.super"), true, true);
|
||||
}
|
||||
|
||||
public void testAddCallSuperPass() { //PY-8654
|
||||
doInspectionTest("AddCallSuperPass.py", PyMissingConstructorInspection.class,
|
||||
PyBundle.message("QFIX.add.super"), true, true);
|
||||
// PY-8654
|
||||
public void testAddCallSuperPass() {
|
||||
doInspectionTest(PyMissingConstructorInspection.class, PyBundle.message("QFIX.add.super"), true, true);
|
||||
}
|
||||
|
||||
//PY-491, PY-13297
|
||||
// PY-15867
|
||||
public void testAddCallSuperOptionalAndRequiredParamsNameCollision() {
|
||||
doInspectionTest(PyMissingConstructorInspection.class, PyBundle.message("QFIX.add.super"), true, true);
|
||||
}
|
||||
|
||||
// PY-15927
|
||||
public void testAddCallSuperConflictingTupleParam() {
|
||||
doInspectionTest(PyMissingConstructorInspection.class, PyBundle.message("QFIX.add.super"), true, true);
|
||||
}
|
||||
|
||||
// PY-491, PY-13297
|
||||
public void testAddEncoding() {
|
||||
doInspectionTest("AddEncoding.py", PyMandatoryEncodingInspection.class,
|
||||
PyBundle.message("QFIX.add.encoding"), true, true);
|
||||
doInspectionTest(PyMandatoryEncodingInspection.class, PyBundle.message("QFIX.add.encoding"), true, true);
|
||||
}
|
||||
|
||||
// PY-13297
|
||||
public void testAddEncodingAtLastLine() {
|
||||
doInspectionTest("AddEncodingAtLastLine.py", PyMandatoryEncodingInspection.class,
|
||||
PyBundle.message("QFIX.add.encoding"), true, true);
|
||||
doInspectionTest(PyMandatoryEncodingInspection.class, PyBundle.message("QFIX.add.encoding"), true, true);
|
||||
}
|
||||
|
||||
public void testRemoveDecorator() { //PY-3348
|
||||
doInspectionTest("RemoveDecorator.py", PyDecoratorInspection.class,
|
||||
PyBundle.message("QFIX.remove.decorator"), true, true);
|
||||
// PY-3348
|
||||
public void testRemoveDecorator() {
|
||||
doInspectionTest(PyDecoratorInspection.class, PyBundle.message("QFIX.remove.decorator"), true, true);
|
||||
}
|
||||
|
||||
public void testAddParameter() {
|
||||
doInspectionTest("AddParameter.py", PyUnresolvedReferencesInspection.class,
|
||||
doInspectionTest(PyUnresolvedReferencesInspection.class,
|
||||
PyBundle.message("QFIX.unresolved.reference.add.param.$0", "test"), true, true);
|
||||
}
|
||||
|
||||
public void testRenameUnresolvedReference() { //PY-6595
|
||||
doInspectionTest("RenameUnresolvedReference.py", PyUnresolvedReferencesInspection.class,
|
||||
PyBundle.message("QFIX.rename.unresolved.reference"), true, true);
|
||||
// PY-6595
|
||||
public void testRenameUnresolvedReference() {
|
||||
doInspectionTest(PyUnresolvedReferencesInspection.class, PyBundle.message("QFIX.rename.unresolved.reference"), true, true);
|
||||
}
|
||||
|
||||
public void testSetFunctionToLiteral() { //PY-3120
|
||||
// PY-3120
|
||||
public void testSetFunctionToLiteral() {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON27, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
doInspectionTest("SetFunctionToLiteral.py", PySetFunctionToLiteralInspection.class,
|
||||
PyBundle.message("QFIX.replace.function.set.with.literal"), true, true);
|
||||
doInspectionTest(PySetFunctionToLiteralInspection.class, PyBundle.message("QFIX.replace.function.set.with.literal"), true, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testDictComprehensionToCall() {
|
||||
doInspectionTest("DictComprehensionToCall.py", PyCompatibilityInspection.class,
|
||||
PyBundle.message("INTN.convert.dict.comp.to"), true, true);
|
||||
doInspectionTest(PyCompatibilityInspection.class, PyBundle.message("INTN.convert.dict.comp.to"), true, true);
|
||||
}
|
||||
|
||||
public void testDocstringParams() { //PY-3394
|
||||
// PY-3394
|
||||
public void testDocstringParams() {
|
||||
PyDocumentationSettings documentationSettings = PyDocumentationSettings.getInstance(myFixture.getModule());
|
||||
documentationSettings.setFormat(DocStringFormat.EPYTEXT);
|
||||
try {
|
||||
doInspectionTest("DocstringParams.py", PyDocstringInspection.class,
|
||||
PyBundle.message("QFIX.docstring.add.$0", "b"), true, true);
|
||||
doInspectionTest(PyDocstringInspection.class,
|
||||
PyBundle.message("QFIX.docstring.add.$0", "b"), true, true);
|
||||
}
|
||||
finally {
|
||||
documentationSettings.setFormat(DocStringFormat.PLAIN);
|
||||
@@ -418,20 +425,19 @@ public class PyQuickFixTest extends PyTestCase {
|
||||
PyDocumentationSettings documentationSettings = PyDocumentationSettings.getInstance(myFixture.getModule());
|
||||
documentationSettings.setFormat(DocStringFormat.EPYTEXT);
|
||||
try {
|
||||
doInspectionTest("DocstringParams1.py", PyDocstringInspection.class,
|
||||
PyBundle.message("QFIX.docstring.remove.$0", "c"), true, true);
|
||||
doInspectionTest(PyDocstringInspection.class, PyBundle.message("QFIX.docstring.remove.$0", "c"), true, true);
|
||||
}
|
||||
finally {
|
||||
documentationSettings.setFormat(DocStringFormat.PLAIN);
|
||||
}
|
||||
}
|
||||
|
||||
public void testDocstringParams2() { //PY-4964
|
||||
// PY-4964
|
||||
public void testDocstringParams2() {
|
||||
PyDocumentationSettings documentationSettings = PyDocumentationSettings.getInstance(myFixture.getModule());
|
||||
documentationSettings.setFormat(DocStringFormat.EPYTEXT);
|
||||
try {
|
||||
doInspectionTest("DocstringParams2.py", PyDocstringInspection.class,
|
||||
PyBundle.message("QFIX.docstring.add.$0", "ham"), true, true);
|
||||
doInspectionTest(PyDocstringInspection.class, PyBundle.message("QFIX.docstring.add.$0", "ham"), true, true);
|
||||
}
|
||||
finally {
|
||||
documentationSettings.setFormat(DocStringFormat.PLAIN);
|
||||
@@ -449,9 +455,9 @@ public class PyQuickFixTest extends PyTestCase {
|
||||
myFixture.checkResultByFile(graftBeforeExt(testFiles[0], "_after"));
|
||||
}
|
||||
|
||||
public void testUnresolvedRefTrueFalse() { //PY-3051
|
||||
doInspectionTest("UnresolvedRefTrueFalse.py", PyUnresolvedReferencesInspection.class,
|
||||
PyBundle.message("QFIX.unresolved.reference.replace.$0", "True"), true, true);
|
||||
// PY-3051
|
||||
public void testUnresolvedRefTrueFalse() {
|
||||
doInspectionTest(PyUnresolvedReferencesInspection.class, PyBundle.message("QFIX.unresolved.reference.replace.$0", "True"), true, true);
|
||||
}
|
||||
|
||||
public void testUnnecessaryBackslashInArgumentList() {
|
||||
@@ -498,43 +504,22 @@ public class PyQuickFixTest extends PyTestCase {
|
||||
myFixture.checkHighlighting(true, false, true);
|
||||
}
|
||||
|
||||
// PY-8991
|
||||
public void testRemoveUnicodePrefixFromGluedStringNodesWithSlash() {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON32, new Runnable() {
|
||||
public void run() {
|
||||
myFixture.configureByFile(getTestName(false) + ".py");
|
||||
myFixture.checkHighlighting(true, false, false);
|
||||
final IntentionAction intentionAction = myFixture.findSingleIntention(PyBundle.message("INTN.remove.leading.$0", "U"));
|
||||
assertNotNull(intentionAction);
|
||||
myFixture.launchAction(intentionAction);
|
||||
myFixture.checkResultByFile(getTestName(false) + "_after.py");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// PY-8990
|
||||
public void testRemoveUnicodePrefixFromGluedStringNodesInParenthesis() {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON32, new Runnable() {
|
||||
public void run() {
|
||||
myFixture.configureByFile(getTestName(false) + ".py");
|
||||
myFixture.checkHighlighting(true, false, false);
|
||||
final IntentionAction intentionAction = myFixture.findSingleIntention(PyBundle.message("INTN.remove.leading.$0", "U"));
|
||||
assertNotNull(intentionAction);
|
||||
myFixture.launchAction(intentionAction);
|
||||
myFixture.checkResultByFile(getTestName(false) + "_after.py");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNls
|
||||
protected String getTestDataPath() {
|
||||
return PythonTestUtil.getTestDataPath() + "/inspections/";
|
||||
}
|
||||
|
||||
protected void doInspectionTest(@TestDataFile @NonNls String testFileName,
|
||||
final Class inspectionClass,
|
||||
@NonNls String quickFixName,
|
||||
private void doInspectionTest(@NotNull Class inspectionClass,
|
||||
@NotNull String quickFixName,
|
||||
boolean applyFix,
|
||||
boolean available) {
|
||||
doInspectionTest(getTestName(false) + ".py", inspectionClass, quickFixName, applyFix, available);
|
||||
}
|
||||
|
||||
protected void doInspectionTest(@TestDataFile @NonNls @NotNull String testFileName,
|
||||
@NotNull Class inspectionClass,
|
||||
@NonNls @NotNull String quickFixName,
|
||||
boolean applyFix,
|
||||
boolean available) {
|
||||
doInspectionTest(new String[]{testFileName}, inspectionClass, quickFixName, applyFix, available);
|
||||
@@ -550,9 +535,9 @@ public class PyQuickFixTest extends PyTestCase {
|
||||
* @param available true if the fix should be available, false if it should be explicitly not available.
|
||||
* @throws Exception
|
||||
*/
|
||||
protected void doInspectionTest(@NonNls String[] testFiles,
|
||||
final Class inspectionClass,
|
||||
@NonNls String quickFixName,
|
||||
protected void doInspectionTest(@NonNls @NotNull String[] testFiles,
|
||||
@NotNull Class inspectionClass,
|
||||
@NonNls @NotNull String quickFixName,
|
||||
boolean applyFix,
|
||||
boolean available) {
|
||||
myFixture.enableInspections(inspectionClass);
|
||||
|
||||
@@ -48,7 +48,7 @@ public class WebBrowserServiceImpl extends WebBrowserService {
|
||||
VirtualFile file = request.getVirtualFile();
|
||||
return file instanceof LightVirtualFile || !request.getFile().getViewProvider().isPhysical()
|
||||
? Collections.<Url>emptyList()
|
||||
: Collections.singleton(Urls.newFromVirtualFile(file));
|
||||
: Collections.singletonList(Urls.newFromVirtualFile(file));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
Reference in New Issue
Block a user