* Determine the type of ignore pattern once per pattern.
Performing this work when checking when each file was ignored accounted
for around 4.5 of the 6 seconds that processing ignored files was taking
on a site with ~14,000 files and a small number of ignore patterns.
After this change, processing ignored files takes less than 1.5 seconds.
* Cache the normalized paths on Resource and SourceFile.
Normalizing the paths is expensive, so avoid doing it multiple
times. `Util::normalize_path` is marked as memoized, but this
is not effective as:
1. `memoize` doesn't appear to work with module functions.
2. Checking whether we have a memoized value is as expensive as
normalizing the path.
This further drops the time it takes to process ignored files on a site
with ~14,000 files from ~1.5 seconds to ~0.6 seconds.