Fix data race in LightReferenceListBuilder

Effectively this is a cherry-pick of
https://github.com/JetBrains/intellij-community/commit/75032008695977f171540b5f0e055b77aa682c0c
This commit is contained in:
Denis Zharkov
2018-11-01 11:03:07 +03:00
parent 94d9fd8b72
commit 34e8ce6a48
@@ -19,8 +19,8 @@ import java.util.List;
*/ */
public class KotlinLightReferenceListBuilder extends LightReferenceListBuilder implements PsiReferenceList { public class KotlinLightReferenceListBuilder extends LightReferenceListBuilder implements PsiReferenceList {
private final List<PsiJavaCodeReferenceElement> myRefs = new ArrayList<>(); private final List<PsiJavaCodeReferenceElement> myRefs = new ArrayList<>();
private PsiJavaCodeReferenceElement[] myCachedRefs; private volatile PsiJavaCodeReferenceElement[] myCachedRefs;
private PsiClassType[] myCachedTypes; private volatile PsiClassType[] myCachedTypes;
private final Role myRole; private final Role myRole;
private final PsiElementFactory myFactory; private final PsiElementFactory myFactory;
@@ -57,34 +57,27 @@ public class KotlinLightReferenceListBuilder extends LightReferenceListBuilder i
@NotNull @NotNull
@Override @Override
public PsiJavaCodeReferenceElement[] getReferenceElements() { public PsiJavaCodeReferenceElement[] getReferenceElements() {
if (myCachedRefs == null) { PsiJavaCodeReferenceElement[] refs = myCachedRefs;
if (myRefs.isEmpty()) { if (refs == null) {
myCachedRefs = PsiJavaCodeReferenceElement.EMPTY_ARRAY; myCachedRefs = refs = myRefs.toArray(PsiJavaCodeReferenceElement.EMPTY_ARRAY);
}
else {
myCachedRefs = myRefs.toArray(PsiJavaCodeReferenceElement.EMPTY_ARRAY);
}
} }
return myCachedRefs; return refs;
} }
@NotNull @NotNull
@Override @Override
public PsiClassType[] getReferencedTypes() { public PsiClassType[] getReferencedTypes() {
if (myCachedTypes == null) { PsiClassType[] types = myCachedTypes;
if (myRefs.isEmpty()) { if (types == null) {
myCachedTypes = PsiClassType.EMPTY_ARRAY; int size = myRefs.size();
} types = size == 0 ? PsiClassType.EMPTY_ARRAY : new PsiClassType[size];
else { for (int i = 0; i < size; i++) {
final int size = myRefs.size(); types[i] = myFactory.createType(myRefs.get(i));
myCachedTypes = new PsiClassType[size];
for (int i = 0; i < size; i++) {
myCachedTypes[i] = myFactory.createType(myRefs.get(i));
}
} }
myCachedTypes = types;
} }
return myCachedTypes; return types;
} }
@Override @Override