Skip to content

Commit 96ea53c

Browse files
committed
Inline reflect sources needed for Dotty
1 parent 3677d34 commit 96ea53c

17 files changed

+1700
-24
lines changed

compiler/src/dotty/tools/dotc/classpath/VirtualDirectoryClassPath.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import dotty.tools.io.{AbstractFile, Path, PlainFile, VirtualDirectory}
55
import FileUtils._
66
import java.net.URL
77

8-
import scala.reflect.internal.util.AbstractFileClassLoader
98
import dotty.tools.io.ClassPath
109

1110
case class VirtualDirectoryClassPath(dir: VirtualDirectory) extends ClassPath with DirectoryLookup[ClassFileEntryImpl] with NoSourcePaths {

compiler/src/dotty/tools/dotc/sbt/ExtractDependencies.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ class ExtractDependencies extends Phase {
101101
val classSegments = Path(ze.path).segments
102102
binaryDependency(zipFile, className(classSegments))
103103
}
104-
case pf: scala.reflect.io.PlainFile =>
104+
case pf: dotty.tools.io.PlainFile =>
105105
val packages = dep.ownersIterator
106106
.filter(x => x.is(PackageClass) && !x.isEffectiveRoot).length
107107
// We can recover the fully qualified name of a classfile from
Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
1+
/* NSC -- new Scala compiler
2+
* Copyright 2005-2013 LAMP/EPFL
3+
* @author Martin Odersky
4+
*/
5+
6+
package dotty.tools.io
7+
8+
import java.io.{
9+
IOException, InputStream, OutputStream, BufferedOutputStream,
10+
ByteArrayOutputStream
11+
}
12+
import java.net.URL
13+
14+
/**
15+
* An abstraction over files for use in the reflection/compiler libraries.
16+
*
17+
* ''Note: This library is considered experimental and should not be used unless you know what you are doing.''
18+
*
19+
* @author Philippe Altherr
20+
* @version 1.0, 23/03/2004
21+
*/
22+
object AbstractFile {
23+
/** Returns "getFile(new File(path))". */
24+
def getFile(path: String): AbstractFile = getFile(File(path))
25+
def getFile(path: Path): AbstractFile = getFile(path.toFile)
26+
27+
/**
28+
* If the specified File exists and is a regular file, returns an
29+
* abstract regular file backed by it. Otherwise, returns `null`.
30+
*/
31+
def getFile(file: File): AbstractFile =
32+
if (file.isFile) new PlainFile(file) else null
33+
34+
/** Returns "getDirectory(new File(path))". */
35+
def getDirectory(path: Path): AbstractFile = getDirectory(path.toFile)
36+
37+
/**
38+
* If the specified File exists and is either a directory or a
39+
* readable zip or jar archive, returns an abstract directory
40+
* backed by it. Otherwise, returns `null`.
41+
*/
42+
def getDirectory(file: File): AbstractFile =
43+
if (file.isDirectory) new PlainFile(file)
44+
else if (file.isFile && Path.isExtensionJarOrZip(file.jfile)) ZipArchive fromFile file
45+
else null
46+
47+
/**
48+
* If the specified URL exists and is a regular file or a directory, returns an
49+
* abstract regular file or an abstract directory, respectively, backed by it.
50+
* Otherwise, returns `null`.
51+
*/
52+
def getURL(url: URL): AbstractFile =
53+
if (url.getProtocol == "file") {
54+
val f = new java.io.File(url.getPath)
55+
if (f.isDirectory) getDirectory(f)
56+
else getFile(f)
57+
} else null
58+
59+
def getResources(url: URL): AbstractFile = ZipArchive fromManifestURL url
60+
}
61+
62+
/**
63+
* <p>
64+
* This class and its children serve to unify handling of files and
65+
* directories. These files and directories may or may not have some
66+
* real counter part within the file system. For example, some file
67+
* handles reference files within a zip archive or virtual ones
68+
* that exist only in memory.
69+
* </p>
70+
* <p>
71+
* Every abstract file has a path (i.e. a full name) and a name
72+
* (i.e. a short name) and may be backed by some real File. There are
73+
* two different kinds of abstract files: regular files and
74+
* directories. Regular files may be read and have a last modification
75+
* time. Directories may list their content and look for subfiles with
76+
* a specified name or path and of a specified kind.
77+
* </p>
78+
* <p>
79+
* The interface does <b>not</b> allow to access the content.
80+
* The class `symtab.classfile.AbstractFileReader` accesses
81+
* bytes, knowing that the character set of classfiles is UTF-8. For
82+
* all other cases, the class `SourceFile` is used, which honors
83+
* `global.settings.encoding.value`.
84+
* </p>
85+
*
86+
* ''Note: This library is considered experimental and should not be used unless you know what you are doing.''
87+
*/
88+
abstract class AbstractFile extends Iterable[AbstractFile] {
89+
90+
/** Returns the name of this abstract file. */
91+
def name: String
92+
93+
/** Returns the path of this abstract file. */
94+
def path: String
95+
96+
/** Returns the path of this abstract file in a canonical form. */
97+
def canonicalPath: String = if (file == null) path else file.getCanonicalPath
98+
99+
/** Checks extension case insensitively. */
100+
def hasExtension(other: String) = extension == other.toLowerCase
101+
private lazy val extension: String = Path.extension(name)
102+
103+
/** The absolute file, if this is a relative file. */
104+
def absolute: AbstractFile
105+
106+
/** Returns the containing directory of this abstract file */
107+
def container : AbstractFile
108+
109+
/** Returns the underlying File if any and null otherwise. */
110+
def file: JFile
111+
112+
/** An underlying source, if known. Mostly, a zip/jar file. */
113+
def underlyingSource: Option[AbstractFile] = None
114+
115+
/** Does this abstract file denote an existing file? */
116+
def exists: Boolean = {
117+
if (Statistics.canEnable) Statistics.incCounter(IOStats.fileExistsCount)
118+
(file eq null) || file.exists
119+
}
120+
121+
/** Does this abstract file represent something which can contain classfiles? */
122+
def isClassContainer = isDirectory || (file != null && (extension == "jar" || extension == "zip"))
123+
124+
/** Create a file on disk, if one does not exist already. */
125+
def create(): Unit
126+
127+
/** Delete the underlying file or directory (recursively). */
128+
def delete(): Unit
129+
130+
/** Is this abstract file a directory? */
131+
def isDirectory: Boolean
132+
133+
/** Does this abstract file correspond to something on-disk? */
134+
def isVirtual: Boolean = false
135+
136+
/** Returns the time that this abstract file was last modified. */
137+
def lastModified: Long
138+
139+
/** returns an input stream so the file can be read */
140+
def input: InputStream
141+
142+
/** Returns an output stream for writing the file */
143+
def output: OutputStream
144+
145+
/** Returns a buffered output stream for writing the file - defaults to out */
146+
def bufferedOutput: BufferedOutputStream = new BufferedOutputStream(output)
147+
148+
/** size of this file if it is a concrete file. */
149+
def sizeOption: Option[Int] = None
150+
151+
def toURL: URL = if (file == null) null else file.toURI.toURL
152+
153+
/** Returns contents of file (if applicable) in a Char array.
154+
* warning: use `Global.getSourceFile()` to use the proper
155+
* encoding when converting to the char array.
156+
*/
157+
@throws(classOf[IOException])
158+
def toCharArray = new String(toByteArray).toCharArray
159+
160+
/** Returns contents of file (if applicable) in a byte array.
161+
*/
162+
@throws(classOf[IOException])
163+
def toByteArray: Array[Byte] = {
164+
val in = input
165+
sizeOption match {
166+
case Some(size) =>
167+
var rest = size
168+
val arr = new Array[Byte](rest)
169+
while (rest > 0) {
170+
val res = in.read(arr, arr.length - rest, rest)
171+
if (res == -1)
172+
throw new IOException("read error")
173+
rest -= res
174+
}
175+
in.close()
176+
arr
177+
case None =>
178+
val out = new ByteArrayOutputStream()
179+
var c = in.read()
180+
while(c != -1) {
181+
out.write(c)
182+
c = in.read()
183+
}
184+
in.close()
185+
out.toByteArray()
186+
}
187+
}
188+
189+
/** Returns all abstract subfiles of this abstract directory. */
190+
def iterator: Iterator[AbstractFile]
191+
192+
/** Returns the abstract file in this abstract directory with the specified
193+
* name. If there is no such file, returns `null`. The argument
194+
* `directory` tells whether to look for a directory or
195+
* a regular file.
196+
*/
197+
def lookupName(name: String, directory: Boolean): AbstractFile
198+
199+
/** Returns an abstract file with the given name. It does not
200+
* check that it exists.
201+
*/
202+
def lookupNameUnchecked(name: String, directory: Boolean): AbstractFile
203+
204+
/** Return an abstract file that does not check that `path` denotes
205+
* an existing file.
206+
*/
207+
def lookupPathUnchecked(path: String, directory: Boolean): AbstractFile = {
208+
lookup((f, p, dir) => f.lookupNameUnchecked(p, dir), path, directory)
209+
}
210+
211+
private def lookup(getFile: (AbstractFile, String, Boolean) => AbstractFile,
212+
path0: String,
213+
directory: Boolean): AbstractFile = {
214+
val separator = java.io.File.separatorChar
215+
// trim trailing '/'s
216+
val path: String = if (path0.last == separator) path0 dropRight 1 else path0
217+
val length = path.length()
218+
assert(length > 0 && !(path.last == separator), path)
219+
var file = this
220+
var start = 0
221+
while (true) {
222+
val index = path.indexOf(separator, start)
223+
assert(index < 0 || start < index, ((path, directory, start, index)))
224+
val name = path.substring(start, if (index < 0) length else index)
225+
file = getFile(file, name, if (index < 0) directory else true)
226+
if ((file eq null) || index < 0) return file
227+
start = index + 1
228+
}
229+
file
230+
}
231+
232+
private def fileOrSubdirectoryNamed(name: String, isDir: Boolean): AbstractFile = {
233+
val lookup = lookupName(name, isDir)
234+
if (lookup != null) lookup
235+
else {
236+
val jfile = new JFile(file, name)
237+
if (isDir) jfile.mkdirs() else jfile.createNewFile()
238+
new PlainFile(jfile)
239+
}
240+
}
241+
242+
/**
243+
* Get the file in this directory with the given name,
244+
* creating an empty file if it does not already existing.
245+
*/
246+
def fileNamed(name: String): AbstractFile = {
247+
assert(isDirectory, "Tried to find '%s' in '%s' but it is not a directory".format(name, path))
248+
fileOrSubdirectoryNamed(name, isDir = false)
249+
}
250+
251+
/**
252+
* Get the subdirectory with a given name, creating it if it
253+
* does not already exist.
254+
*/
255+
def subdirectoryNamed(name: String): AbstractFile = {
256+
assert (isDirectory, "Tried to find '%s' in '%s' but it is not a directory".format(name, path))
257+
fileOrSubdirectoryNamed(name, isDir = true)
258+
}
259+
260+
protected def unsupported(): Nothing = unsupported(null)
261+
protected def unsupported(msg: String): Nothing = throw new UnsupportedOperationException(msg)
262+
263+
/** Returns the path of this abstract file. */
264+
override def toString() = path
265+
266+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/* __ *\
2+
** ________ ___ / / ___ Scala API **
3+
** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL **
4+
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5+
** /____/\___/_/ |_/____/_/ | | **
6+
** |/ **
7+
\* */
8+
9+
package dotty.tools.io
10+
11+
/**
12+
* ''Note: This library is considered experimental and should not be used unless you know what you are doing.''
13+
*/
14+
object Directory {
15+
import scala.util.Properties.userDir
16+
17+
private def normalizePath(s: String) = Some(apply(Path(s).normalize))
18+
def Current: Option[Directory] = if (userDir == "") None else normalizePath(userDir)
19+
20+
def apply(path: Path): Directory = path.toDirectory
21+
22+
// Like File.makeTemp but creates a directory instead
23+
def makeTemp(prefix: String = Path.randomPrefix, suffix: String = null, dir: JFile = null): Directory = {
24+
val path = File.makeTemp(prefix, suffix, dir)
25+
path.delete()
26+
path.createDirectory()
27+
}
28+
}
29+
30+
/** An abstraction for directories.
31+
*
32+
* @author Paul Phillips
33+
* @since 2.8
34+
*
35+
* ''Note: This is library is considered experimental and should not be used unless you know what you are doing.''
36+
*/
37+
class Directory(jfile: JFile) extends Path(jfile) {
38+
override def toAbsolute: Directory = if (isAbsolute) this else super.toAbsolute.toDirectory
39+
override def toDirectory: Directory = this
40+
override def toFile: File = new File(jfile)
41+
override def normalize: Directory = super.normalize.toDirectory
42+
43+
/** An iterator over the contents of this directory.
44+
*/
45+
def list: Iterator[Path] =
46+
jfile.listFiles match {
47+
case null => Iterator.empty
48+
case xs => xs.iterator map Path.apply
49+
}
50+
51+
def dirs: Iterator[Directory] = list collect { case x: Directory => x }
52+
def files: Iterator[File] = list collect { case x: File => x }
53+
54+
override def walkFilter(cond: Path => Boolean): Iterator[Path] =
55+
list filter cond flatMap (_ walkFilter cond)
56+
57+
def deepFiles: Iterator[File] = Path.onlyFiles(deepList())
58+
59+
/** If optional depth argument is not given, will recurse
60+
* until it runs out of contents.
61+
*/
62+
def deepList(depth: Int = -1): Iterator[Path] =
63+
if (depth < 0) list ++ (dirs flatMap (_ deepList (depth)))
64+
else if (depth == 0) Iterator.empty
65+
else list ++ (dirs flatMap (_ deepList (depth - 1)))
66+
}

0 commit comments

Comments
 (0)