diff --git a/java/java-impl/java-impl.iml b/java/java-impl/java-impl.iml
index cf601bbd0f76..ee71056b6734 100644
--- a/java/java-impl/java-impl.iml
+++ b/java/java-impl/java-impl.iml
@@ -56,11 +56,11 @@
+
-
-
+
\ No newline at end of file
diff --git a/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java b/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java
index cb215d06380d..0a61a7c94c06 100644
--- a/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java
+++ b/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java
@@ -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 findUrlForClass(PsiClass aClass) {
+ public static List 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 findUrlForVirtualFile(final Project project, final VirtualFile virtualFile, final String relPath) {
+ public static List 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 orderEntries = fileIndex.getOrderEntriesForFile(virtualFile);
- for (OrderEntry orderEntry : orderEntries) {
- final String[] files = JavadocOrderRootType.getUrls(orderEntry);
- final List 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 urls = file == null ? null : BuiltInWebBrowserUrlProvider.getUrls(file, project, null);
+ if (!ContainerUtil.isEmpty(urls)) {
+ List result = new SmartList();
+ for (Url url : urls) {
+ result.add(url.toExternalForm());
+ }
+ return result;
+ }
+ }
+ }
+
+ List httpRoot = PlatformDocumentationUtil.getHttpRoots(JavadocOrderRootType.getUrls(orderEntry), relPath);
+ if (httpRoot != null) {
+ return httpRoot;
+ }
}
return null;
}
diff --git a/platform/built-in-server/src/org/jetbrains/builtInWebServer/DefaultWebServerRootsProvider.java b/platform/built-in-server/src/org/jetbrains/builtInWebServer/DefaultWebServerRootsProvider.java
index fa09f74d71ea..70ed18f5f98b 100644
--- a/platform/built-in-server/src/org/jetbrains/builtInWebServer/DefaultWebServerRootsProvider.java
+++ b/platform/built-in-server/src/org/jetbrains/builtInWebServer/DefaultWebServerRootsProvider.java
@@ -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 {
+ 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 &&
diff --git a/platform/core-impl/src/com/intellij/codeInsight/documentation/PlatformDocumentationUtil.java b/platform/core-impl/src/com/intellij/codeInsight/documentation/PlatformDocumentationUtil.java
index 966d8173c150..fa519f0249bb 100644
--- a/platform/core-impl/src/com/intellij/codeInsight/documentation/PlatformDocumentationUtil.java
+++ b/platform/core-impl/src/com/intellij/codeInsight/documentation/PlatformDocumentationUtil.java
@@ -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 getHttpRoots(final String[] roots, String relPath) {
- final ArrayList result = new ArrayList();
+ public static List getHttpRoots(@NotNull String[] roots, String relPath) {
+ List result = new SmartList();
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());
+ }
}
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java
index d687848a4949..36e8f4005070 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java
@@ -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 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 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
diff --git a/platform/lang-impl/src/com/intellij/ide/actions/ExternalJavaDocAction.java b/platform/lang-impl/src/com/intellij/ide/actions/ExternalJavaDocAction.java
index 9d73cd569c40..f974d35afd8d 100644
--- a/platform/lang-impl/src/com/intellij/ide/actions/ExternalJavaDocAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/actions/ExternalJavaDocAction.java
@@ -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 urls, Component component) {
- final HashSet set = new HashSet(urls);
+ public static void showExternalJavadoc(@NotNull List urls, Component component) {
+ Set set = new THashSet(urls);
if (set.size() > 1) {
JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep("Choose external documentation root", ArrayUtil.toStringArray(set)) {
@Override
diff --git a/platform/platform-api/src/com/intellij/ide/browsers/BrowserLauncherAppless.java b/platform/platform-api/src/com/intellij/ide/browsers/BrowserLauncherAppless.java
index 2385d0000bee..c7f3989c8b7c 100644
--- a/platform/platform-api/src/com/intellij/ide/browsers/BrowserLauncherAppless.java
+++ b/platform/platform-api/src/com/intellij/ide/browsers/BrowserLauncherAppless.java
@@ -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);
diff --git a/platform/platform-api/src/com/intellij/openapi/keymap/KeyboardSettingsExternalizable.java b/platform/platform-api/src/com/intellij/openapi/keymap/KeyboardSettingsExternalizable.java
index 8f4c6f6b4329..e96abb6fd18f 100644
--- a/platform/platform-api/src/com/intellij/openapi/keymap/KeyboardSettingsExternalizable.java
+++ b/platform/platform-api/src/com/intellij/openapi/keymap/KeyboardSettingsExternalizable.java
@@ -35,7 +35,7 @@ import java.util.Locale;
)
public class KeyboardSettingsExternalizable implements PersistentStateComponent {
- 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;
}
diff --git a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java
index f6a0b2d9e7fb..ad541c2675dc 100644
--- a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java
+++ b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java
@@ -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
diff --git a/python/src/com/jetbrains/python/inspections/quickfix/AddCallSuperQuickFix.java b/python/src/com/jetbrains/python/inspections/quickfix/AddCallSuperQuickFix.java
index c8ac88af9da1..d6568240ecf4 100644
--- a/python/src/com/jetbrains/python/inspections/quickfix/AddCallSuperQuickFix.java
+++ b/python/src/com/jetbrains/python/inspections/quickfix/AddCallSuperQuickFix.java
@@ -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"
+ *
* 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> couple = buildNewFunctionParamsAndSuperInitCallArgs(problemFunction, superInit);
+ final List 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 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 problemParams = new ArrayList();
- final List functionParams = new ArrayList();
- 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> buildNewFunctionParamsAndSuperInitCallArgs(@NotNull PyFunction origInit,
+ @NotNull PyFunction superInit) {
+ final List newFunctionParams = new ArrayList();
+ final List superCallArgs = new ArrayList();
+
+ 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 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 problemParams, @NotNull final List 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 myRequiredParams = new ArrayList();
+ /**
+ * Parameters with default value that come before first "*..." parameter.
+ */
+ private final List myOptionalParams = new ArrayList();
+ /**
+ * 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 myRequiredKwOnlyParams = new ArrayList();
+ /**
+ * Parameters with default value that come after first "*..." parameter.
+ */
+ private final List myOptionalKwOnlyParams = new ArrayList();
+ /**
+ * Parameter of form "**kwargs" (keyword vararg).
+ */
+ private final PyParameter myKeywordContainerParam;
+
+ private final Set myAllParameterNames = new LinkedHashSet();
+
+ 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 getRequiredParameters() {
+ return Collections.unmodifiableList(myRequiredParams);
+ }
+
+ @NotNull
+ public List getOptionalParameters() {
+ return Collections.unmodifiableList(myOptionalParams);
+ }
+
+ @Nullable
+ public PyParameter getPositionalContainerParameter() {
+ return myPositionalContainerParam;
+ }
+
+ @Nullable
+ public PyParameter getSingleStarParameter() {
+ return mySingleStarParam;
+ }
+
+ @NotNull
+ public List getRequiredKeywordOnlyParameters() {
+ return Collections.unmodifiableList(myRequiredKwOnlyParams);
+ }
+
+ @NotNull
+ public List getOptionalKeywordOnlyParameters() {
+ return Collections.unmodifiableList(myOptionalKwOnlyParams);
+ }
+
+ @Nullable
+ public PyParameter getKeywordContainerParameter() {
+ return myKeywordContainerParam;
+ }
+
+ @NotNull
+ public Set getAllParameterNames() {
+ return Collections.unmodifiableSet(myAllParameterNames);
+ }
+ }
+
+ @NotNull
+ private static List collectParameterNames(@NotNull PyParameter param) {
+ final List result = new ArrayList();
+ collectParameterNames(param, result);
+ return result;
+ }
+
+
+ private static void collectParameterNames(@NotNull PyParameter param, @NotNull Collection 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());
}
}
}
diff --git a/python/testData/inspections/AddCallSuperAnnotations.py b/python/testData/inspections/AddCallSuperAnnotations.py
deleted file mode 100644
index b50ae1b4fb72..000000000000
--- a/python/testData/inspections/AddCallSuperAnnotations.py
+++ /dev/null
@@ -1,8 +0,0 @@
-class Example1:
- def __init__(self, field1: str):
- self.field1 = field1
-
-
-class Example2(Example1):
- def __init__(self): ## Missed call to __init__ of super class
- pass
\ No newline at end of file
diff --git a/python/testData/inspections/AddCallSuperAnnotations_after.py b/python/testData/inspections/AddCallSuperAnnotations_after.py
deleted file mode 100644
index 4bfd08c375e3..000000000000
--- a/python/testData/inspections/AddCallSuperAnnotations_after.py
+++ /dev/null
@@ -1,8 +0,0 @@
-class Example1:
- def __init__(self, field1: str):
- self.field1 = field1
-
-
-class Example2(Example1):
- def __init__(self, field1):
- super().__init__(field1)
\ No newline at end of file
diff --git a/python/testData/inspections/AddCallSuperConflictingTupleParam.py b/python/testData/inspections/AddCallSuperConflictingTupleParam.py
new file mode 100644
index 000000000000..276e16dc2e73
--- /dev/null
+++ b/python/testData/inspections/AddCallSuperConflictingTupleParam.py
@@ -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):
+ pass
\ No newline at end of file
diff --git a/python/testData/inspections/AddCallSuperConflictingTupleParam_after.py b/python/testData/inspections/AddCallSuperConflictingTupleParam_after.py
new file mode 100644
index 000000000000..5a41d4a81d09
--- /dev/null
+++ b/python/testData/inspections/AddCallSuperConflictingTupleParam_after.py
@@ -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))
\ No newline at end of file
diff --git a/python/testData/inspections/AddCallSuperKeywordOnlyParamInInit.py b/python/testData/inspections/AddCallSuperKeywordOnlyParamInInit.py
new file mode 100644
index 000000000000..e1da8962d217
--- /dev/null
+++ b/python/testData/inspections/AddCallSuperKeywordOnlyParamInInit.py
@@ -0,0 +1,7 @@
+class A:
+ def __init__(self, a):
+ pass
+
+class B(A):
+ def __init__(self, b, c=1, *args, kw_only):
+ pass
\ No newline at end of file
diff --git a/python/testData/inspections/AddCallSuperKeywordOnlyParamInInit_after.py b/python/testData/inspections/AddCallSuperKeywordOnlyParamInInit_after.py
new file mode 100644
index 000000000000..925cac6746a3
--- /dev/null
+++ b/python/testData/inspections/AddCallSuperKeywordOnlyParamInInit_after.py
@@ -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)
\ No newline at end of file
diff --git a/python/testData/inspections/AddCallSuperKeywordOnlyParamInSuperInit.py b/python/testData/inspections/AddCallSuperKeywordOnlyParamInSuperInit.py
new file mode 100644
index 000000000000..5248dd92742a
--- /dev/null
+++ b/python/testData/inspections/AddCallSuperKeywordOnlyParamInSuperInit.py
@@ -0,0 +1,8 @@
+class A:
+ def __init__(self, a, b=1, *args, kw_only):
+ pass
+
+
+class B(A):
+ def __init__(self, c):
+ pass
\ No newline at end of file
diff --git a/python/testData/inspections/AddCallSuperKeywordOnlyParamInSuperInit_after.py b/python/testData/inspections/AddCallSuperKeywordOnlyParamInSuperInit_after.py
new file mode 100644
index 000000000000..0ee340e47d36
--- /dev/null
+++ b/python/testData/inspections/AddCallSuperKeywordOnlyParamInSuperInit_after.py
@@ -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)
\ No newline at end of file
diff --git a/python/testData/inspections/AddCallSuperOptionalAndRequiredParamsNameCollision.py b/python/testData/inspections/AddCallSuperOptionalAndRequiredParamsNameCollision.py
new file mode 100644
index 000000000000..3d3bb7d4b64e
--- /dev/null
+++ b/python/testData/inspections/AddCallSuperOptionalAndRequiredParamsNameCollision.py
@@ -0,0 +1,8 @@
+class A:
+ def __init__(self, a):
+ pass
+
+
+class B(A):
+ def __init__(self, a=1):
+ pass
\ No newline at end of file
diff --git a/python/testData/inspections/AddCallSuperOptionalAndRequiredParamsNameCollision_after.py b/python/testData/inspections/AddCallSuperOptionalAndRequiredParamsNameCollision_after.py
new file mode 100644
index 000000000000..1693904e6b58
--- /dev/null
+++ b/python/testData/inspections/AddCallSuperOptionalAndRequiredParamsNameCollision_after.py
@@ -0,0 +1,8 @@
+class A:
+ def __init__(self, a):
+ pass
+
+
+class B(A):
+ def __init__(self, a=1):
+ A.__init__(self, a)
\ No newline at end of file
diff --git a/python/testData/inspections/AddCallSuperSingleStarParamInSuperInit.py b/python/testData/inspections/AddCallSuperSingleStarParamInSuperInit.py
new file mode 100644
index 000000000000..7ff489252191
--- /dev/null
+++ b/python/testData/inspections/AddCallSuperSingleStarParamInSuperInit.py
@@ -0,0 +1,7 @@
+class A:
+ def __init__(self, *, kw_only, optional_kw_only=None):
+ pass
+
+class B(A):
+ def __init__(self):
+ pass
\ No newline at end of file
diff --git a/python/testData/inspections/AddCallSuperSingleStarParamInSuperInitAndVarargInInit.py b/python/testData/inspections/AddCallSuperSingleStarParamInSuperInitAndVarargInInit.py
new file mode 100644
index 000000000000..afca366ff1e3
--- /dev/null
+++ b/python/testData/inspections/AddCallSuperSingleStarParamInSuperInitAndVarargInInit.py
@@ -0,0 +1,7 @@
+class A:
+ def __init__(self, *, kw_only):
+ pass
+
+class B(A):
+ def __init__(self, *args, another_kw_only):
+ pass
\ No newline at end of file
diff --git a/python/testData/inspections/AddCallSuperSingleStarParamInSuperInitAndVarargInInit_after.py b/python/testData/inspections/AddCallSuperSingleStarParamInSuperInitAndVarargInInit_after.py
new file mode 100644
index 000000000000..01cf279b21fc
--- /dev/null
+++ b/python/testData/inspections/AddCallSuperSingleStarParamInSuperInitAndVarargInInit_after.py
@@ -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)
\ No newline at end of file
diff --git a/python/testData/inspections/AddCallSuperSingleStarParamInSuperInit_after.py b/python/testData/inspections/AddCallSuperSingleStarParamInSuperInit_after.py
new file mode 100644
index 000000000000..1eb8c4228300
--- /dev/null
+++ b/python/testData/inspections/AddCallSuperSingleStarParamInSuperInit_after.py
@@ -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)
\ No newline at end of file
diff --git a/python/testData/inspections/AddCallSuperTypeAnnotationsPreserved.py b/python/testData/inspections/AddCallSuperTypeAnnotationsPreserved.py
new file mode 100644
index 000000000000..76b33e20063e
--- /dev/null
+++ b/python/testData/inspections/AddCallSuperTypeAnnotationsPreserved.py
@@ -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, *, e:bytes) -> list:
+ pass
\ No newline at end of file
diff --git a/python/testData/inspections/AddCallSuperTypeAnnotationsPreserved_after.py b/python/testData/inspections/AddCallSuperTypeAnnotationsPreserved_after.py
new file mode 100644
index 000000000000..c8b5b3e67c00
--- /dev/null
+++ b/python/testData/inspections/AddCallSuperTypeAnnotationsPreserved_after.py
@@ -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)
\ No newline at end of file
diff --git a/python/testSrc/com/jetbrains/python/Py3QuickFixTest.java b/python/testSrc/com/jetbrains/python/Py3QuickFixTest.java
index f757da9f3fac..10ed5fa597b4 100644
--- a/python/testSrc/com/jetbrains/python/Py3QuickFixTest.java
+++ b/python/testSrc/com/jetbrains/python/Py3QuickFixTest.java
@@ -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);
diff --git a/python/testSrc/com/jetbrains/python/PyQuickFixTest.java b/python/testSrc/com/jetbrains/python/PyQuickFixTest.java
index 9a55254d8287..1fc8572ae262 100644
--- a/python/testSrc/com/jetbrains/python/PyQuickFixTest.java
+++ b/python/testSrc/com/jetbrains/python/PyQuickFixTest.java
@@ -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);
diff --git a/xml/impl/src/com/intellij/ide/browsers/impl/WebBrowserServiceImpl.java b/xml/impl/src/com/intellij/ide/browsers/impl/WebBrowserServiceImpl.java
index 6cd24659c003..097a1d1859fc 100644
--- a/xml/impl/src/com/intellij/ide/browsers/impl/WebBrowserServiceImpl.java
+++ b/xml/impl/src/com/intellij/ide/browsers/impl/WebBrowserServiceImpl.java
@@ -48,7 +48,7 @@ public class WebBrowserServiceImpl extends WebBrowserService {
VirtualFile file = request.getVirtualFile();
return file instanceof LightVirtualFile || !request.getFile().getViewProvider().isPhysical()
? Collections.emptyList()
- : Collections.singleton(Urls.newFromVirtualFile(file));
+ : Collections.singletonList(Urls.newFromVirtualFile(file));
}
@NotNull