Skip to content

Commit 1d5f91e

Browse files
committed
Fix importUsers concurrency issues
1 parent a7a16d0 commit 1d5f91e

File tree

3 files changed

+34
-27
lines changed

3 files changed

+34
-27
lines changed

src/com/goide/codeInsight/imports/GoImportOptimizer.java

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -127,17 +127,8 @@ public static MultiMap<String, GoImportSpec> filterUnusedImports(@NotNull PsiFil
127127
Collection<GoImportSpec> implicitImports = ContainerUtil.newArrayList(result.get("."));
128128
for (GoImportSpec importEntry : implicitImports) {
129129
GoImportSpec spec = getImportSpec(importEntry);
130-
if (spec != null && spec.isDot()) {
131-
List<? extends PsiElement> list = spec.getUserData(GoReferenceBase.IMPORT_USERS);
132-
if (list != null) {
133-
for (PsiElement e : list) {
134-
if (e.isValid()) {
135-
result.remove(".", importEntry);
136-
break;
137-
}
138-
ProgressManager.checkCanceled();
139-
}
140-
}
130+
if (spec != null && spec.isDot() && hasImportUsers(spec)) {
131+
result.remove(".", importEntry);
141132
}
142133
}
143134

@@ -194,8 +185,24 @@ private void markAsUsed(@NotNull PsiElement qualifier, @NotNull PsiReference ref
194185
return result;
195186
}
196187

188+
private static boolean hasImportUsers(@NotNull GoImportSpec spec) {
189+
//noinspection SynchronizationOnLocalVariableOrMethodParameter
190+
synchronized (spec) {
191+
List<PsiElement> list = spec.getUserData(GoReferenceBase.IMPORT_USERS);
192+
if (list != null) {
193+
for (PsiElement e : list) {
194+
if (e.isValid()) {
195+
return true;
196+
}
197+
ProgressManager.checkCanceled();
198+
}
199+
}
200+
}
201+
return false;
202+
}
203+
197204
@NotNull
198-
public static Set<GoImportSpec> findDuplicatedEntries(@NotNull MultiMap<String, GoImportSpec> importMap) {
205+
private static Set<GoImportSpec> findDuplicatedEntries(@NotNull MultiMap<String, GoImportSpec> importMap) {
199206
Set<GoImportSpec> duplicatedEntries = ContainerUtil.newLinkedHashSet();
200207
for (Map.Entry<String, Collection<GoImportSpec>> imports : importMap.entrySet()) {
201208
Collection<GoImportSpec> importsWithSameName = imports.getValue();

src/com/goide/highlighting/GoHighlightingAnnotator.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.jetbrains.annotations.Nullable;
3333

3434
import java.util.List;
35+
import java.util.stream.Collectors;
3536

3637
import static com.goide.highlighting.GoSyntaxHighlightingColors.*;
3738

@@ -137,15 +138,14 @@ private static boolean isPackageWide(@NotNull GoConstDefinition o) {
137138
public void annotate(@NotNull PsiElement o, @NotNull AnnotationHolder holder) {
138139
if (!o.isValid()) return;
139140
if (o instanceof GoImportSpec && ((GoImportSpec)o).isDot()) {
140-
List<? extends PsiElement> importUsers = o.getUserData(GoReferenceBase.IMPORT_USERS);
141-
if (importUsers != null) {
142-
List<PsiElement> newImportUsers = ContainerUtil.newSmartList();
143-
for (PsiElement user : importUsers) {
144-
if (user.isValid()) {
145-
newImportUsers.add(user);
146-
}
141+
//noinspection SynchronizationOnLocalVariableOrMethodParameter
142+
synchronized (o) {
143+
List<PsiElement> importUsers = o.getUserData(GoReferenceBase.IMPORT_USERS);
144+
if (importUsers != null) {
145+
List<PsiElement> newImportUsers = ContainerUtil.newSmartList();
146+
newImportUsers.addAll(importUsers.stream().filter(PsiElement::isValid).collect(Collectors.toList()));
147+
o.putUserData(GoReferenceBase.IMPORT_USERS, newImportUsers.isEmpty() ? null : newImportUsers);
147148
}
148-
o.putUserData(GoReferenceBase.IMPORT_USERS, newImportUsers.isEmpty() ? null : newImportUsers);
149149
}
150150
}
151151
else if (o instanceof GoLiteral) {

src/com/goide/psi/impl/GoReferenceBase.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
import static com.goide.psi.impl.GoPsiImplUtil.allowed;
3838

3939
public abstract class GoReferenceBase<T extends GoReferenceExpressionBase> extends PsiPolyVariantReferenceBase<T> {
40-
public static final Key<List<? extends PsiElement>> IMPORT_USERS = Key.create("IMPORT_USERS");
40+
public static final Key<List<PsiElement>> IMPORT_USERS = Key.create("IMPORT_USERS");
4141
public static final Key<String> ACTUAL_NAME = Key.create("ACTUAL_NAME");
4242

4343
public GoReferenceBase(T element, TextRange range) {
@@ -51,13 +51,13 @@ protected static String getPath(@Nullable PsiFile file) {
5151
return virtualFile == null ? null : virtualFile.getPath();
5252
}
5353

54-
private static void putIfAbsent(@NotNull PsiElement importElement, @NotNull PsiElement usage) {
55-
List<PsiElement> newList = ContainerUtil.newSmartList(usage);
56-
List<? extends PsiElement> list = importElement.getUserData(IMPORT_USERS);
57-
if (list != null) {
58-
newList.addAll(list);
54+
private static void putIfAbsent(@NotNull GoImportSpec importSpec, @NotNull PsiElement usage) {
55+
//noinspection SynchronizationOnLocalVariableOrMethodParameter
56+
synchronized (importSpec) {
57+
List<PsiElement> newUsages = ContainerUtil.newSmartList(usage);
58+
newUsages.addAll(IMPORT_USERS.get(importSpec, ContainerUtil.emptyList()));
59+
importSpec.putUserData(IMPORT_USERS, newUsages);
5960
}
60-
importElement.putUserData(IMPORT_USERS, newList);
6161
}
6262

6363
protected boolean processDirectory(@Nullable PsiDirectory dir,

0 commit comments

Comments
 (0)