Created
March 6, 2018 12:06
-
-
Save dwijnand/23380b784b9cefc2641d616a05ffdd25 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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