Remove dead code that resolves forward references in annotations

This commit is contained in:
Semyon Proshev
2018-03-13 17:36:51 +03:00
parent f668a5a18f
commit 83a321b609
3 changed files with 47 additions and 49 deletions
@@ -260,9 +260,9 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference
}
protected final List<RatedResolveResult> getResultsFromProcessor(@NotNull String referencedName,
@NotNull PyResolveProcessor processor,
@Nullable PsiElement realContext,
@Nullable PsiElement resolveRoof) {
@NotNull PyResolveProcessor processor,
@Nullable PsiElement realContext,
@Nullable PsiElement resolveRoof) {
boolean unreachableLocalDeclaration = false;
boolean resolveInParentScope = false;
final ResolveResultList resultList = new ResolveResultList();
@@ -270,57 +270,47 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference
final TypeEvalContext typeEvalContext = myContext.getTypeEvalContext();
ScopeOwner resolvedOwner = processor.getOwner();
if (resolvedOwner != null && !processor.getResults().isEmpty()) {
final Collection<PsiElement> resolvedElements = processor.getElements();
final Scope resolvedScope = ControlFlowCache.getScope(resolvedOwner);
final Collection<PsiElement> resolvedElements = processor.getElements();
if (resolvedOwner != null && !resolvedElements.isEmpty() && !ControlFlowCache.getScope(resolvedOwner).isGlobal(referencedName)) {
if (resolvedOwner == referenceOwner) {
final List<Instruction> instructions = getLatestDefinitions(referencedName, resolvedOwner, realContext);
// TODO: Use the results from the processor as a cache for resolving to latest defs
final ResolveResultList latestDefs = resolveToLatestDefs(instructions, realContext, referencedName, typeEvalContext);
if (!latestDefs.isEmpty()) {
if (ContainerUtil.exists(latestDefs, result -> result.getElement() instanceof PyCallable)) {
return StreamEx
.of(resolvedElements)
.nonNull()
.filter(element -> PyiUtil.isOverload(element, typeEvalContext))
.map(element -> new RatedResolveResult(getRate(element, typeEvalContext), element))
.prepend(latestDefs)
.toList();
}
if (!resolvedScope.isGlobal(referencedName)) {
if (resolvedOwner == referenceOwner) {
final List<Instruction> instructions = getLatestDefinitions(referencedName, resolvedOwner, realContext);
// TODO: Use the results from the processor as a cache for resolving to latest defs
final ResolveResultList latestDefs = resolveToLatestDefs(instructions, realContext, referencedName, typeEvalContext);
if (!latestDefs.isEmpty()) {
if (ContainerUtil.exists(latestDefs, result -> result.getElement() instanceof PyCallable)) {
return StreamEx
.of(processor.getResults().keySet())
.nonNull()
.filter(element -> PyiUtil.isOverload(element, typeEvalContext))
.map(element -> new RatedResolveResult(getRate(element, typeEvalContext), element))
.prepend(latestDefs)
.toList();
}
return latestDefs;
}
else if (resolvedOwner instanceof PyClass || instructions.isEmpty() && allInOwnScopeComprehensions(resolvedElements)) {
resolveInParentScope = true;
}
else {
unreachableLocalDeclaration = true;
}
}
else if (referenceOwner != null) {
if (!allowsForwardOutgoingReferencesInClass(myElement)) {
final PyClass outermostNestedClass = outermostNestedClass(referenceOwner, resolvedOwner);
return latestDefs;
}
else if (resolvedOwner instanceof PyClass || instructions.isEmpty() && allInOwnScopeComprehensions(resolvedElements)) {
resolveInParentScope = true;
}
else if (PyiUtil.isInsideStubAnnotation(myElement)) {
for (PsiElement element : resolvedElements) {
resultList.poke(element, getRate(element, typeEvalContext));
}
return resultList;
}
else {
unreachableLocalDeclaration = true;
if (outermostNestedClass != null) {
final List<Instruction> instructions =
PyDefUseUtil.getLatestDefs(resolvedOwner, referencedName, outermostNestedClass, false, true);
return resolveToLatestDefs(instructions, outermostNestedClass, referencedName, typeEvalContext);
}
}
else if (referenceOwner != null) {
if (!allowsForwardOutgoingReferencesInClass(myElement)) {
final PyClass outermostNestedClass = outermostNestedClass(referenceOwner, resolvedOwner);
if (outermostNestedClass != null) {
final List<Instruction> instructions =
PyDefUseUtil.getLatestDefs(resolvedOwner, referencedName, outermostNestedClass, false, true);
return resolveToLatestDefs(instructions, outermostNestedClass, referencedName, typeEvalContext);
}
}
final Scope referenceScope = ControlFlowCache.getScope(referenceOwner);
if (referenceScope.containsDeclaration(referencedName)) {
unreachableLocalDeclaration = true;
}
final Scope referenceScope = ControlFlowCache.getScope(referenceOwner);
if (referenceScope.containsDeclaration(referencedName)) {
unreachableLocalDeclaration = true;
}
}
}
@@ -0,0 +1,4 @@
def f(x: C) -> C: ...
<ref>
class C: ...
@@ -61,4 +61,8 @@ public class PyiResolveTest extends PyMultiFileResolveTestCase {
public void testGenericAttribute() {
assertResolvesTo(PyTargetExpression.class, "foo");
}
public void testForwardReference() {
assertResolvesTo(PyClass.class, "C");
}
}