Skip to content

Commit 63a348c

Browse files
authored
Merge pull request #264 from eatkins/demorgan
Apply DeMorgan's rule to not filters
2 parents 6d9aab1 + f0a8866 commit 63a348c

File tree

2 files changed

+49
-11
lines changed

2 files changed

+49
-11
lines changed

io/src/main/scala/sbt/nio/file/PathFilter.scala

+15-11
Original file line numberDiff line numberDiff line change
@@ -122,12 +122,18 @@ object PathFilter extends LowPriorityPathFilter {
122122
case g => new OrPathFilter(f, g)
123123
}
124124
}
125-
def unary_! : PathFilter = pathFilter match {
126-
case AllPass => NoPass
127-
case NoPass => AllPass
128-
case IsHidden => IsNotHidden
129-
case IsNotHidden => IsHidden
130-
case pf => new NotPathFilter(pf)
125+
def unary_! : PathFilter = {
126+
def not(pf: PathFilter): PathFilter = pf match {
127+
case AllPass => NoPass
128+
case NoPass => AllPass
129+
case IsHidden => IsNotHidden
130+
case IsNotHidden => IsHidden
131+
case p: NotPathFilter => p.filter
132+
case af: AndPathFilter => new OrPathFilter(not(af.left), not(af.right))
133+
case of: OrPathFilter => new AndPathFilter(not(of.left), not(of.right))
134+
case pf => new NotPathFilter(pf)
135+
}
136+
not(pathFilter)
131137
}
132138
}
133139

@@ -257,8 +263,7 @@ private[sbt] case object NoPass extends PathFilter {
257263
override def accept(path: Path, attributes: FileAttributes): Boolean = false
258264
}
259265

260-
private[sbt] class AndPathFilter(private val left: PathFilter, private val right: PathFilter)
261-
extends PathFilter {
266+
private[sbt] class AndPathFilter(val left: PathFilter, val right: PathFilter) extends PathFilter {
262267
override def accept(path: Path, attributes: FileAttributes): Boolean =
263268
left.accept(path, attributes) && right.accept(path, attributes)
264269
override def equals(obj: Any): Boolean = obj match {
@@ -269,8 +274,7 @@ private[sbt] class AndPathFilter(private val left: PathFilter, private val right
269274
override def toString: String = s"$left && $right"
270275
}
271276

272-
private[sbt] class OrPathFilter(private val left: PathFilter, private val right: PathFilter)
273-
extends PathFilter {
277+
private[sbt] class OrPathFilter(val left: PathFilter, val right: PathFilter) extends PathFilter {
274278
override def accept(path: Path, attributes: FileAttributes): Boolean =
275279
left.accept(path, attributes) || right.accept(path, attributes)
276280
override def hashCode: Int = (left.## * 31) ^ right.##
@@ -281,7 +285,7 @@ private[sbt] class OrPathFilter(private val left: PathFilter, private val right:
281285
override def toString: String = s"$left || $right"
282286
}
283287

284-
private[sbt] class NotPathFilter(private val filter: PathFilter) extends PathFilter {
288+
private[sbt] class NotPathFilter(val filter: PathFilter) extends PathFilter {
285289
override def accept(path: Path, attributes: FileAttributes): Boolean =
286290
!filter.accept(path, attributes)
287291
override def equals(obj: Any): Boolean = obj match {

io/src/test/scala/sbt/nio/PathFilterSpec.scala

+34
Original file line numberDiff line numberDiff line change
@@ -126,4 +126,38 @@ class PathFilterSpec extends FlatSpec {
126126
assert(!(!notBar).accept(foo))
127127
assert((!notBar).accept(bar))
128128
}
129+
they should "negate" in IO.withTemporaryDirectory { dir =>
130+
val dirPath = dir.toPath
131+
val foo = Files.createFile(dirPath / "foo.txt")
132+
val hidden = Files.createFile(dirPath / ".hidden").setHidden
133+
val filter = IsDirectory && !IsHidden
134+
val notFilter = !filter
135+
assert(notFilter == (!IsDirectory || IsHidden))
136+
assert(!filter.accept(foo))
137+
assert(!filter.accept(hidden))
138+
assert(filter.accept(dirPath))
139+
assert(notFilter.accept(foo))
140+
assert(notFilter.accept(hidden))
141+
assert(!notFilter.accept(dirPath))
142+
143+
val tripleAndFilter = IsDirectory && !IsHidden && !(** / "*.txt")
144+
val notTripleAndFilter = !tripleAndFilter
145+
assert(notTripleAndFilter == (!IsDirectory || IsHidden || (** / "*.txt")))
146+
assert(!(tripleAndFilter.accept(foo)))
147+
assert(tripleAndFilter.accept(dirPath))
148+
assert(!(tripleAndFilter.accept(hidden)))
149+
assert(notTripleAndFilter.accept(foo))
150+
assert(notTripleAndFilter.accept(hidden))
151+
assert(!(notTripleAndFilter.accept(dirPath)))
152+
153+
val tripleOrFilter = IsDirectory || IsHidden || (** / "*.txt")
154+
val notTripleOrFilter = !tripleOrFilter
155+
assert(notTripleOrFilter == (!IsDirectory && !IsHidden && !(** / "*.txt")))
156+
assert(tripleOrFilter.accept(foo))
157+
assert(tripleOrFilter.accept(hidden))
158+
assert(tripleOrFilter.accept(dirPath))
159+
assert(!(notTripleOrFilter.accept(foo)))
160+
assert(!(notTripleOrFilter.accept(hidden)))
161+
assert(!(notTripleOrFilter.accept(dirPath)))
162+
}
129163
}

0 commit comments

Comments
 (0)