All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opalj.av.checking.FieldMatcher.scala Maven / Gradle / Ivy

The newest version!
/* BSD 2-Clause License - see OPAL/LICENSE for details. */
package org.opalj
package av
package checking

import scala.collection.immutable
import org.opalj.br.ClassFile
import org.opalj.br.FieldType
import org.opalj.br.Field
import org.opalj.br.analyses.SomeProject
import org.opalj.br.VirtualSourceElement

/**
 * Matches fields based on their name, type, annotations and declaring class.
 *
 * @author Marco Torsello
 * @author Michael Eichberg
 */
case class FieldMatcher(
        declaringClass: ClassLevelMatcher,
        annotations:    AnnotationsPredicate,
        theType:        Option[FieldType],
        theName:        Option[NamePredicate]
)
    extends SourceElementsMatcher {

    def doesClassFileMatch(classFile: ClassFile)(implicit project: SomeProject): Boolean = {
        declaringClass.doesMatch(classFile)
    }

    def doesFieldMatch(field: Field): Boolean = {
        (theType.isEmpty || (theType.get eq field.fieldType)) && (
            (theName.isEmpty || theName.get(field.name))
        ) &&
            annotations(field.annotations)
    }

    def extension(implicit project: SomeProject): immutable.Set[VirtualSourceElement] = {
        val allMatchedFields = project.allClassFiles collect {
            case classFile if doesClassFileMatch(classFile) => {
                classFile.fields collect {
                    case field if doesFieldMatch(field) => field.asVirtualField(classFile)
                }
            }
        }
        allMatchedFields.flatten.toSet
    }

}

/**
 * Defines several additional factory methods to facilitate the creation of
 * [[FieldMatcher]]s.
 *
 * @author Marco Torsello
 */
object FieldMatcher {

    def apply(
        declaringClass:       ClassLevelMatcher    = AllClasses,
        annotationsPredicate: AnnotationsPredicate = AnyAnnotations,
        theType:              Option[String]       = None,
        theName:              Option[String]       = None,
        matchPrefix:          Boolean              = false
    ): FieldMatcher = {

        assert(theName.isDefined || !matchPrefix)

        val nameMatcher: Option[NamePredicate] =
            theName match {
                case Some(f) =>
                    if (matchPrefix)
                        Some(StartsWith(f))
                    else
                        Some(Equals(f))
                case _ =>
                    None
            }

        new FieldMatcher(
            declaringClass,
            annotationsPredicate,
            theType.map(fqn => FieldType(fqn.replace('.', '/'))),
            nameMatcher
        )
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy