PyStdlibCanonicalPathProvider shouldn't modify the passed QualifiedName in place

Otherwise PythonPathCache starts returning, e.g. "path" instead of
"ntpath" for ntpath.py module.

On the whole, it seems that QualifiedName#getComponents() shouldn't
return the original backed array list in the first place.

Additionally, PythonPathCache returns unmodifiable lists of qualified
names and elements to prevent similar, tricky to track down, errors in
future.
This commit is contained in:
Mikhail Golubev
2017-04-17 19:22:54 +03:00
parent d794eeef12
commit 2e008b6dda
2 changed files with 5 additions and 3 deletions
@@ -36,7 +36,7 @@ public class PyStdlibCanonicalPathProvider implements PyCanonicalPathProvider {
public static QualifiedName restoreStdlibCanonicalPath(QualifiedName qName) {
if (qName.getComponentCount() > 0) {
final List<String> components = qName.getComponents();
final List<String> components = new ArrayList<>(qName.getComponents());
final String head = components.get(0);
if (head.equals("_abcoll") || head.equals("_collections") || head.equals("_collections_abc")) {
components.set(0, "collections");
@@ -24,6 +24,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -53,7 +54,7 @@ public abstract class PythonPathCache {
// At least one element is invalid
return null;
}
return elements;
return elements != null ? Collections.unmodifiableList(elements) : null;
}
public void put(QualifiedName qualifiedName, List<PsiElement> results) {
@@ -67,7 +68,8 @@ public abstract class PythonPathCache {
if (vFile == null) {
return null;
}
return myQNameCache.get(vFile.getUrl());
final List<QualifiedName> names = myQNameCache.get(vFile.getUrl());
return names != null ? Collections.unmodifiableList(names) : null;
}
public void putNames(VirtualFile vFile, List<QualifiedName> qNames) {