mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
added extension point for reference resolve
added resolve for web2py global variables
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
package com.jetbrains.python.psi.resolve;
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.jetbrains.python.psi.PyQualifiedExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* User : ktisha
|
||||
*/
|
||||
public interface PyReferenceResolveProvider {
|
||||
ExtensionPointName<PyReferenceResolveProvider> EP_NAME = ExtensionPointName.create("Pythonid.pyReferenceResolveProvider");
|
||||
|
||||
/**
|
||||
* Allows to provide a custom resolve result for qualified expression
|
||||
*/
|
||||
@NotNull
|
||||
List<RatedResolveResult> resolveName(@NotNull final PyQualifiedExpression element,
|
||||
@NotNull final List<PsiElement> definers);
|
||||
}
|
||||
@@ -838,6 +838,7 @@
|
||||
<extensionPoint qualifiedName="Pythonid.keywordArgumentProvider" interface="com.jetbrains.python.psi.impl.PyKeywordArgumentProvider"/>
|
||||
<extensionPoint qualifiedName="Pythonid.canonicalPathProvider" interface="com.jetbrains.python.psi.resolve.PyCanonicalPathProvider"/>
|
||||
<extensionPoint qualifiedName="Pythonid.templateContextProvider" interface="com.jetbrains.python.templateLanguages.TemplateContextProvider"/>
|
||||
<extensionPoint qualifiedName="Pythonid.pyReferenceResolveProvider" interface="com.jetbrains.python.psi.resolve.PyReferenceResolveProvider"/>
|
||||
</extensionPoints>
|
||||
|
||||
<extensions defaultExtensionNs="Pythonid">
|
||||
@@ -864,6 +865,7 @@
|
||||
<typeProvider implementation="com.jetbrains.python.codeInsight.userSkeletons.PyUserSkeletonsTypeProvider"/>
|
||||
|
||||
<typeProvider implementation="com.jetbrains.python.debugger.PyCallSignatureTypeProvider"/>
|
||||
<pyReferenceResolveProvider implementation="com.jetbrains.python.psi.resolve.PythonBuiltinReferenceResolveProvider"/>
|
||||
|
||||
<!-- Django -->
|
||||
<pyClassMembersProvider implementation="com.jetbrains.django.codeInsight.DjangoClassMembersProvider"/>
|
||||
@@ -893,6 +895,7 @@
|
||||
<importResolver implementation="com.jetbrains.cython.CythonImportResolver"/>
|
||||
<visitorFilter language="Cython" implementationClass="com.jetbrains.cython.CythonVisitorFilter"/>
|
||||
<pyModuleMembersProvider implementation="com.jetbrains.cython.CythonModuleMembersProvider"/>
|
||||
<pyReferenceResolveProvider implementation="com.jetbrains.cython.CythonReferenceResolveProvider"/>
|
||||
|
||||
<!-- Mako -->
|
||||
<dialectsTokenSetContributor implementation="com.jetbrains.mako.MakoTokenSetContributor"/>
|
||||
@@ -911,6 +914,10 @@
|
||||
<!-- SQLAlchemy -->
|
||||
<typeProvider implementation="com.jetbrains.sqlalchemy.SQLAlchemyTypeProvider"/>
|
||||
<knownDecoratorProvider implementation="com.jetbrains.sqlalchemy.SQLAlchemyKnownDecoratorProvider"/>
|
||||
|
||||
<!-- Web2Py -->
|
||||
<pyReferenceResolveProvider implementation="com.jetbrains.web2py.Web2PyReferenceResolveProvider"/>
|
||||
|
||||
</extensions>
|
||||
|
||||
<project-components>
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.annotation.HighlightSeverity;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
@@ -16,8 +17,9 @@ import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.PlatformIcons;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import com.jetbrains.cython.CythonLanguageDialect;
|
||||
import com.jetbrains.cython.CythonResolveUtil;
|
||||
import com.jetbrains.cython.psi.*;
|
||||
import com.jetbrains.cython.psi.CythonIncludeStatement;
|
||||
import com.jetbrains.cython.psi.CythonNamedElement;
|
||||
import com.jetbrains.cython.psi.CythonVariable;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ReadWriteInstruction;
|
||||
@@ -248,8 +250,9 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference
|
||||
PsiElement realContext, PsiElement roof) {
|
||||
ResolveResultList ret = new ResolveResultList();
|
||||
PsiElement uexpr = processor.getResult();
|
||||
final List<PsiElement> definers = processor.getDefiners();
|
||||
if (uexpr != null) {
|
||||
if (processor.getDefiners().isEmpty()) {
|
||||
if (definers.isEmpty()) {
|
||||
final ScopeOwner originalOwner = ScopeUtil.getScopeOwner(realContext);
|
||||
final ScopeOwner owner = ScopeUtil.getScopeOwner(uexpr);
|
||||
if (owner != null) {
|
||||
@@ -284,7 +287,7 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference
|
||||
}
|
||||
}
|
||||
// sort what we got
|
||||
for (PsiElement hit : processor.getDefiners()) {
|
||||
for (PsiElement hit : definers) {
|
||||
ret.poke(hit, getRate(hit));
|
||||
}
|
||||
final PsiElement packageInit = PyUtil.turnDirIntoInit(uexpr);
|
||||
@@ -292,46 +295,30 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference
|
||||
uexpr = packageInit; // an import statement may have returned a dir
|
||||
}
|
||||
}
|
||||
else if (!processor.getDefiners().isEmpty()) {
|
||||
ret.add(new ImportedResolveResult(null, RatedResolveResult.RATE_LOW, processor.getDefiners()));
|
||||
else if (!definers.isEmpty()) {
|
||||
ret.add(new ImportedResolveResult(null, RatedResolveResult.RATE_LOW, definers));
|
||||
}
|
||||
PyBuiltinCache builtins_cache = PyBuiltinCache.getInstance(realContext);
|
||||
PyBuiltinCache builtinCache = PyBuiltinCache.getInstance(realContext);
|
||||
if (uexpr == null) {
|
||||
// ...as a part of current module
|
||||
String name = myElement.getName();
|
||||
if (PyModuleType.MODULE_MEMBERS.contains(name)) {
|
||||
PyType otype = builtins_cache.getObjectType(); // "object" as a closest kin to "module"
|
||||
if (otype != null && name != null) {
|
||||
ret.addAll(otype.resolveMember(name, null, AccessDirection.READ, myContext));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (uexpr == null) {
|
||||
// ...as a builtin symbol
|
||||
PyFile bfile = builtins_cache.getBuiltinsFile();
|
||||
if (bfile != null && !PyUtil.isClassPrivateName(referencedName)) {
|
||||
uexpr = bfile.getElementNamed(referencedName);
|
||||
if (uexpr == null && "__builtins__".equals(referencedName)) {
|
||||
uexpr = bfile; // resolve __builtins__ reference
|
||||
}
|
||||
}
|
||||
}
|
||||
if (uexpr == null && CythonLanguageDialect.isInsideCythonFile(realContext)) {
|
||||
final CythonFile implicit = CythonResolveUtil.findImplicitDefinitionFile(realContext);
|
||||
if (implicit != null) {
|
||||
uexpr = implicit.getElementNamed(referencedName);
|
||||
}
|
||||
final ScopeOwner owner = PsiTreeUtil.getParentOfType(myElement, ScopeOwner.class);
|
||||
if (owner instanceof CythonFile) {
|
||||
final PsiElement resolved = ((CythonFile)owner).getElementNamed(referencedName);
|
||||
if ((resolved instanceof CythonFunction && ((CythonFunction)resolved).isCythonLevel()) ||
|
||||
resolved instanceof CythonFile) {
|
||||
ret.poke(resolved, getRate(resolved));
|
||||
PyType objectType = builtinCache.getObjectType(); // "object" as a closest kin to "module"
|
||||
if (objectType != null && name != null) {
|
||||
ret.addAll(objectType.resolveMember(name, null, AccessDirection.READ, myContext));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (uexpr != null) {
|
||||
ret.add(new ImportedResolveResult(uexpr, getRate(uexpr), processor.getDefiners()));
|
||||
ret.add(new ImportedResolveResult(uexpr, getRate(uexpr), definers));
|
||||
}
|
||||
else {
|
||||
for (PyReferenceResolveProvider provider : Extensions.getExtensions(PyReferenceResolveProvider.EP_NAME)) {
|
||||
final List<RatedResolveResult> results = provider.resolveName(myElement, definers);
|
||||
for (RatedResolveResult res : results) {
|
||||
ret.add(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -379,7 +366,7 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference
|
||||
|
||||
// NOTE: very crude
|
||||
|
||||
private static int getRate(PsiElement elt) {
|
||||
public static int getRate(PsiElement elt) {
|
||||
int rate;
|
||||
if (CythonLanguageDialect.isInsideCythonFile(elt) && elt instanceof CythonIncludeStatement) {
|
||||
rate = RatedResolveResult.RATE_LOW;
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package com.jetbrains.python.psi.resolve;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.jetbrains.python.psi.PyFile;
|
||||
import com.jetbrains.python.psi.PyQualifiedExpression;
|
||||
import com.jetbrains.python.psi.PyUtil;
|
||||
import com.jetbrains.python.psi.impl.PyBuiltinCache;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import com.jetbrains.python.psi.impl.references.PyReferenceImpl;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* User : ktisha
|
||||
*/
|
||||
public class PythonBuiltinReferenceResolveProvider implements PyReferenceResolveProvider {
|
||||
@NotNull
|
||||
@Override
|
||||
public List<RatedResolveResult> resolveName(@NotNull PyQualifiedExpression element,
|
||||
@NotNull List<PsiElement> definers) {
|
||||
final List<RatedResolveResult> result = new ArrayList<RatedResolveResult>();
|
||||
final PsiElement realContext = PyPsiUtils.getRealContext(element);
|
||||
final String referencedName = element.getReferencedName();
|
||||
final PyBuiltinCache builtinCache = PyBuiltinCache.getInstance(realContext);
|
||||
// ...as a builtin symbol
|
||||
final PyFile bfile = builtinCache.getBuiltinsFile();
|
||||
if (bfile != null && !PyUtil.isClassPrivateName(referencedName)) {
|
||||
PsiElement resultElement = bfile.getElementNamed(referencedName);
|
||||
if (resultElement == null && "__builtins__".equals(referencedName)) {
|
||||
resultElement = bfile; // resolve __builtins__ reference
|
||||
}
|
||||
if (resultElement != null)
|
||||
result.add(new ImportedResolveResult(resultElement, PyReferenceImpl.getRate(resultElement), definers));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user