44package scala .tools .nsc .classpath
55
66import java .io .File
7- import java .io .FileFilter
87import java .net .URL
98import scala .reflect .io .AbstractFile
109import scala .reflect .io .PlainFile
1110import scala .tools .nsc .util .ClassRepresentation
1211import FileUtils ._
1312
1413/**
15- * A trait allowing to look for classpath entries of given type in directories.
16- * It provides common logic for classes handling class and source files.
14+ * A trait allowing to look for classpath entries in directories. It provides common logic for
15+ * classes handling class and source files.
1716 * It makes use of the fact that in the case of nested directories it's easy to find a file
1817 * when we have a name of a package.
18+ * It abstracts over the file representation to work with both JFile and AbstractFile.
1919 */
20- trait DirectoryFileLookup [FileEntryType <: ClassRepClassPathEntry ] extends FlatClassPath {
21- val dir : File
22- assert(dir != null , " Directory file in DirectoryFileLookup cannot be null" )
20+ trait DirectoryLookup [FileEntryType <: ClassRepClassPathEntry ] extends FlatClassPath {
21+ type F
22+
23+ val dir : F
24+
25+ protected def emptyFiles : Array [F ] // avoids reifying ClassTag[F]
26+ protected def getSubDir (dirName : String ): Option [F ]
27+ protected def listChildren (dir : F , filter : Option [F => Boolean ] = None ): Array [F ]
28+ protected def getName (f : F ): String
29+ protected def toAbstractFile (f : F ): AbstractFile
30+ protected def isPackage (f : F ): Boolean
2331
24- override def asURLs : Seq [ URL ] = Seq (dir.toURI.toURL)
25- override def asClassPathStrings : Seq [ String ] = Seq (dir.getPath)
32+ protected def createFileEntry ( file : AbstractFile ) : FileEntryType
33+ protected def isMatchingFile ( f : F ) : Boolean
2634
27- import FlatClassPath .RootPackage
28- private def getDirectory (forPackage : String ): Option [File ] = {
29- if (forPackage == RootPackage ) {
35+ private def getDirectory (forPackage : String ): Option [F ] = {
36+ if (forPackage == FlatClassPath .RootPackage ) {
3037 Some (dir)
3138 } else {
3239 val packageDirName = FileUtils .dirPath(forPackage)
33- val packageDir = new File (dir, packageDirName)
34- if (packageDir.exists && packageDir.isDirectory) {
35- Some (packageDir)
36- } else None
40+ getSubDir(packageDirName)
3741 }
3842 }
3943
40- override private [nsc] def packages (inPackage : String ): Seq [PackageEntry ] = {
44+ private [nsc] def packages (inPackage : String ): Seq [PackageEntry ] = {
4145 val dirForPackage = getDirectory(inPackage)
42- val nestedDirs : Array [File ] = dirForPackage match {
43- case None => Array .empty
44- case Some (directory) => directory.listFiles( DirectoryFileLookup .packageDirectoryFileFilter )
46+ val nestedDirs : Array [F ] = dirForPackage match {
47+ case None => emptyFiles
48+ case Some (directory) => listChildren( directory, Some (isPackage) )
4549 }
4650 val prefix = PackageNameUtils .packagePrefix(inPackage)
47- val entries = nestedDirs map { file =>
48- PackageEntryImpl (prefix + file.getName)
49- }
50- entries
51+ nestedDirs.map(f => PackageEntryImpl (prefix + getName(f)))
5152 }
5253
5354 protected def files (inPackage : String ): Seq [FileEntryType ] = {
5455 val dirForPackage = getDirectory(inPackage)
55- val files : Array [File ] = dirForPackage match {
56- case None => Array .empty
57- case Some (directory) => directory.listFiles(fileFilter)
58- }
59- val entries = files map { file =>
60- val wrappedFile = new scala.reflect.io.File (file)
61- createFileEntry(new PlainFile (wrappedFile))
56+ val files : Array [F ] = dirForPackage match {
57+ case None => emptyFiles
58+ case Some (directory) => listChildren(directory, Some (isMatchingFile))
6259 }
63- entries
60+ files.map(f => createFileEntry(toAbstractFile(f)))
6461 }
6562
66- override private [nsc] def list (inPackage : String ): FlatClassPathEntries = {
63+ private [nsc] def list (inPackage : String ): FlatClassPathEntries = {
6764 val dirForPackage = getDirectory(inPackage)
68- val files : Array [File ] = dirForPackage match {
69- case None => Array .empty
70- case Some (directory) => directory.listFiles( )
65+ val files : Array [F ] = dirForPackage match {
66+ case None => emptyFiles
67+ case Some (directory) => listChildren(directory )
7168 }
7269 val packagePrefix = PackageNameUtils .packagePrefix(inPackage)
7370 val packageBuf = collection.mutable.ArrayBuffer .empty[PackageEntry ]
7471 val fileBuf = collection.mutable.ArrayBuffer .empty[FileEntryType ]
7572 for (file <- files) {
76- if (file.isPackage) {
77- val pkgEntry = PackageEntryImpl (packagePrefix + file.getName)
78- packageBuf += pkgEntry
79- } else if (fileFilter.accept(file)) {
80- val wrappedFile = new scala.reflect.io.File (file)
81- val abstractFile = new PlainFile (wrappedFile)
82- fileBuf += createFileEntry(abstractFile)
83- }
73+ if (isPackage(file))
74+ packageBuf += PackageEntryImpl (packagePrefix + getName(file))
75+ else if (isMatchingFile(file))
76+ fileBuf += createFileEntry(toAbstractFile(file))
8477 }
8578 FlatClassPathEntries (packageBuf, fileBuf)
8679 }
87-
88- protected def createFileEntry (file : AbstractFile ): FileEntryType
89- protected def fileFilter : FileFilter
9080}
9181
92- object DirectoryFileLookup {
82+ trait JFileDirectoryLookup [FileEntryType <: ClassRepClassPathEntry ] extends DirectoryLookup [FileEntryType ] {
83+ type F = File
9384
94- private [classpath] object packageDirectoryFileFilter extends FileFilter {
95- override def accept (pathname : File ): Boolean = pathname.isPackage
85+ protected def emptyFiles : Array [File ] = Array .empty
86+ protected def getSubDir (packageDirName : String ): Option [File ] = {
87+ val packageDir = new File (dir, packageDirName)
88+ if (packageDir.exists && packageDir.isDirectory) Some (packageDir)
89+ else None
9690 }
97- }
91+ protected def listChildren (dir : File , filter : Option [File => Boolean ]): Array [File ] = filter match {
92+ case Some (f) => dir.listFiles(mkFileFilter(f))
93+ case None => dir.listFiles()
94+ }
95+ protected def getName (f : File ): String = f.getName
96+ protected def toAbstractFile (f : File ): AbstractFile = new PlainFile (new scala.reflect.io.File (f))
97+ protected def isPackage (f : File ): Boolean = f.isPackage
9898
99- case class DirectoryFlatClassPath (dir : File )
100- extends DirectoryFileLookup [ClassFileEntryImpl ]
101- with NoSourcePaths {
99+ assert(dir != null , " Directory file in DirectoryFileLookup cannot be null" )
102100
101+ def asURLs : Seq [URL ] = Seq (dir.toURI.toURL)
102+ def asClassPathStrings : Seq [String ] = Seq (dir.getPath)
103+ }
104+
105+ case class DirectoryFlatClassPath (dir : File ) extends JFileDirectoryLookup [ClassFileEntryImpl ] with NoSourcePaths {
103106 override def findClass (className : String ): Option [ClassRepresentation [AbstractFile ]] = findClassFile(className) map ClassFileEntryImpl
104107
105- override def findClassFile (className : String ): Option [AbstractFile ] = {
108+ def findClassFile (className : String ): Option [AbstractFile ] = {
106109 val relativePath = FileUtils .dirPath(className)
107110 val classFile = new File (s " $dir/ $relativePath.class " )
108111 if (classFile.exists) {
@@ -112,31 +115,19 @@ case class DirectoryFlatClassPath(dir: File)
112115 } else None
113116 }
114117
115- override protected def createFileEntry (file : AbstractFile ): ClassFileEntryImpl = ClassFileEntryImpl (file)
116- override protected def fileFilter : FileFilter = DirectoryFlatClassPath .classFileFilter
117-
118- override private [nsc] def classes (inPackage : String ): Seq [ClassFileEntry ] = files(inPackage)
119- }
120-
121- object DirectoryFlatClassPath {
118+ protected def createFileEntry (file : AbstractFile ): ClassFileEntryImpl = ClassFileEntryImpl (file)
119+ protected def isMatchingFile (f : File ): Boolean = f.isClass
122120
123- private val classFileFilter = new FileFilter {
124- override def accept (pathname : File ): Boolean = pathname.isClass
125- }
121+ private [nsc] def classes (inPackage : String ): Seq [ClassFileEntry ] = files(inPackage)
126122}
127123
128- case class DirectoryFlatSourcePath (dir : File )
129- extends DirectoryFileLookup [SourceFileEntryImpl ]
130- with NoClassPaths {
124+ case class DirectoryFlatSourcePath (dir : File ) extends JFileDirectoryLookup [SourceFileEntryImpl ] with NoClassPaths {
125+ def asSourcePathString : String = asClassPathString
131126
132- override def asSourcePathString : String = asClassPathString
127+ protected def createFileEntry (file : AbstractFile ): SourceFileEntryImpl = SourceFileEntryImpl (file)
128+ protected def isMatchingFile (f : File ): Boolean = endsScalaOrJava(f.getName)
133129
134- override protected def createFileEntry (file : AbstractFile ): SourceFileEntryImpl = SourceFileEntryImpl (file)
135- override protected def fileFilter : FileFilter = DirectoryFlatSourcePath .sourceFileFilter
136-
137- override def findClass (className : String ): Option [ClassRepresentation [AbstractFile ]] = {
138- findSourceFile(className) map SourceFileEntryImpl
139- }
130+ override def findClass (className : String ): Option [ClassRepresentation [AbstractFile ]] = findSourceFile(className) map SourceFileEntryImpl
140131
141132 private def findSourceFile (className : String ): Option [AbstractFile ] = {
142133 val relativePath = FileUtils .dirPath(className)
@@ -151,12 +142,5 @@ case class DirectoryFlatSourcePath(dir: File)
151142 }
152143 }
153144
154- override private [nsc] def sources (inPackage : String ): Seq [SourceFileEntry ] = files(inPackage)
155- }
156-
157- object DirectoryFlatSourcePath {
158-
159- private val sourceFileFilter = new FileFilter {
160- override def accept (pathname : File ): Boolean = endsScalaOrJava(pathname.getName)
161- }
145+ private [nsc] def sources (inPackage : String ): Seq [SourceFileEntry ] = files(inPackage)
162146}
0 commit comments