diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala | 100 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Implicits.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 12 | ||||
-rwxr-xr-x | tools/get-scala-revision | 5 |
4 files changed, 67 insertions, 52 deletions
diff --git a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala index ea36eb03c7..efa524503c 100644 --- a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala +++ b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala @@ -196,11 +196,11 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => /** The start of a scaladoc code block */ protected val CodeBlockStart = - new Regex("""(.*)((?:\{\{\{)|(?:\u000E<pre(?: [^>]*)?>\u000E))(.*)""") + new Regex("""(.*?)((?:\{\{\{)|(?:\u000E<pre(?: [^>]*)?>\u000E))(.*)""") /** The end of a scaladoc code block */ protected val CodeBlockEnd = - new Regex("""(.*)((?:\}\}\})|(?:\u000E</pre>\u000E))(.*)""") + new Regex("""(.*?)((?:\}\}\})|(?:\u000E</pre>\u000E))(.*)""") /** A key used for a tag map. The key is built from the name of the tag and * from the linked symbol if the tag has one. @@ -250,7 +250,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => * @param remaining The lines that must still recursively be parsed. * @param inCodeBlock Whether the next line is part of a code block (in which no tags must be read). */ def parse0 ( - docBody: String, + docBody: StringBuilder, tags: Map[TagKey, List[String]], lastTagKey: Option[TagKey], remaining: List[String], @@ -258,9 +258,11 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => ): Comment = remaining match { case CodeBlockStart(before, marker, after) :: ls if (!inCodeBlock) => - if (before.trim != "") - parse0(docBody, tags, lastTagKey, before :: (marker + after) :: ls, false) - else if (after.trim != "") + if (!before.trim.isEmpty && !after.trim.isEmpty) + parse0(docBody, tags, lastTagKey, before :: marker :: after :: ls, false) + else if (!before.trim.isEmpty) + parse0(docBody, tags, lastTagKey, before :: marker :: ls, false) + else if (!after.trim.isEmpty) parse0(docBody, tags, lastTagKey, marker :: after :: ls, true) else lastTagKey match { case Some(key) => @@ -271,24 +273,26 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => } parse0(docBody, tags + (key -> value), lastTagKey, ls, true) case None => - parse0(docBody + endOfLine + marker, tags, lastTagKey, ls, true) + parse0(docBody append endOfLine append marker, tags, lastTagKey, ls, true) } case CodeBlockEnd(before, marker, after) :: ls => - if (before.trim != "") - parse0(docBody, tags, lastTagKey, before :: (marker + after) :: ls, true) - else if (after.trim != "") + if (!before.trim.isEmpty && !after.trim.isEmpty) + parse0(docBody, tags, lastTagKey, before :: marker :: after :: ls, true) + if (!before.trim.isEmpty) + parse0(docBody, tags, lastTagKey, before :: marker :: ls, true) + else if (!after.trim.isEmpty) parse0(docBody, tags, lastTagKey, marker :: after :: ls, false) else lastTagKey match { case Some(key) => val value = ((tags get key): @unchecked) match { - case Some(b :: bs) => (b + endOfLine + "}}}") :: bs + case Some(b :: bs) => (b + endOfLine + marker) :: bs case None => oops("lastTagKey set when no tag exists for key") } parse0(docBody, tags + (key -> value), lastTagKey, ls, false) case None => - parse0(docBody + endOfLine + marker, tags, lastTagKey, ls, false) + parse0(docBody append endOfLine append marker, tags, lastTagKey, ls, false) } case SymbolTag(name, sym, body) :: ls if (!inCodeBlock) => @@ -311,8 +315,9 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => parse0(docBody, tags + (key -> value), lastTagKey, ls, inCodeBlock) case line :: ls => - val newBody = if (docBody == "") line else docBody + endOfLine + line - parse0(newBody, tags, lastTagKey, ls, inCodeBlock) + if (docBody.length > 0) docBody append endOfLine + docBody append line + parse0(docBody, tags, lastTagKey, ls, inCodeBlock) case Nil => @@ -350,7 +355,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => } val com = createComment ( - body0 = Some(parseWiki(docBody, pos)), + body0 = Some(parseWiki(docBody.toString, pos)), authors0 = allTags(SimpleTagKey("author")), see0 = allTags(SimpleTagKey("see")), result0 = oneTag(SimpleTagKey("return")), @@ -374,7 +379,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => } - parse0("", Map.empty, None, clean(comment), false) + parse0(new StringBuilder(comment.size), Map.empty, None, clean(comment), false) } @@ -385,7 +390,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => * - Removed all end-of-line whitespace. * - Only `endOfLine` is used to mark line endings. */ def parseWiki(string: String, pos: Position): Body = { - new WikiParser(string.toArray, pos).document() + new WikiParser(string, pos).document() } /** TODO @@ -393,7 +398,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => * @author Ingo Maier * @author Manohar Jonnalagedda * @author Gilles Dubochet */ - protected final class WikiParser(val buffer: Array[Char], pos: Position) extends CharReader(buffer) { wiki => + protected final class WikiParser(val buffer: String, pos: Position) extends CharReader(buffer) { wiki => var summaryParsed = false @@ -411,7 +416,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => def block(): Block = { if (checkSkipInitWhitespace("{{{")) code() - else if (checkSkipInitWhitespace("=")) + else if (checkSkipInitWhitespace('=')) title() else if (checkSkipInitWhitespace("----")) hrule() @@ -493,7 +498,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => def title(): Block = { jumpWhitespace() val inLevel = repeatJump("=") - val text = inline(check(Array.fill(inLevel)('='))) + val text = inline(check("=" * inLevel)) val outLevel = repeatJump("=", inLevel) if (inLevel != outLevel) reportError(pos, "unbalanced or unclosed heading") @@ -734,11 +739,11 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => val pc = char nextChar() // read EOL val ok = { - checkSkipInitWhitespace(Array(endOfLine)) || - checkSkipInitWhitespace(Array('=')) || - checkSkipInitWhitespace(Array('{', '{', '{')) || + checkSkipInitWhitespace(endOfLine) || + checkSkipInitWhitespace('=') || + checkSkipInitWhitespace("{{{") || checkList || - checkSkipInitWhitespace(Array('\u003D')) + checkSkipInitWhitespace('\u003D') } offset = poff char = pc @@ -751,7 +756,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => } } - protected sealed class CharReader(buffer: Array[Char]) { reader => + protected sealed class CharReader(buffer: String) { reader => var char: Char = _ var offset: Int = 0 @@ -760,36 +765,37 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => if (offset >= buffer.length) char = endOfText else { - char = buffer(offset) + char = buffer charAt offset offset += 1 } } - implicit def strintToChars(s: String): Array[Char] = s.toArray - - def store(body: => Unit): String = { - val pre = offset - body - val post = offset - buffer.toArray.slice(pre, post).toString + final def check(chars: String): Boolean = { + val poff = offset + val pc = char + val ok = jump(chars) + offset = poff + char = pc + ok } - final def check(chars: Array[Char]): Boolean = { + def checkSkipInitWhitespace(c: Char): Boolean = { val poff = offset val pc = char - val ok = jump(chars) + jumpWhitespace() + val ok = jump(c) offset = poff char = pc ok } - def checkSkipInitWhitespace(chars: Array[Char]): Boolean = { + def checkSkipInitWhitespace(chars: String): Boolean = { val poff = offset val pc = char jumpWhitespace() val (ok0, chars0) = - if (chars.head == ' ') - (offset > poff, chars.tail) + if (chars.charAt(0) == ' ') + (offset > poff, chars substring 1) else (true, chars) val ok = ok0 && jump(chars0) @@ -825,16 +831,16 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => /** jumps all the characters in chars, consuming them in the process. * @return true only if the correct characters have been jumped */ - final def jump(chars: Array[Char]): Boolean = { + final def jump(chars: String): Boolean = { var index = 0 - while (index < chars.length && char == chars(index) && char != endOfText) { + while (index < chars.length && char == chars.charAt(index) && char != endOfText) { nextChar() index += 1 } index == chars.length } - final def checkedJump(chars: Array[Char]): Boolean = { + final def checkedJump(chars: String): Boolean = { val poff = offset val pc = char val ok = jump(chars) @@ -845,7 +851,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => ok } - final def repeatJump(chars: Array[Char], max: Int): Int = { + final def repeatJump(chars: String, max: Int): Int = { var count = 0 var more = true while (more && count < max) { @@ -857,7 +863,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => count } - final def repeatJump(chars: Array[Char]): Int = { + final def repeatJump(chars: String): Int = { var count = 0 var more = true while (more) { @@ -878,10 +884,10 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => count } - final def jumpUntil(chars: Array[Char]): Int = { + final def jumpUntil(chars: String): Int = { assert(chars.length > 0) var count = 0 - val c = chars(0) + val c = chars.charAt(0) while (!check(chars) && char != endOfText) { nextChar() while (char != c && char != endOfText) { @@ -922,10 +928,10 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => count } - final def readUntil(chars: Array[Char]): Int = { + final def readUntil(chars: String): Int = { assert(chars.length > 0) var count = 0 - val c = chars(0) + val c = chars.charAt(0) while (!check(chars) && char != endOfText) { readBuilder += char nextChar() diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index eaf1b1ffbc..036e7fc750 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -625,7 +625,7 @@ trait Implicits { if (context.hasErrors) fail("typing TypeApply reported errors for the implicit tree") else { - val result = new SearchResult(checked, subst) + val result = new SearchResult(itree2, subst) incCounter(foundImplicits) printInference("[success] found %s for pt %s".format(result, ptInstantiated)) result diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 4cf134d58b..2749f99e18 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -100,6 +100,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { case MethodType(params, _) => val argResultsBuff = new ListBuffer[SearchResult]() val argBuff = new ListBuffer[Tree]() + var paramFailed = false def mkPositionalArg(argTree: Tree, paramName: Name) = argTree def mkNamedArg(argTree: Tree, paramName: Name) = atPos(argTree.pos)(new AssignOrNamedArg(Ident(paramName), (argTree))) @@ -114,14 +115,14 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { for(ar <- argResultsBuff) paramTp = paramTp.subst(ar.subst.from, ar.subst.to) - val res = inferImplicit(fun, paramTp, true, false, context) + val res = if (paramFailed) SearchFailure else inferImplicit(fun, paramTp, context.reportErrors, false, context) argResultsBuff += res if (res != SearchFailure) { argBuff += mkArg(res.tree, param.name) } else { mkArg = mkNamedArg // don't pass the default argument (if any) here, but start emitting named arguments for the following args - if (!param.hasDefault) { + if (!param.hasDefault && !paramFailed) { context.errBuffer.find(_.kind == ErrorKinds.Divergent) match { case Some(divergentImplicit) => // DivergentImplicit error has higher priority than "no implicit found" @@ -133,6 +134,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { case None => NoImplicitFoundError(fun, param) } + paramFailed = true } /* else { TODO: alternative (to expose implicit search failure more) --> @@ -767,7 +769,11 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { withCondConstrTyper(treeInfo.isSelfOrSuperConstrCall(tree)){ typer1 => if (original != EmptyTree && pt != WildcardType) - typer1.silent(tpr => tpr.typed(tpr.applyImplicitArgs(tree), mode, pt)) match { + typer1.silent(tpr => { + val withImplicitArgs = tpr.applyImplicitArgs(tree) + if (tpr.context.hasErrors) tree // silent will wrap it in SilentTypeError anyway + else tpr.typed(withImplicitArgs, mode, pt) + }) match { case SilentResultValue(result) => result case _ => diff --git a/tools/get-scala-revision b/tools/get-scala-revision index 8d48c8cb78..eac512a010 100755 --- a/tools/get-scala-revision +++ b/tools/get-scala-revision @@ -16,9 +16,12 @@ tag=$(git describe --abbrev=0) # the full string - padding correctness depends on abbrev=10. described=$(git describe --abbrev=10 --always --tags) +suffix="${described##${tag}-}" +counter=$(echo $suffix | cut -d - -f 1) +hash=$(echo $suffix | cut -d - -f 2) # 016 is rocket-surgically-calibrated to pad the distance from the # tag to the current commit into a 4-digit number - since maven # will be treating this as a string, the ide depends on # 10 being greater than 9 (thus 0010 and 00009.) -printf "%s-%016s-%s\n" "$tag" "${described##${tag}-}" $(date "+%Y-%m-%d") +printf "%s-%04d-%10s-%s\n" "$tag" "$counter" "$hash" $(date "+%Y-%m-%d") |