diff options
-rw-r--r-- | .gitattributes | 30 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/Global.scala | 5 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzer.scala | 2 | ||||
-rw-r--r-- | src/partest-extras/scala/tools/partest/IcodeComparison.scala | 9 | ||||
-rw-r--r-- | src/reflect/scala/reflect/io/Streamable.scala | 8 |
5 files changed, 37 insertions, 17 deletions
diff --git a/.gitattributes b/.gitattributes index ac98781b3d..da4421cb78 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,20 +2,24 @@ # this must be first so later entries will override it * text=auto +# check out text files with lf, not crlf, on Windows. (especially +# important for Scala source files, since """ preserves line endings) +text eol=lf + # These files are text and should be normalized (convert crlf => lf) -*.c text -*.check text -*.css text -*.flags text -*.html text -*.java text -*.js text -*.policy text -*.sbt text -*.scala text -*.sh text -*.txt text -*.xml text +*.c eol=lf +*.check eol=lf +*.css eol=lf +*.flags eol=lf +*.html eol=lf +*.java eol=lf +*.js eol=lf +*.policy eol=lf +*.sbt eol=lf +*.scala eol=lf +*.sh eol=lf +*.txt eol=lf +*.xml eol=lf # Windows-specific files get windows endings *.bat eol=crlf diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 3469726455..936bed7c8f 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -1686,7 +1686,10 @@ class Global(var currentSettings: Settings, var reporter: Reporter) try { val stream = new FileOutputStream(file) printer.setWriter(new PrintWriter(stream, true)) - printer.printClass(cls) + try + printer.printClass(cls) + finally + stream.close() informProgress(s"wrote $file") } catch { case e: IOException => diff --git a/src/compiler/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzer.scala b/src/compiler/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzer.scala index 700b2f2f6c..594fd8923c 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzer.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzer.scala @@ -475,4 +475,4 @@ class InitialProducerSourceInterpreter extends SourceInterpreter { override def newExceptionValue(tryCatchBlockNode: TryCatchBlockNode, handlerFrame: Frame[_ <: Value], exceptionType: Type): SourceValue = { new SourceValue(1, ExceptionProducer(handlerFrame)) } -}
\ No newline at end of file +} diff --git a/src/partest-extras/scala/tools/partest/IcodeComparison.scala b/src/partest-extras/scala/tools/partest/IcodeComparison.scala index 7122703918..1430db886e 100644 --- a/src/partest-extras/scala/tools/partest/IcodeComparison.scala +++ b/src/partest-extras/scala/tools/partest/IcodeComparison.scala @@ -48,8 +48,13 @@ abstract class IcodeComparison extends DirectTest { compile("-d" :: testOutput.path :: arg0 :: args.toList : _*) val icodeFiles = testOutput.files.toList filter (_ hasExtension "icode") - try icodeFiles sortBy (_.name) flatMap (f => f.lines.toList) - finally icodeFiles foreach (f => f.delete()) + // Some methods in scala.reflect.io.File leak an InputStream, leaving the underlying file open. + // Windows won't delete an open file, but we must ensure the files get deleted, since the logic + // here depends on it (collectIcode will be called multiple times, and we can't allow crosstalk + // between calls). So we are careful to use `slurp` which does call `close`, and careful to + // check that `delete` returns true indicating successful deletion. + try icodeFiles sortBy (_.name) flatMap (f => f.slurp().lines.toList) + finally icodeFiles foreach (f => require(f.delete())) } /** Collect icode at the default phase, `printIcodeAfterPhase`. */ diff --git a/src/reflect/scala/reflect/io/Streamable.scala b/src/reflect/scala/reflect/io/Streamable.scala index aa47947672..99a14d1fb0 100644 --- a/src/reflect/scala/reflect/io/Streamable.scala +++ b/src/reflect/scala/reflect/io/Streamable.scala @@ -27,6 +27,10 @@ object Streamable { * efficient method implementations. * * ''Note: This library is considered experimental and should not be used unless you know what you are doing.'' + * + * Note that this code was not written with resource management in mind. + * Several methods (such as `chars` and `lines`) create InputStreams they + * don't close */ trait Bytes { def inputStream(): InputStream @@ -82,9 +86,13 @@ object Streamable { */ def creationCodec: Codec = implicitly[Codec] + /** Caller is responsible for closing the returned BufferedSource. */ def chars(codec: Codec): BufferedSource = Source.fromInputStream(inputStream())(codec) + /** Beware! Leaks an InputStream which will not be closed until it gets finalized. */ def lines(): Iterator[String] = lines(creationCodec) + + /** Beware! Leaks an InputStream which will not be closed until it gets finalized. */ def lines(codec: Codec): Iterator[String] = chars(codec).getLines() /** Obtains an InputStreamReader wrapped around a FileInputStream. |