[FIR] FirBasedSymbol: iterate annotations by index instead of iterator to avoid possible ConcurrentModificationException
^KT-56046
This commit is contained in:
committed by
Space Team
parent
19a61015c0
commit
38575cdbc1
+20
-9
@@ -51,12 +51,15 @@ internal fun annotationsByClassId(
|
|||||||
annotationContainer: FirAnnotationContainer = firSymbol.fir,
|
annotationContainer: FirAnnotationContainer = firSymbol.fir,
|
||||||
): List<KtAnnotationApplicationWithArgumentsInfo> =
|
): List<KtAnnotationApplicationWithArgumentsInfo> =
|
||||||
if (firSymbol.isFromCompilerRequiredAnnotationsPhase(classId)) {
|
if (firSymbol.isFromCompilerRequiredAnnotationsPhase(classId)) {
|
||||||
annotationContainer.resolvedCompilerRequiredAnnotations(firSymbol).mapIndexedNotNull { index, annotation ->
|
buildList {
|
||||||
if (!useSiteTargetFilter.isAllowed(annotation.useSiteTarget) || annotation.toAnnotationClassIdSafe(useSiteSession) != classId) {
|
// this loop by index is required to avoid possible ConcurrentModificationException
|
||||||
return@mapIndexedNotNull null
|
val annotations = annotationContainer.resolvedCompilerRequiredAnnotations(firSymbol)
|
||||||
|
for (index in annotations.indices) {
|
||||||
|
val annotation = annotations[index]
|
||||||
|
if (useSiteTargetFilter.isAllowed(annotation.useSiteTarget) && annotation.toAnnotationClassIdSafe(useSiteSession) == classId) {
|
||||||
|
add(annotation.toKtAnnotationApplication(useSiteSession, index))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
annotation.toKtAnnotationApplication(useSiteSession, index)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
annotationContainer.resolvedAnnotationsWithArguments(firSymbol).mapIndexedNotNull { index, annotation ->
|
annotationContainer.resolvedAnnotationsWithArguments(firSymbol).mapIndexedNotNull { index, annotation ->
|
||||||
@@ -99,16 +102,24 @@ internal fun hasAnnotation(
|
|||||||
useSiteTargetFilter: AnnotationUseSiteTargetFilter,
|
useSiteTargetFilter: AnnotationUseSiteTargetFilter,
|
||||||
useSiteSession: FirSession,
|
useSiteSession: FirSession,
|
||||||
annotationContainer: FirAnnotationContainer = firSymbol.fir,
|
annotationContainer: FirAnnotationContainer = firSymbol.fir,
|
||||||
): Boolean =
|
): Boolean {
|
||||||
if (firSymbol.isFromCompilerRequiredAnnotationsPhase(classId)) {
|
return if (firSymbol.isFromCompilerRequiredAnnotationsPhase(classId)) {
|
||||||
annotationContainer.resolvedCompilerRequiredAnnotations(firSymbol).any {
|
// this loop by index is required to avoid possible ConcurrentModificationException
|
||||||
useSiteTargetFilter.isAllowed(it.useSiteTarget) && it.toAnnotationClassIdSafe(useSiteSession) == classId
|
val annotations = annotationContainer.resolvedCompilerRequiredAnnotations(firSymbol)
|
||||||
|
for (index in annotations.indices) {
|
||||||
|
val annotation = annotations[index]
|
||||||
|
if (useSiteTargetFilter.isAllowed(annotation.useSiteTarget) && annotation.toAnnotationClassIdSafe(useSiteSession) == classId) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
false
|
||||||
} else {
|
} else {
|
||||||
annotationContainer.resolvedAnnotationsWithClassIds(firSymbol).any {
|
annotationContainer.resolvedAnnotationsWithClassIds(firSymbol).any {
|
||||||
useSiteTargetFilter.isAllowed(it.useSiteTarget) && it.toAnnotationClassId(useSiteSession) == classId
|
useSiteTargetFilter.isAllowed(it.useSiteTarget) && it.toAnnotationClassId(useSiteSession) == classId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun FirBasedSymbol<*>.isFromCompilerRequiredAnnotationsPhase(classId: ClassId): Boolean =
|
private fun FirBasedSymbol<*>.isFromCompilerRequiredAnnotationsPhase(classId: ClassId): Boolean =
|
||||||
fir.resolvePhase < FirResolvePhase.TYPES && classId in CompilerRequiredAnnotationsHelper.REQUIRED_ANNOTATIONS
|
fir.resolvePhase < FirResolvePhase.TYPES && classId in CompilerRequiredAnnotationsHelper.REQUIRED_ANNOTATIONS
|
||||||
@@ -79,7 +79,17 @@ fun FirAnnotationContainer.resolvedAnnotationsWithArguments(anchorElement: FirBa
|
|||||||
fun List<FirAnnotation>.resolvedAnnotationsWithArguments(anchorElement: FirBasedSymbol<*>): List<FirAnnotation> {
|
fun List<FirAnnotation>.resolvedAnnotationsWithArguments(anchorElement: FirBasedSymbol<*>): List<FirAnnotation> {
|
||||||
if (isEmpty()) return emptyList()
|
if (isEmpty()) return emptyList()
|
||||||
|
|
||||||
val phase = if (any { it is FirAnnotationCall && it.arguments.isNotEmpty() }) {
|
// this loop by index is required to avoid possible ConcurrentModificationException
|
||||||
|
var hasAnnotationCallWithArguments = false
|
||||||
|
for (i in indices) {
|
||||||
|
val currentAnnotation = get(i)
|
||||||
|
if (currentAnnotation is FirAnnotationCall && currentAnnotation.arguments.isNotEmpty()) {
|
||||||
|
hasAnnotationCallWithArguments = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val phase = if (hasAnnotationCallWithArguments) {
|
||||||
FirResolvePhase.ANNOTATIONS_ARGUMENTS_MAPPING
|
FirResolvePhase.ANNOTATIONS_ARGUMENTS_MAPPING
|
||||||
} else {
|
} else {
|
||||||
FirResolvePhase.TYPES
|
FirResolvePhase.TYPES
|
||||||
|
|||||||
Reference in New Issue
Block a user