mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Introduce PyOverridingReferenceResolveProvider and PythonOverridingBuiltinReferenceResolveProvider as its implementation to handle implicit __class__
This commit is contained in:
+19
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jetbrains.python.psi.resolve;
|
||||
|
||||
public interface PyOverridingReferenceResolveProvider extends PyReferenceResolveProvider {
|
||||
}
|
||||
@@ -689,6 +689,7 @@
|
||||
|
||||
<typeProvider implementation="com.jetbrains.python.debugger.PyCallSignatureTypeProvider"/>
|
||||
<pyReferenceResolveProvider implementation="com.jetbrains.python.psi.resolve.PythonBuiltinReferenceResolveProvider"/>
|
||||
<pyReferenceResolveProvider implementation="com.jetbrains.python.psi.resolve.PythonOverridingBuiltinReferenceResolveProvider"/>
|
||||
|
||||
<!-- NumPy -->
|
||||
<pyModuleMembersProvider implementation="com.jetbrains.numpy.codeInsight.NumpyModuleMembersProvider"/>
|
||||
|
||||
@@ -223,6 +223,11 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference
|
||||
*/
|
||||
@NotNull
|
||||
protected List<RatedResolveResult> resolveInner() {
|
||||
final ResolveResultList overriddenRet = resolveByOverridingReferenceResolveProviders();
|
||||
if (!overriddenRet.isEmpty()) {
|
||||
return overriddenRet;
|
||||
}
|
||||
|
||||
final ResolveResultList ret = new ResolveResultList();
|
||||
|
||||
final String referencedName = myElement.getReferencedName();
|
||||
@@ -235,27 +240,6 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference
|
||||
}
|
||||
}
|
||||
|
||||
// resolve implicit __class__ inside class function
|
||||
if (myElement instanceof PyReferenceExpression &&
|
||||
PyNames.__CLASS__.equals(referencedName) &&
|
||||
LanguageLevel.forElement(myElement).isAtLeast(LanguageLevel.PYTHON30)) {
|
||||
final PyFunction containingFunction = PsiTreeUtil.getParentOfType(myElement, PyFunction.class);
|
||||
|
||||
if (containingFunction != null) {
|
||||
final PyClass containingClass = containingFunction.getContainingClass();
|
||||
|
||||
if (containingClass != null) {
|
||||
final PyResolveProcessor processor = new PyResolveProcessor(referencedName);
|
||||
PyResolveUtil.scopeCrawlUp(processor, myElement, referencedName, containingFunction);
|
||||
|
||||
if (processor.getElements().isEmpty()) {
|
||||
ret.add(new RatedResolveResult(RatedResolveResult.RATE_NORMAL, containingClass));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// here we have an unqualified expr. it may be defined:
|
||||
// ...in current file
|
||||
final PyResolveProcessor processor = new PyResolveProcessor(referencedName);
|
||||
@@ -359,11 +343,28 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ResolveResultList resolveByOverridingReferenceResolveProviders() {
|
||||
final ResolveResultList results = new ResolveResultList();
|
||||
final TypeEvalContext context = myContext.getTypeEvalContext();
|
||||
|
||||
Arrays
|
||||
.stream(Extensions.getExtensions(PyReferenceResolveProvider.EP_NAME))
|
||||
.filter(PyOverridingReferenceResolveProvider.class::isInstance)
|
||||
.map(provider -> provider.resolveName(myElement, context))
|
||||
.forEach(results::addAll);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ResolveResultList resolveByReferenceResolveProviders() {
|
||||
final ResolveResultList results = new ResolveResultList();
|
||||
final TypeEvalContext context = myContext.getTypeEvalContext();
|
||||
for (PyReferenceResolveProvider provider : Extensions.getExtensions(PyReferenceResolveProvider.EP_NAME)) {
|
||||
if (provider instanceof PyOverridingReferenceResolveProvider) {
|
||||
continue;
|
||||
}
|
||||
results.addAll(provider.resolveName(myElement, context));
|
||||
}
|
||||
return results;
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jetbrains.python.psi.resolve;
|
||||
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.types.TypeEvalContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class PythonOverridingBuiltinReferenceResolveProvider implements PyOverridingReferenceResolveProvider {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<RatedResolveResult> resolveName(@NotNull PyQualifiedExpression element, @NotNull TypeEvalContext context) {
|
||||
final String referencedName = element.getReferencedName();
|
||||
|
||||
// resolve implicit __class__ inside class function
|
||||
if (element instanceof PyReferenceExpression &&
|
||||
PyNames.__CLASS__.equals(referencedName) &&
|
||||
LanguageLevel.forElement(element).isAtLeast(LanguageLevel.PYTHON30)) {
|
||||
final PyFunction containingFunction = PsiTreeUtil.getParentOfType(element, PyFunction.class);
|
||||
|
||||
if (containingFunction != null) {
|
||||
final PyClass containingClass = containingFunction.getContainingClass();
|
||||
|
||||
if (containingClass != null) {
|
||||
final PyResolveProcessor processor = new PyResolveProcessor(referencedName);
|
||||
PyResolveUtil.scopeCrawlUp(processor, element, referencedName, containingFunction);
|
||||
|
||||
if (processor.getElements().isEmpty()) {
|
||||
return Collections.singletonList(new RatedResolveResult(RatedResolveResult.RATE_NORMAL, containingClass));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user