@@ -23,58 +23,20 @@ import org.opalj.br.fpcf.PropertyStoreKey
2323import org .opalj .br .fpcf .analyses .ContextProvider
2424import org .opalj .br .fpcf .properties .cg .Callees
2525
26- class DirectCallMatcher extends AbstractPropertyMatcher {
26+ class DirectCallMatcher extends AbstractRepeatablePropertyMatcher {
27+ override val singleAnnotationType : ObjectType = ObjectType (" org/opalj/fpcf/properties/callgraph/DirectCall" )
28+ override val containerAnnotationType : ObjectType = ObjectType (" org/opalj/fpcf/properties/callgraph/DirectCalls" )
2729
28- override def validateProperty (
30+ override def validateSingleProperty (
2931 p : Project [_],
3032 as : Set [ObjectType ],
3133 entity : Any ,
3234 a : AnnotationLike ,
3335 properties : Iterable [Property ]
3436 ): Option [String ] = {
35- // If the entity is annotated with a single annotation, we receive a DirectCall annotation.
36- // If it is annotated with multiple DirectCall annotations, we receive a single DirectCalls
37- // container annotation.
38- val singleAnnotation = ObjectType (" org/opalj/fpcf/properties/callgraph/DirectCall" )
39- val containerAnnotation = ObjectType (" org/opalj/fpcf/properties/callgraph/DirectCalls" )
40-
41- if (a.annotationType == singleAnnotation) {
42- validateSingleAnnotation(p, as, entity, a, properties)
43-
44- } else if (a.annotationType == containerAnnotation) {
45- // Get sub-annotations from the container annotation.
46- val subAnnotations : ArraySeq [AnnotationLike ] =
47- getValue(p, containerAnnotation, a.elementValuePairs, " value" )
48- .asArrayValue.values.map(a => a.asAnnotationValue.annotation)
49-
50- // Validate each sub-annotation individually.
51- val validationResults =
52- subAnnotations.map(validateSingleAnnotation(p, as, entity, _, properties))
53- val errors = validationResults.filter(_.isDefined)
54-
55- if (errors.nonEmpty) {
56- Some (errors.mkString(" , " ))
57- } else {
58- None
59- }
60-
61- } else {
62- Some (" Invalid annotation." )
63- }
64- }
65-
66- private def validateSingleAnnotation (
67- p : Project [_],
68- as : Set [ObjectType ],
69- entity : Any ,
70- a : AnnotationLike ,
71- properties : Iterable [Property ]
72- ): Option [String ] = {
73- val annotationType = a.annotationType.asObjectType
74-
7537 // Get call graph analyses for which this annotation applies.
7638 val analysesElementValues : Seq [ElementValue ] =
77- getValue(p, annotationType , a.elementValuePairs, " analyses" ).asArrayValue.values
39+ getValue(p, singleAnnotationType , a.elementValuePairs, " analyses" ).asArrayValue.values
7840 val analyses = analysesElementValues.map(ev => ev.asClassValue.value.asObjectType)
7941
8042 // If none of the annotated analyses match the executed ones, return...
@@ -119,8 +81,8 @@ class DirectCallMatcher extends AbstractPropertyMatcher {
11981 // Fetch values from the annotation.
12082 // TODO clean these up and move them into some helper?
12183 // note: there is a helper class in JCG that does something similar
122- val lineNumber = getValue(p, annotationType , a.elementValuePairs, " line" ).asIntValue.value
123- val methodName = getValue(p, annotationType , a.elementValuePairs, " name" ).asStringValue.value
84+ val lineNumber = getValue(p, singleAnnotationType , a.elementValuePairs, " line" ).asIntValue.value
85+ val methodName = getValue(p, singleAnnotationType , a.elementValuePairs, " name" ).asStringValue.value
12486 val resolvedTargets = {
12587 val av = a.elementValuePairs collectFirst {
12688 case ElementValuePair (" resolvedTargets" , ArrayValue (ab)) =>
0 commit comments