<commit_before>package com.sageserpent.plutonium

import java.lang.reflect.{Method, Modifier}
import java.time.Instant
import java.util.Optional
import java.util.concurrent.Callable

import com.sageserpent.americium.{Finite, NegativeInfinity, PositiveInfinity, Unbounded}
import com.sageserpent.plutonium.World.Revision
import net.bytebuddy.ByteBuddy
import net.bytebuddy.description.method.MethodDescription
import net.bytebuddy.dynamic.DynamicType.Builder
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy
import net.bytebuddy.dynamic.scaffold.subclass.ConstructorStrategy
import net.bytebuddy.implementation.bind.annotation._
import net.bytebuddy.implementation.{FieldAccessor, FixedValue, MethodDelegation}
import net.bytebuddy.matcher.{BooleanMatcher, ElementMatcher, ElementMatchers, NameMatcher}
import resource.{ManagedResource, makeManagedResource}

import scala.collection.JavaConversions._
import scala.collection.Searching._
import scala.collection.mutable
import scala.reflect.runtime._
import scala.reflect.runtime.universe.{Super => _, This => _, _}
/**
  * Created by Gerard on 19/07/2015.
  */


object WorldImplementationCodeFactoring {
  type EventOrderingTiebreakerIndex = Int

  sealed abstract class AbstractEventData extends java.io.Serializable {
    val introducedInRevision: Revision
  }

  case class EventData(serializableEvent: SerializableEvent, override val introducedInRevision: Revision, eventOrderingTiebreakerIndex: EventOrderingTiebreakerIndex) extends AbstractEventData

  case class AnnulledEventData(override val introducedInRevision: Revision) extends AbstractEventData

  implicit val eventOrdering = Ordering.by((_: SerializableEvent).when)

  implicit val eventDataOrdering: Ordering[EventData] = Ordering.by {
    case EventData(serializableEvent, introducedInRevision, eventOrderingTiebreakerIndex) =>
      (serializableEvent, introducedInRevision, eventOrderingTiebreakerIndex)
  }

  def eventTimelineFrom(eventDatums: Seq[AbstractEventData]): Seq[SerializableEvent] = (eventDatums collect {
    case eventData: EventData => eventData
  }).sorted.map(_.serializableEvent)

  def serializableEventFrom(event: Event): SerializableEvent = {
    val patchesPickedUpFromAnEventBeingApplied = mutable.MutableList.empty[AbstractPatch]

    class LocalRecorderFactory extends RecorderFactory {
      override def apply[Raw <: Identified : TypeTag](id: Raw#Id): Raw = {
        val proxyFactory = new ProxyFactory {
          val isForRecordingOnly = true

          class AcquiredState{
            val _id: Raw#Id = id
            val _typeTag: TypeTag[Raw] = typeTag[Raw]
            def capturePatch(patch: AbstractPatch) {
              patchesPickedUpFromAnEventBeingApplied += patch
            }
          }

          override val stateToBeAcquiredByProxy: AcquiredState = new AcquiredState

          val stateAcquisitionTrait = classOf[StateAcquisition]

          override val additionalInterfaces: Array[Class[_]] = RecordingCallbackStuff.additionalInterfaces
          override val cachedProxyConstructors: mutable.Map[Type, (universe.MethodMirror, Class[_])] = RecordingCallbackStuff.cachedProxyConstructors

          val matchItemReconstitutionData: ElementMatcher[MethodDescription] = methodDescription => firstMethodIsOverrideCompatibleWithSecond(methodDescription, IdentifiedItemsScope.itemReconstitutionDataProperty)

          val matchPermittedReadAccess: ElementMatcher[MethodDescription] = methodDescription => IdentifiedItemsScope.alwaysAllowsReadAccessTo(methodDescription) || RecordingCallbackStuff.isFinalizer(methodDescription)

          val matchForbiddenReadAccess: ElementMatcher[MethodDescription] = methodDescription => !methodDescription.getReturnType.represents(classOf[Unit])

          val matchMutation: ElementMatcher[MethodDescription] = new BooleanMatcher(true)

          class ItemReconstitutionData {
            @RuntimeType
            def apply(@RuntimeType @FieldValue("acquiredState") acquiredState: AcquiredState) = acquiredState._id -> acquiredState._typeTag
          }

          // TODO - this is just a hokey no-operation - remove it!
          object permittedReadAccess {
            @RuntimeType
            def apply(@SuperCall superCall: Callable[_]) = superCall.call()
            }

          object forbiddenReadAccess {
            @RuntimeType
            def apply(@Origin method: Method, @This target: AnyRef) = {
              throw new UnsupportedOperationException(s"Attempt to call method: '$method' with a non-unit return type on a recorder proxy: '$target' while capturing a change or measurement.")
            }
          }

          object mutation {
            @RuntimeType
            def apply(@Origin method: Method, @AllArguments arguments: Array[AnyRef], @This target: AnyRef, @RuntimeType @FieldValue("acquiredState") acquiredState: AcquiredState) = {
              val item = target.asInstanceOf[Recorder]<commit_msg>Tidy up the state acquired by recording proxies.<commit_after>package com.sageserpent.plutonium

import java.lang.reflect.{Method, Modifier}
import java.time.Instant
import java.util.Optional
import java.util.concurrent.Callable

import com.sageserpent.americium.{Finite, NegativeInfinity, PositiveInfinity, Unbounded}
import com.sageserpent.plutonium.World.Revision
import net.bytebuddy.ByteBuddy
import net.bytebuddy.description.method.MethodDescription
import net.bytebuddy.dynamic.DynamicType.Builder
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy
import net.bytebuddy.dynamic.scaffold.subclass.ConstructorStrategy
import net.bytebuddy.implementation.bind.annotation._
import net.bytebuddy.implementation.{FieldAccessor, FixedValue, MethodDelegation}
import net.bytebuddy.matcher.{BooleanMatcher, ElementMatcher, ElementMatchers, NameMatcher}
import resource.{ManagedResource, makeManagedResource}

import scala.collection.JavaConversions._
import scala.collection.Searching._
import scala.collection.mutable
import scala.reflect.runtime._
import scala.reflect.runtime.universe.{Super => _, This => _, _}
/**
  * Created by Gerard on 19/07/2015.
  */


object WorldImplementationCodeFactoring {
  type EventOrderingTiebreakerIndex = Int

  sealed abstract class AbstractEventData extends java.io.Serializable {
    val introducedInRevision: Revision
  }

  case class EventData(serializableEvent: SerializableEvent, override val introducedInRevision: Revision, eventOrderingTiebreakerIndex: EventOrderingTiebreakerIndex) extends AbstractEventData

  case class AnnulledEventData(override val introducedInRevision: Revision) extends AbstractEventData

  implicit val eventOrdering = Ordering.by((_: SerializableEvent).when)

  implicit val eventDataOrdering: Ordering[EventData] = Ordering.by {
    case EventData(serializableEvent, introducedInRevision, eventOrderingTiebreakerIndex) =>
      (serializableEvent, introducedInRevision, eventOrderingTiebreakerIndex)
  }

  def eventTimelineFrom(eventDatums: Seq[AbstractEventData]): Seq[SerializableEvent] = (eventDatums collect {
    case eventData: EventData => eventData
  }).sorted.map(_.serializableEvent)

  def serializableEventFrom(event: Event): SerializableEvent = {
    val patchesPickedUpFromAnEventBeingApplied = mutable.MutableList.empty[AbstractPatch]

    class LocalRecorderFactory extends RecorderFactory {
      override def apply[Raw <: Identified : TypeTag](id: Raw#Id): Raw = {
        val proxyFactory = new ProxyFactory {
          val isForRecordingOnly = true

          class AcquiredState{
            def itemReconstitutionData = id -> typeTag[Raw]
            def capturePatch(patch: AbstractPatch) {
              patchesPickedUpFromAnEventBeingApplied += patch
            }
          }

          override val stateToBeAcquiredByProxy: AcquiredState = new AcquiredState

          val stateAcquisitionTrait = classOf[StateAcquisition]

          override val additionalInterfaces: Array[Class[_]] = RecordingCallbackStuff.additionalInterfaces
          override val cachedProxyConstructors: mutable.Map[Type, (universe.MethodMirror, Class[_])] = RecordingCallbackStuff.cachedProxyConstructors

          val matchItemReconstitutionData: ElementMatcher[MethodDescription] = methodDescription => firstMethodIsOverrideCompatibleWithSecond(methodDescription, IdentifiedItemsScope.itemReconstitutionDataProperty)

          val matchPermittedReadAccess: ElementMatcher[MethodDescription] = methodDescription => IdentifiedItemsScope.alwaysAllowsReadAccessTo(methodDescription) || RecordingCallbackStuff.isFinalizer(methodDescription)

          val matchForbiddenReadAccess: ElementMatcher[MethodDescription] = methodDescription => !methodDescription.getReturnType.represents(classOf[Unit])

          val matchMutation: ElementMatcher[MethodDescription] = new BooleanMatcher(true)

          class ItemReconstitutionData {
            @RuntimeType
            def apply(@RuntimeType @FieldValue("acquiredState") acquiredState: AcquiredState) = acquiredState.itemReconstitutionData
          }

          // TODO - this is just a hokey no-operation - remove it!
          object permittedReadAccess {
            @RuntimeType
            def apply(@SuperCall superCall: Callable[_]) = superCall.call()
            }

          object forbiddenReadAccess {
            @RuntimeType
            def apply(@Origin method: Method, @This target: AnyRef) = {
              throw new UnsupportedOperationException(s"Attempt to call method: '$method' with a non-unit return type on a recorder proxy: '$target' while capturing a change or measurement.")
            }
          }

          object mutation {
            @RuntimeType
            def apply(@Origin method: Method, @AllArguments arguments: Array[AnyRef], @This target: AnyRef, @RuntimeType @FieldValue("acquiredState") acquiredState: AcquiredState) = {
              val item = target.asInstanceOf[Recorder]
{'fraction_non_alphanumeric': 0.07449278288079136, 'fraction_numerical': 0.001615019683052387, 'mean_word_length': 4.344120819848976, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 19, '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': '423144', 'n_tokens_mistral': 2637, 'n_tokens_neox': 2501, 'n_words': 567}