<commit_before>package edu.arizona.sista.matcher

import scala.reflect.ClassTag
import scala.reflect.runtime.universe._
import edu.arizona.sista.struct.Interval
import edu.arizona.sista.processors.Document

class ActionMirror[T <: Actions : ClassTag](obj: T) {
  private val instanceMirror = runtimeMirror(obj.getClass.getClassLoader).reflect(obj)

  def reflect(name: String): ReflectedAction = {
    val methodSymbol = instanceMirror.symbol.typeSignature.member(newTermName(name)).asMethod
    val methodMirror = instanceMirror.reflectMethod(methodSymbol)
    new ReflectedAction(name, methodMirror)
  }
}

class ReflectedAction(val name: String, methodMirror: MethodMirror) {
  def apply(label: String, mention: Map[String, Seq[Interval]], sent: Int, doc: Document, ruleName: String, state: State): Seq[Mention] =
    methodMirror(label, mention, sent, doc, ruleName, state).asInstanceOf[Seq[Mention]]
}
<commit_msg>synchronize reflection<commit_after>package edu.arizona.sista.matcher

import scala.reflect.ClassTag
import scala.reflect.runtime.universe._
import edu.arizona.sista.struct.Interval
import edu.arizona.sista.processors.Document

class ActionMirror[T <: Actions : ClassTag](obj: T) {
  private val instanceMirror = runtimeMirror(obj.getClass.getClassLoader).reflect(obj)

  def reflect(name: String): ReflectedAction = ActionMirror.Lock.synchronized {
    val methodSymbol = instanceMirror.symbol.typeSignature.member(newTermName(name)).asMethod
    val methodMirror = instanceMirror.reflectMethod(methodSymbol)
    new ReflectedAction(name, methodMirror)
  }
}

object ActionMirror {
  private object Lock  // scala reflection isn't thread-safe :(
}

class ReflectedAction(val name: String, methodMirror: MethodMirror) {
  def apply(label: String, mention: Map[String, Seq[Interval]], sent: Int, doc: Document, ruleName: String, state: State): Seq[Mention] =
    methodMirror(label, mention, sent, doc, ruleName, state).asInstanceOf[Seq[Mention]]
}

{'fraction_non_alphanumeric': 0.10879511947127606, 'fraction_numerical': 0.0, 'mean_word_length': 6.1046931407942235, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5105440', 'n_tokens_mistral': 618, 'n_tokens_neox': 593, 'n_words': 129}