mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'python-fixes'
Conflicts: python/src/com/jetbrains/python/inspections/quickfix/AddFunctionQuickFix.java
This commit is contained in:
@@ -15,10 +15,7 @@
|
||||
*/
|
||||
package com.jetbrains.python.psi;
|
||||
|
||||
import com.intellij.injected.editor.VirtualFileWindow;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -131,34 +128,6 @@ public enum LanguageLevel {
|
||||
|
||||
public static final Key<LanguageLevel> KEY = new Key<LanguageLevel>("python.language.level");
|
||||
|
||||
@NotNull
|
||||
public static LanguageLevel forFile(@NotNull VirtualFile virtualFile) {
|
||||
if (virtualFile instanceof VirtualFileWindow)
|
||||
virtualFile = ((VirtualFileWindow)virtualFile).getDelegate();
|
||||
|
||||
// Most of the cases should be handled by this one, PyLanguageLevelPusher pushes folders only
|
||||
final VirtualFile folder = virtualFile.getParent();
|
||||
if (folder != null) {
|
||||
final LanguageLevel level = folder.getUserData(KEY);
|
||||
if (level != null) return level;
|
||||
}
|
||||
else {
|
||||
// However this allows us to setup language level per file manually
|
||||
// in case when it is LightVirtualFile
|
||||
final LanguageLevel level = virtualFile.getUserData(KEY);
|
||||
if (level != null) return level;
|
||||
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
final LanguageLevel languageLevel = FORCE_LANGUAGE_LEVEL;
|
||||
if (languageLevel != null) {
|
||||
return languageLevel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return getDefault();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static LanguageLevel forElement(@NotNull PsiElement element) {
|
||||
final PsiFile containingFile = element.getContainingFile();
|
||||
|
||||
+5
-7
@@ -22,7 +22,6 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiWhiteSpace;
|
||||
@@ -35,7 +34,10 @@ import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyBuiltinCache;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import com.jetbrains.python.psi.impl.PyStringLiteralExpressionImpl;
|
||||
import com.jetbrains.python.psi.types.*;
|
||||
import com.jetbrains.python.psi.types.PyClassType;
|
||||
import com.jetbrains.python.psi.types.PyType;
|
||||
import com.jetbrains.python.psi.types.PyTypeChecker;
|
||||
import com.jetbrains.python.psi.types.TypeEvalContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -230,11 +232,7 @@ public class ConvertFormatOperatorToMethodIntention extends BaseIntentionAction
|
||||
if (binaryExpression == null) {
|
||||
return false;
|
||||
}
|
||||
final VirtualFile virtualFile = binaryExpression.getContainingFile().getVirtualFile();
|
||||
if (virtualFile == null) {
|
||||
return false;
|
||||
}
|
||||
final LanguageLevel languageLevel = LanguageLevel.forFile(virtualFile);
|
||||
final LanguageLevel languageLevel = LanguageLevel.forElement(binaryExpression);
|
||||
if (languageLevel.isOlderThan(LanguageLevel.PYTHON26)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ public class PyUserSkeletonsUtil {
|
||||
final PsiDirectory psiDirectory = PsiManager.getInstance(project).findDirectory(directory);
|
||||
PsiElement fileSkeleton = new QualifiedNameResolverImpl(qName).resolveModuleAt(psiDirectory);
|
||||
if (fileSkeleton instanceof PsiDirectory) {
|
||||
fileSkeleton = PyUtil.getPackageElement((PsiDirectory)fileSkeleton);
|
||||
fileSkeleton = PyUtil.getPackageElement((PsiDirectory)fileSkeleton, foothold);
|
||||
}
|
||||
if (fileSkeleton instanceof PyFile) {
|
||||
cache.put(cacheQName, Collections.singletonList(fileSkeleton));
|
||||
|
||||
@@ -21,10 +21,11 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.containers.FactoryMap;
|
||||
import com.jetbrains.python.console.parsing.PyConsoleHighlightingLexer;
|
||||
import com.jetbrains.python.console.PydevConsoleRunner;
|
||||
import com.jetbrains.python.lexer.PythonHighlightingLexer;
|
||||
import com.jetbrains.python.psi.LanguageLevel;
|
||||
import com.jetbrains.python.psi.PyUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
@@ -51,11 +52,10 @@ public class PySyntaxHighlighterFactory extends SyntaxHighlighterFactory {
|
||||
};
|
||||
|
||||
@NotNull
|
||||
public SyntaxHighlighter getSyntaxHighlighter(final Project project, final VirtualFile virtualFile) {
|
||||
LanguageLevel languageLevel = virtualFile != null ? LanguageLevel.forFile(virtualFile) : LanguageLevel.getDefault();
|
||||
if (virtualFile != null && PydevConsoleRunner.isInPydevConsole(virtualFile)) {
|
||||
return myConsoleMap.get(languageLevel);
|
||||
}
|
||||
return myMap.get(languageLevel);
|
||||
public SyntaxHighlighter getSyntaxHighlighter(@Nullable final Project project, @Nullable final VirtualFile virtualFile) {
|
||||
final LanguageLevel level = project != null && virtualFile != null ?
|
||||
PyUtil.getLanguageLevelForVirtualFile(project, virtualFile) :
|
||||
LanguageLevel.getDefault();
|
||||
return myMap.get(level);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,19 +21,18 @@ import com.intellij.codeInspection.ProblemHighlightType;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.util.PsiElementFilter;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.QualifiedName;
|
||||
import com.intellij.util.Processor;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.inspections.quickfix.RenameParameterQuickFix;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyBuiltinCache;
|
||||
import com.intellij.psi.util.QualifiedName;
|
||||
import com.jetbrains.python.psi.types.PyClassType;
|
||||
import com.jetbrains.python.psi.types.PyNoneType;
|
||||
import com.jetbrains.python.psi.types.PyType;
|
||||
@@ -79,13 +78,7 @@ public class PyPropertyDefinitionInspection extends PyInspection {
|
||||
super(holder, session);
|
||||
PsiFile psiFile = session.getFile();
|
||||
// save us continuous checks for level, module, stc
|
||||
LanguageLevel level = null;
|
||||
if (psiFile != null) {
|
||||
VirtualFile vfile = psiFile.getVirtualFile();
|
||||
if (vfile != null) level = LanguageLevel.forFile(vfile);
|
||||
}
|
||||
if (level == null) level = LanguageLevel.getDefault();
|
||||
myLevel = level;
|
||||
myLevel = LanguageLevel.forElement(psiFile);
|
||||
// string classes
|
||||
final List<PyClass> string_classes = new ArrayList<PyClass>(2);
|
||||
final PyBuiltinCache builtins = PyBuiltinCache.getInstance(psiFile);
|
||||
|
||||
@@ -17,7 +17,6 @@ package com.jetbrains.python.inspections;
|
||||
|
||||
import com.intellij.codeInspection.LocalInspectionToolSession;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
@@ -52,11 +51,7 @@ public class PyRaisingNewStyleClassInspection extends PyInspection {
|
||||
|
||||
@Override
|
||||
public void visitPyRaiseStatement(PyRaiseStatement node) {
|
||||
final VirtualFile virtualFile = node.getContainingFile().getVirtualFile();
|
||||
if (virtualFile == null) {
|
||||
return;
|
||||
}
|
||||
if (LanguageLevel.forFile(virtualFile).isAtLeast(LanguageLevel.PYTHON25)) {
|
||||
if (LanguageLevel.forElement(node).isAtLeast(LanguageLevel.PYTHON25)) {
|
||||
return;
|
||||
}
|
||||
final PyExpression[] expressions = node.getExpressions();
|
||||
|
||||
@@ -17,7 +17,6 @@ package com.jetbrains.python.inspections;
|
||||
|
||||
import com.intellij.codeInspection.LocalInspectionToolSession;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.psi.*;
|
||||
@@ -67,8 +66,7 @@ public class PyTupleAssignmentBalanceInspection extends PyInspection {
|
||||
PyExpression[] elements = ((PyTupleExpression) lhsExpression).getElements();
|
||||
|
||||
boolean containsStarExpression = false;
|
||||
VirtualFile virtualFile = node.getContainingFile().getVirtualFile();
|
||||
if (virtualFile != null && LanguageLevel.forFile(virtualFile).isPy3K()) {
|
||||
if (LanguageLevel.forElement(node).isPy3K()) {
|
||||
for (PyExpression target: elements) {
|
||||
if (target instanceof PyStarExpression) {
|
||||
if (containsStarExpression) {
|
||||
|
||||
@@ -116,7 +116,7 @@ public class AddFunctionQuickFix implements LocalQuickFix {
|
||||
}
|
||||
}
|
||||
// else: no arglist, use empty args
|
||||
PyFunction function = builder.buildFunction(project, LanguageLevel.forFile(file.getVirtualFile()));
|
||||
PyFunction function = builder.buildFunction(project, LanguageLevel.forElement(file));
|
||||
|
||||
// add to the bottom
|
||||
function = (PyFunction) file.add(function);
|
||||
|
||||
@@ -23,13 +23,17 @@ import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder;
|
||||
import com.intellij.ide.fileTemplates.FileTemplate;
|
||||
import com.intellij.ide.fileTemplates.FileTemplateManager;
|
||||
import com.intellij.injected.editor.VirtualFileWindow;
|
||||
import com.intellij.lang.ASTFactory;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.module.ModuleUtilCore;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.ui.popup.Balloon;
|
||||
@@ -66,6 +70,7 @@ import com.jetbrains.python.psi.types.*;
|
||||
import com.jetbrains.python.refactoring.classes.PyDependenciesComparator;
|
||||
import com.jetbrains.python.refactoring.classes.extractSuperclass.PyExtractSuperclassHelper;
|
||||
import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo;
|
||||
import com.jetbrains.python.sdk.PythonSdkType;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -733,6 +738,52 @@ public class PyUtil {
|
||||
return pyClass.findMethodByName(PyNames.INIT, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Python language level for a virtual file.
|
||||
*
|
||||
* @see {@link LanguageLevel#forElement}
|
||||
*/
|
||||
@NotNull
|
||||
public static LanguageLevel getLanguageLevelForVirtualFile(@NotNull Project project,
|
||||
@NotNull VirtualFile virtualFile) {
|
||||
if (virtualFile instanceof VirtualFileWindow)
|
||||
virtualFile = ((VirtualFileWindow)virtualFile).getDelegate();
|
||||
|
||||
// Most of the cases should be handled by this one, PyLanguageLevelPusher pushes folders only
|
||||
final VirtualFile folder = virtualFile.getParent();
|
||||
if (folder != null) {
|
||||
final LanguageLevel level = folder.getUserData(LanguageLevel.KEY);
|
||||
if (level != null) return level;
|
||||
}
|
||||
else {
|
||||
// However this allows us to setup language level per file manually
|
||||
// in case when it is LightVirtualFile
|
||||
final LanguageLevel level = virtualFile.getUserData(LanguageLevel.KEY);
|
||||
if (level != null) return level;
|
||||
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
final LanguageLevel languageLevel = LanguageLevel.FORCE_LANGUAGE_LEVEL;
|
||||
if (languageLevel != null) {
|
||||
return languageLevel;
|
||||
}
|
||||
}
|
||||
}
|
||||
return guessLanguageLevel(project);
|
||||
}
|
||||
|
||||
private static LanguageLevel guessLanguageLevel(@NotNull Project project) {
|
||||
final ModuleManager moduleManager = ModuleManager.getInstance(project);
|
||||
if (moduleManager != null) {
|
||||
for (Module projectModule : moduleManager.getModules()) {
|
||||
final Sdk sdk = PythonSdkType.findPythonSdk(projectModule);
|
||||
if (sdk != null) {
|
||||
return PythonSdkType.getLanguageLevelForSdk(sdk);
|
||||
}
|
||||
}
|
||||
}
|
||||
return LanguageLevel.getDefault();
|
||||
}
|
||||
|
||||
public static class KnownDecoratorProviderHolder {
|
||||
public static PyKnownDecoratorProvider[] KNOWN_DECORATOR_PROVIDERS = Extensions.getExtensions(PyKnownDecoratorProvider.EP_NAME);
|
||||
|
||||
@@ -793,11 +844,14 @@ public class PyUtil {
|
||||
return target;
|
||||
}
|
||||
|
||||
public static boolean isPackage(@NotNull PsiDirectory directory) {
|
||||
public static boolean isPackage(@NotNull PsiDirectory directory, @Nullable PsiElement anchor) {
|
||||
if (turnDirIntoInit(directory) != null) {
|
||||
return true;
|
||||
}
|
||||
if (LanguageLevel.forFile(directory.getVirtualFile()).isAtLeast(LanguageLevel.PYTHON33)) {
|
||||
final LanguageLevel level = anchor != null ?
|
||||
LanguageLevel.forElement(anchor) :
|
||||
getLanguageLevelForVirtualFile(directory.getProject(), directory.getVirtualFile());
|
||||
if (level.isAtLeast(LanguageLevel.PYTHON33)) {
|
||||
return true;
|
||||
}
|
||||
return hasNamespacePackageFile(directory);
|
||||
@@ -808,8 +862,8 @@ public class PyUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiElement getPackageElement(@NotNull PsiDirectory directory) {
|
||||
if (isPackage(directory)) {
|
||||
public static PsiElement getPackageElement(@NotNull PsiDirectory directory, @Nullable PsiElement anchor) {
|
||||
if (isPackage(directory, anchor)) {
|
||||
final PsiElement init = turnDirIntoInit(directory);
|
||||
if (init != null) {
|
||||
return init;
|
||||
|
||||
@@ -663,10 +663,7 @@ public class PyClassImpl extends PyPresentableElementImpl<PyClassStub> implement
|
||||
// EA-32381: A tree-based instance may not have a parent element somehow, so getContainingFile() may be not appropriate
|
||||
final PsiFile file = getParentByStub() != null ? getContainingFile() : null;
|
||||
if (file != null) {
|
||||
final VirtualFile vfile = file.getVirtualFile();
|
||||
if (vfile != null) {
|
||||
level = LanguageLevel.forFile(vfile);
|
||||
}
|
||||
level = LanguageLevel.forElement(file);
|
||||
}
|
||||
final boolean useAdvancedSyntax = level.isAtLeast(LanguageLevel.PYTHON26);
|
||||
final Property local = processPropertiesInClass(name, filter, useAdvancedSyntax);
|
||||
|
||||
@@ -294,7 +294,7 @@ public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression {
|
||||
if (virtualFile == null) {
|
||||
virtualFile = getViewProvider().getVirtualFile();
|
||||
}
|
||||
return LanguageLevel.forFile(virtualFile);
|
||||
return PyUtil.getLanguageLevelForVirtualFile(getProject(), virtualFile);
|
||||
}
|
||||
|
||||
public Icon getIcon(int flags) {
|
||||
|
||||
@@ -143,7 +143,7 @@ public class PyImportedModule extends LightElement implements NameDefiner {
|
||||
element = ResolveImportUtil.resolveModuleInRoots(getImportedPrefix(), getContainingFile());
|
||||
}
|
||||
if (element instanceof PsiDirectory) {
|
||||
return PyUtil.getPackageElement((PsiDirectory)element);
|
||||
return PyUtil.getPackageElement((PsiDirectory)element, this);
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
@@ -427,7 +427,7 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference
|
||||
}
|
||||
else if (resolveResult instanceof PsiDirectory) {
|
||||
final PsiDirectory directory = (PsiDirectory)resolveResult;
|
||||
if (PyUtil.isPackage(directory) && directory == element) {
|
||||
if (PyUtil.isPackage(directory, null) && directory == element) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ public class ResolveImportUtil {
|
||||
throw new PsiInvalidElementAccessException(candidate, "Got an invalid candidate from resolveImportSourceCandidates(): " + candidate.getClass());
|
||||
}
|
||||
if (candidate instanceof PsiDirectory) {
|
||||
candidate = PyUtil.getPackageElement((PsiDirectory)candidate);
|
||||
candidate = PyUtil.getPackageElement((PsiDirectory)candidate, importStatement);
|
||||
}
|
||||
PsiElement result = resolveChild(candidate, name, file, false, true);
|
||||
if (result != null) {
|
||||
@@ -326,7 +326,7 @@ public class ResolveImportUtil {
|
||||
if (referencedName == null) return null;
|
||||
|
||||
final PsiDirectory subdir = dir.findSubdirectory(referencedName);
|
||||
if (subdir != null && (!checkForPackage || PyUtil.isPackage(subdir))) {
|
||||
if (subdir != null && (!checkForPackage || PyUtil.isPackage(subdir, containingFile))) {
|
||||
return subdir;
|
||||
}
|
||||
|
||||
@@ -358,7 +358,7 @@ public class ResolveImportUtil {
|
||||
ResolveResultList ret = new ResolveResultList();
|
||||
for (PsiElement target : targets) {
|
||||
if (target instanceof PsiDirectory) {
|
||||
target = PyUtil.getPackageElement((PsiDirectory)target);
|
||||
target = PyUtil.getPackageElement((PsiDirectory)target, null);
|
||||
}
|
||||
if (target != null) { // Ignore non-package dirs, worthless
|
||||
int rate = RatedResolveResult.RATE_HIGH;
|
||||
|
||||
@@ -450,7 +450,7 @@ public class PyTypeParser {
|
||||
break;
|
||||
}
|
||||
if (module instanceof PsiDirectory) {
|
||||
module = PyUtil.getPackageElement((PsiDirectory)module);
|
||||
module = PyUtil.getPackageElement((PsiDirectory)module, myAnchor);
|
||||
}
|
||||
if (module instanceof PyTypedElement) {
|
||||
final PyType moduleType = context.getType((PyTypedElement)module);
|
||||
|
||||
@@ -23,11 +23,9 @@ import com.intellij.codeInspection.ProblemHighlightType;
|
||||
import com.intellij.codeInspection.ex.ProblemDescriptorImpl;
|
||||
import com.intellij.codeInspection.ex.QuickFixWrapper;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.jetbrains.python.psi.LanguageLevel;
|
||||
import com.jetbrains.python.psi.PyElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -44,7 +42,7 @@ public class UnsupportedFeatures extends CompatibilityVisitor {
|
||||
|
||||
@Override
|
||||
public void visitPyElement(PyElement node) {
|
||||
setVersionsToProcess(Arrays.asList(getLanguageLevel(node)));
|
||||
setVersionsToProcess(Arrays.asList(LanguageLevel.forElement(node)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -70,15 +68,6 @@ public class UnsupportedFeatures extends CompatibilityVisitor {
|
||||
getHolder().createWarningAnnotation(range, message);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static LanguageLevel getLanguageLevel(PyElement node) {
|
||||
VirtualFile virtualFile = node.getContainingFile().getVirtualFile();
|
||||
if (virtualFile != null) {
|
||||
return LanguageLevel.forFile(virtualFile);
|
||||
}
|
||||
return LanguageLevel.getDefault();
|
||||
}
|
||||
|
||||
private static IntentionAction createIntention(PsiElement node, String message, LocalQuickFix fix) {
|
||||
return createIntention(node, node.getTextRange(), message, fix);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user