From fb299f80f3f85e935695d5b7cb7f2c712b150e3c Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Thu, 24 Sep 2015 14:27:58 +1000 Subject: Improve presentation compilation of annotations A trio of problems were hampering autocompletion of annotations. First, given that that annotation is written before the annotated member, it is very common to end parse incomplete code that has a floating annotation without an anotatee. The parser was discarding the annotations (ie, the modifiers) and emitting an `EmptyTree`. Second, the presetation compiler was only looking for annotations in the Modifiers of a member def, but after typechecking annotations are moved into the symbol. Third, if an annotation failed to typecheck, it was being discarded in place of `ErroneousAnnotation`. This commit: - modifies the parser to uses a dummy class- or type-def tree, instead of EmptyTree, which can carry the annotations. - updates the locator to look in the symbol annotations of the modifiers contains no annotations. - uses a separate instance of `ErroneousAnnotation` for each erroneous annotation, and stores the original tree in its `original` tree. --- src/reflect/scala/reflect/internal/AnnotationInfos.scala | 2 +- src/reflect/scala/reflect/internal/Positions.scala | 9 ++++++++- src/reflect/scala/reflect/runtime/JavaUniverseForce.scala | 1 - 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'src/reflect') diff --git a/src/reflect/scala/reflect/internal/AnnotationInfos.scala b/src/reflect/scala/reflect/internal/AnnotationInfos.scala index 6863cdfd82..b923541b56 100644 --- a/src/reflect/scala/reflect/internal/AnnotationInfos.scala +++ b/src/reflect/scala/reflect/internal/AnnotationInfos.scala @@ -404,7 +404,7 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable => object UnmappableAnnotation extends CompleteAnnotationInfo(NoType, Nil, Nil) - object ErroneousAnnotation extends CompleteAnnotationInfo(ErrorType, Nil, Nil) + class ErroneousAnnotation() extends CompleteAnnotationInfo(ErrorType, Nil, Nil) /** Extracts symbol of thrown exception from AnnotationInfo. * diff --git a/src/reflect/scala/reflect/internal/Positions.scala b/src/reflect/scala/reflect/internal/Positions.scala index 4d0e31b037..15d68bcdfe 100644 --- a/src/reflect/scala/reflect/internal/Positions.scala +++ b/src/reflect/scala/reflect/internal/Positions.scala @@ -252,7 +252,14 @@ trait Positions extends api.Positions { self: SymbolTable => super.traverse(t) } else t match { case mdef: MemberDef => - traverseTrees(mdef.mods.annotations) + val annTrees = mdef.mods.annotations match { + case Nil if mdef.symbol != null => + // After typechecking, annotations are mvoed from the modifiers + // to the annotation on the symbol of the anotatee. + mdef.symbol.annotations.map(_.original) + case anns => anns + } + traverseTrees(annTrees) case _ => } } diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala index 5477bdd6d4..7725e4a2f0 100644 --- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala +++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala @@ -106,7 +106,6 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => this.AnnotationInfo this.Annotation this.UnmappableAnnotation - this.ErroneousAnnotation this.ThrownException this.typeNames this.tpnme -- cgit v1.2.3 From 49fb8e3ceb151f28adfc4ae1670147550fdda580 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Thu, 24 Sep 2015 12:26:09 -0400 Subject: fix indentation this sneaked into 2d025fe2d0c9cd0e01e390055b0531166988f901 --- src/reflect/scala/reflect/internal/Chars.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/reflect') diff --git a/src/reflect/scala/reflect/internal/Chars.scala b/src/reflect/scala/reflect/internal/Chars.scala index 0f532a4e57..74413fdaba 100644 --- a/src/reflect/scala/reflect/internal/Chars.scala +++ b/src/reflect/scala/reflect/internal/Chars.scala @@ -66,7 +66,7 @@ trait Chars { '0' <= c && c <= '9' || 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' /** Can character start an alphanumeric Scala identifier? */ - def isIdentifierStart(c: Char): Boolean = + def isIdentifierStart(c: Char): Boolean = (c == '_') || (c == '$') || Character.isUnicodeIdentifierStart(c) /** Can character form part of an alphanumeric Scala identifier? */ -- cgit v1.2.3 From efece9fdb5c268d5a1af5b44cdac198c19eaff87 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Thu, 24 Sep 2015 21:56:16 -0400 Subject: add comments warning of InputStream leaks in scala.io.reflect --- src/reflect/scala/reflect/io/Streamable.scala | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/reflect') 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. -- cgit v1.2.3