Skip to content

Instantly share code, notes, and snippets.

@dwijnand
Created March 6, 2018 12:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dwijnand/23380b784b9cefc2641d616a05ffdd25 to your computer and use it in GitHub Desktop.
Save dwijnand/23380b784b9cefc2641d616a05ffdd25 to your computer and use it in GitHub Desktop.
package t
import sbt._
object Main {
def simpleFileFilterFnClass(ff: FileFilter) = ff.asInstanceOf[SimpleFileFilter].acceptFunction.getClass
def simpleFilterFnClass(ff: FileFilter) = ff.asInstanceOf[SimpleFilter].acceptFunction.getClass
sealed abstract class Extractor {
def fnClass: Class[_ <: (Nothing => Boolean)]
final lazy val fnClassStr = fnClass.toString
final def getAcceptFn(ff: FileFilter): Option[Nothing => Boolean] = {
def check(fn: Nothing => Boolean) = fn.getClass.toString == fnClassStr
ff match {
case x: SimpleFileFilter if check(x.acceptFunction) => Some(x.acceptFunction)
case x: SimpleFilter if check(x.acceptFunction) => Some(x.acceptFunction)
case _ => None
}
}
final def getField(name: String) = {
val f = fnClass getDeclaredField name
f setAccessible true
f
}
final def getFileFilterField(f: java.lang.reflect.Field, value: Nothing => Boolean) = {
val fieldValue =
try f get value
catch {
case e: IllegalArgumentException =>
throw new IllegalArgumentException(s"Failed to get field on value $value", e)
}
fieldValue.asInstanceOf[FileFilter]
}
}
sealed class UnaryExtractor(val fnClass: Class[_ <: (Nothing => Boolean)]) extends Extractor {
final val field1 = getField("arg$1")
final def unapply(ff: FileFilter): Option[FileFilter] =
getAcceptFn(ff) map (getFileFilterField(field1, _))
}
sealed class DuoExtractor(val fnClass: Class[_ <: (Nothing => Boolean)]) extends Extractor {
final val field1 = getField("arg$1")
final val field2 = getField("arg$2")
final def unapply(ff: FileFilter): Option[(FileFilter, FileFilter)] =
getAcceptFn(ff) map (fn => (getFileFilterField(field1, fn), getFileFilterField(field2, fn)))
}
object || extends DuoExtractor(simpleFileFilterFnClass(AllPassFilter || AllPassFilter))
object && extends DuoExtractor(simpleFileFilterFnClass(AllPassFilter && AllPassFilter))
object -- extends DuoExtractor(simpleFileFilterFnClass(AllPassFilter -- AllPassFilter))
object SFF_Unary_- extends UnaryExtractor(simpleFileFilterFnClass(-HiddenFileFilter))
object | extends DuoExtractor(simpleFilterFnClass(AllPassFilter | AllPassFilter))
object & extends DuoExtractor(simpleFilterFnClass(AllPassFilter & AllPassFilter))
object - extends DuoExtractor(simpleFilterFnClass(AllPassFilter - AllPassFilter))
object SF_Unary_- extends UnaryExtractor(simpleFilterFnClass(-AllPassFilter))
def simpleFileFilterToString(sff: SimpleFileFilter) = sff match {
case ff1 || ff2 => s"SimpleFileFilter(${fileFilterToString(ff1)} || ${fileFilterToString(ff2)})"
case ff1 && ff2 => s"SimpleFileFilter(${fileFilterToString(ff1)} && ${fileFilterToString(ff2)})"
case ff1 -- ff2 => s"SimpleFileFilter(${fileFilterToString(ff1)} -- ${fileFilterToString(ff2)})"
case SFF_Unary_-(ff) => s"SimpleFileFilter(-${fileFilterToString(ff)})"
case _ => "" + sff
}
def simpleFilterToString(sf: SimpleFilter) = sf match {
case ff1 `|` ff2 => s"SimpleFilter(${fileFilterToString(ff1)} | ${fileFilterToString(ff2)})"
case ff1 & ff2 => s"SimpleFilter(${fileFilterToString(ff1)} & ${fileFilterToString(ff2)})"
case ff1 - ff2 => s"SimpleFilter(${fileFilterToString(ff1)} - ${fileFilterToString(ff2)})"
case SF_Unary_-(ff) => s"SimpleFilter(-${fileFilterToString(ff)})"
case _ => "" + sf
}
def fileFilterToString(f: FileFilter): String = f match {
case x: ExactFilter => s"ExactFilter(${x.matchName})"
case x: PatternFilter => s"PatternFilter(${x.pattern})"
case x: SimpleFileFilter => simpleFileFilterToString(x)
case x: SimpleFilter => simpleFilterToString(x)
case HiddenFileFilter => "HiddenFileFilter"
case AllPassFilter => "AllPassFilter"
case x => "" + x
}
def sourceToString(s: Watched.WatchSource): String = {
def field(name: String) = {
val cl = classOf[Watched.WatchSource]
val f = cl getDeclaredField name
f setAccessible true
f get s
}
def filterField(name: String) = fileFilterToString(field(name).asInstanceOf[FileFilter])
s"""Source(
| base = ${field("base")},
| includeFilter = ${filterField("includeFilter")},
| excludeFilter = ${filterField("excludeFilter")},
| recursive = ${field("recursive")},
|)""".stripMargin
}
}
// (watchSources in Compile).eval map sourceToString foreach println
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment