Skip to content

Commit 2586e6c

Browse files
committed
Merge commit '555f8f0' into merge/2.11-to-2.12-apr-21
2 parents 15b1637 + 555f8f0 commit 2586e6c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+2276
-287
lines changed

scripts/jobs/integrate/bootstrap

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,22 @@ rm -rf $baseDir/resolutionScratch_
108108
mkdir -p $baseDir/resolutionScratch_
109109

110110
# repo used to publish "locker" scala to (to start the bootstrap)
111-
privateCred="private-repo"
112-
privateRepo="http://private-repo.typesafe.com/typesafe/scala-release-temp/"
111+
releaseTempRepoCred="private-repo"
112+
releaseTempRepoUrl=${releaseTempRepoUrl-"http://private-repo.typesafe.com/typesafe/scala-release-temp/"}
113+
114+
# Used below in sbtArgs since we use a dedicated repository to share artifcacts between jobs,
115+
# so we need to configure SBT to use these rather than its default, Maven Central.
116+
# See http://www.scala-sbt.org/0.13/docs/Proxy-Repositories.html
117+
sbtRepositoryConfig="$scriptsDir/repositories-scala-release"
118+
cat > "$sbtRepositoryConfig" << EOF
119+
[repositories]
120+
plugins: http://dl.bintray.com/sbt/sbt-plugin-releases/, [organisation]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]
121+
private-repo: $releaseTempRepoUrl
122+
typesafe-ivy-releases: http://repo.typesafe.com/typesafe/ivy-releases/, [organization]/[module]/[revision]/[type]s/[artifact](-[classifier]).[ext], bootOnly
123+
sbt-plugin-releases: http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-releases, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]
124+
maven-central
125+
local
126+
EOF
113127

114128
##### git
115129
gfxd() {
@@ -158,7 +172,7 @@ function st_stagingRepoClose() {
158172
# the old version (on jenkins, and I don't want to upgrade for risk of breaking other builds) honors -sbt-dir
159173
# the new version of sbt-extras ignores sbt-dir, so we pass it in as -Dsbt.global.base
160174
# need to set sbt-dir to one that has the gpg.sbt plugin config
161-
sbtArgs="-no-colors -ivy $baseDir/ivy2 -Dsbt.override.build.repos=true -Dsbt.repository.config=$scriptsDir/repositories-scala-release -Dsbt.global.base=$HOME/.sbt/0.13 -sbt-dir $HOME/.sbt/0.13"
175+
sbtArgs="-no-colors -ivy $baseDir/ivy2 -Dsbt.override.build.repos=true -Dsbt.repository.config=$sbtRepositoryConfig -Dsbt.global.base=$HOME/.sbt/0.13 -sbt-dir $HOME/.sbt/0.13"
162176

163177
sbtBuild() {
164178
echo "### sbtBuild: "$sbtCmd $sbtArgs "${scalaVersionTasks[@]}" "${publishTasks[@]}" "$@"
@@ -457,8 +471,8 @@ bootstrap() {
457471
# in sabbus lingo, the resulting Scala build will be used as starr to build the released Scala compiler
458472
ant -Dmaven.version.number=$SCALA_VER\
459473
-Dremote.snapshot.repository=NOPE\
460-
-Dremote.release.repository=$privateRepo\
461-
-Drepository.credentials.id=$privateCred\
474+
-Dremote.release.repository=$releaseTempRepoUrl\
475+
-Drepository.credentials.id=$releaseTempRepoCred\
462476
-Dscalac.args.optimise=-optimise\
463477
-Ddocs.skip=1\
464478
-Dlocker.skip=1\
@@ -471,7 +485,7 @@ bootstrap() {
471485
# publish to our internal repo (so we can resolve the modules in the scala build below)
472486
# we only need to build the modules necessary to build Scala itself
473487
# since the version of locker and quick are the same
474-
publishTasks=('set credentials += Credentials(Path.userHome / ".credentials-private-repo")' "set every publishTo := Some(\"private-repo\" at \"$privateRepo\")")
488+
publishTasks=('set credentials += Credentials(Path.userHome / ".credentials-private-repo")' "set every publishTo := Some(\"private-repo\" at \"$releaseTempRepoUrl\")")
475489
buildTasks=($publishPrivateTask)
476490
buildModules
477491

@@ -496,14 +510,14 @@ bootstrap() {
496510
# which is fully cross-versioned (for $SCALA_VER, the version we're releasing)
497511
ant -Dstarr.version=$SCALA_VER\
498512
-Dscala.full.version=$SCALA_VER\
499-
-Dextra.repo.url=$privateRepo\
513+
-Dextra.repo.url=$releaseTempRepoUrl\
500514
-Dmaven.version.suffix=$SCALA_VER_SUFFIX\
501515
${updatedModuleVersions[@]} \
502516
-Dupdate.versions=1\
503517
-Dscaladoc.git.commit=$SCALADOC_SOURCE_LINKS_VER\
504518
-Dremote.snapshot.repository=NOPE\
505-
-Dremote.release.repository=$privateRepo\
506-
-Drepository.credentials.id=$privateCred\
519+
-Dremote.release.repository=$releaseTempRepoUrl\
520+
-Drepository.credentials.id=$releaseTempRepoCred\
507521
-Dscalac.args.optimise=-optimise\
508522
$antBuildTask $publishPrivateTask
509523

scripts/repositories-scala-release

Lines changed: 0 additions & 7 deletions
This file was deleted.

src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala

Lines changed: 78 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package scala.tools.nsc
77
package ast.parser
88

9+
import scala.annotation.tailrec
910
import scala.collection.mutable
1011
import mutable.{ Buffer, ArrayBuffer, ListBuffer }
1112
import scala.util.control.ControlThrowable
@@ -172,20 +173,19 @@ trait MarkupParsers {
172173
}
173174

174175
def appendText(pos: Position, ts: Buffer[Tree], txt: String): Unit = {
175-
def append(t: String) = ts append handle.text(pos, t)
176-
177-
if (preserveWS) append(txt)
178-
else {
176+
def append(text: String): Unit = {
177+
val tree = handle.text(pos, text)
178+
ts append tree
179+
}
180+
val clean = if (preserveWS) txt else {
179181
val sb = new StringBuilder()
180-
181182
txt foreach { c =>
182183
if (!isSpace(c)) sb append c
183184
else if (sb.isEmpty || !isSpace(sb.last)) sb append ' '
184185
}
185-
186-
val trimmed = sb.toString.trim
187-
if (!trimmed.isEmpty) append(trimmed)
186+
sb.toString.trim
188187
}
188+
if (!clean.isEmpty) append(clean)
189189
}
190190

191191
/** adds entity/character to ts as side-effect
@@ -216,44 +216,75 @@ trait MarkupParsers {
216216
if (xCheckEmbeddedBlock) ts append xEmbeddedExpr
217217
else appendText(p, ts, xText)
218218

219-
/** Returns true if it encounters an end tag (without consuming it),
220-
* appends trees to ts as side-effect.
219+
/** At an open angle-bracket, detects an end tag
220+
* or consumes CDATA, comment, PI or element.
221+
* Trees are appended to `ts` as a side-effect.
222+
* @return true if an end tag (without consuming it)
221223
*/
222-
private def content_LT(ts: ArrayBuffer[Tree]): Boolean = {
223-
if (ch == '/')
224-
return true // end tag
225-
226-
val toAppend = ch match {
227-
case '!' => nextch() ; if (ch =='[') xCharData else xComment // CDATA or Comment
228-
case '?' => nextch() ; xProcInstr // PI
229-
case _ => element // child node
224+
private def content_LT(ts: ArrayBuffer[Tree]): Boolean =
225+
(ch == '/') || {
226+
val toAppend = ch match {
227+
case '!' => nextch() ; if (ch =='[') xCharData else xComment // CDATA or Comment
228+
case '?' => nextch() ; xProcInstr // PI
229+
case _ => element // child node
230+
}
231+
ts append toAppend
232+
false
230233
}
231234

232-
ts append toAppend
233-
false
234-
}
235-
236235
def content: Buffer[Tree] = {
237236
val ts = new ArrayBuffer[Tree]
238-
while (true) {
239-
if (xEmbeddedBlock)
237+
val coalescing = settings.XxmlSettings.isCoalescing
238+
@tailrec def loopContent(): Unit =
239+
if (xEmbeddedBlock) {
240240
ts append xEmbeddedExpr
241-
else {
241+
loopContent()
242+
} else {
242243
tmppos = o2p(curOffset)
243244
ch match {
244-
// end tag, cdata, comment, pi or child node
245-
case '<' => nextch() ; if (content_LT(ts)) return ts
246-
// either the character '{' or an embedded scala block }
247-
case '{' => content_BRACE(tmppos, ts) // }
248-
// EntityRef or CharRef
249-
case '&' => content_AMP(ts)
250-
case SU => return ts
251-
// text content - here xEmbeddedBlock might be true
252-
case _ => appendText(tmppos, ts, xText)
245+
case '<' => // end tag, cdata, comment, pi or child node
246+
nextch()
247+
if (!content_LT(ts)) loopContent()
248+
case '{' => // } literal brace or embedded Scala block
249+
content_BRACE(tmppos, ts)
250+
loopContent()
251+
case '&' => // EntityRef or CharRef
252+
content_AMP(ts)
253+
loopContent()
254+
case SU => ()
255+
case _ => // text content - here xEmbeddedBlock might be true
256+
appendText(tmppos, ts, xText)
257+
loopContent()
253258
}
254259
}
260+
// merge text sections and strip attachments
261+
def coalesce(): ArrayBuffer[Tree] = {
262+
def copy() = {
263+
val buf = new ArrayBuffer[Tree]
264+
var acc = new StringBuilder
265+
var pos: Position = NoPosition
266+
def emit() = if (acc.nonEmpty) {
267+
appendText(pos, buf, acc.toString)
268+
acc.clear()
269+
}
270+
for (t <- ts)
271+
t.attachments.get[handle.TextAttache] match {
272+
case Some(ta) =>
273+
if (acc.isEmpty) pos = ta.pos
274+
acc append ta.text
275+
case _ =>
276+
emit()
277+
buf += t
278+
}
279+
emit()
280+
buf
281+
}
282+
val res = if (ts.count(_.hasAttachment[handle.TextAttache]) > 1) copy() else ts
283+
for (t <- res) t.removeAttachment[handle.TextAttache]
284+
res
255285
}
256-
unreachable
286+
loopContent()
287+
if (coalescing) coalesce() else ts
257288
}
258289

259290
/** '<' element ::= xmlTag1 '>' { xmlExpr | '{' simpleExpr '}' } ETag
@@ -289,20 +320,16 @@ trait MarkupParsers {
289320
private def xText: String = {
290321
assert(!xEmbeddedBlock, "internal error: encountered embedded block")
291322
val buf = new StringBuilder
292-
def done = buf.toString
293-
294-
while (ch != SU) {
295-
if (ch == '}') {
296-
if (charComingAfter(nextch()) == '}') nextch()
297-
else errorBraces()
298-
}
299-
300-
buf append ch
301-
nextch()
302-
if (xCheckEmbeddedBlock || ch == '<' || ch == '&')
303-
return done
304-
}
305-
done
323+
if (ch != SU)
324+
do {
325+
if (ch == '}') {
326+
if (charComingAfter(nextch()) == '}') nextch()
327+
else errorBraces()
328+
}
329+
buf append ch
330+
nextch()
331+
} while (!(ch == SU || xCheckEmbeddedBlock || ch == '<' || ch == '&'))
332+
buf.toString
306333
}
307334

308335
/** Some try/catch/finally logic used by xLiteral and xLiteralPattern. */
@@ -344,12 +371,12 @@ trait MarkupParsers {
344371
tmppos = o2p(curOffset) // Iuli: added this line, as it seems content_LT uses tmppos when creating trees
345372
content_LT(ts)
346373

347-
// parse more XML ?
374+
// parse more XML?
348375
if (charComingAfter(xSpaceOpt()) == '<') {
349376
do {
350377
xSpaceOpt()
351378
nextch()
352-
ts append element
379+
content_LT(ts)
353380
} while (charComingAfter(xSpaceOpt()) == '<')
354381
handle.makeXMLseq(r2p(start, start, curOffset), ts)
355382
}

src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) {
3636
val _MetaData: NameType = "MetaData"
3737
val _NamespaceBinding: NameType = "NamespaceBinding"
3838
val _NodeBuffer: NameType = "NodeBuffer"
39+
val _PCData: NameType = "PCData"
3940
val _PrefixedAttribute: NameType = "PrefixedAttribute"
4041
val _ProcInstr: NameType = "ProcInstr"
4142
val _Text: NameType = "Text"
@@ -46,6 +47,7 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) {
4647
private object xmlterms extends TermNames {
4748
val _Null: NameType = "Null"
4849
val __Elem: NameType = "Elem"
50+
val _PCData: NameType = "PCData"
4951
val __Text: NameType = "Text"
5052
val _buf: NameType = "$buf"
5153
val _md: NameType = "$md"
@@ -55,10 +57,15 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) {
5557
val _xml: NameType = "xml"
5658
}
5759

58-
import xmltypes.{_Comment, _Elem, _EntityRef, _Group, _MetaData, _NamespaceBinding, _NodeBuffer,
59-
_PrefixedAttribute, _ProcInstr, _Text, _Unparsed, _UnprefixedAttribute}
60+
import xmltypes.{
61+
_Comment, _Elem, _EntityRef, _Group, _MetaData, _NamespaceBinding, _NodeBuffer,
62+
_PCData, _PrefixedAttribute, _ProcInstr, _Text, _Unparsed, _UnprefixedAttribute
63+
}
64+
65+
import xmlterms.{ _Null, __Elem, __Text, _buf, _md, _plus, _scope, _tmpscope, _xml }
6066

61-
import xmlterms.{_Null, __Elem, __Text, _buf, _md, _plus, _scope, _tmpscope, _xml}
67+
/** Attachment for trees deriving from text nodes (Text, CData, entities). Used for coalescing. */
68+
case class TextAttache(pos: Position, text: String)
6269

6370
// convenience methods
6471
private def LL[A](x: A*): List[List[A]] = List(List(x:_*))
@@ -108,16 +115,21 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) {
108115
final def entityRef(pos: Position, n: String) =
109116
atPos(pos)( New(_scala_xml_EntityRef, LL(const(n))) )
110117

118+
private def coalescing = settings.XxmlSettings.isCoalescing
119+
111120
// create scala.xml.Text here <: scala.xml.Node
112121
final def text(pos: Position, txt: String): Tree = atPos(pos) {
113-
if (isPattern) makeTextPat(const(txt))
114-
else makeText1(const(txt))
122+
val t = if (isPattern) makeTextPat(const(txt)) else makeText1(const(txt))
123+
if (coalescing) t updateAttachment TextAttache(pos, txt) else t
115124
}
116125

117126
def makeTextPat(txt: Tree) = Apply(_scala_xml__Text, List(txt))
118127
def makeText1(txt: Tree) = New(_scala_xml_Text, LL(txt))
119128
def comment(pos: Position, text: String) = atPos(pos)( Comment(const(text)) )
120-
def charData(pos: Position, txt: String) = atPos(pos)( makeText1(const(txt)) )
129+
def charData(pos: Position, txt: String) = if (coalescing) text(pos, txt) else atPos(pos) {
130+
if (isPattern) Apply(_scala_xml(xmlterms._PCData), List(const(txt)))
131+
else New(_scala_xml(_PCData), LL(const(txt)))
132+
}
121133

122134
def procInstr(pos: Position, target: String, txt: String) =
123135
atPos(pos)( ProcInstr(const(target), const(txt)) )

src/compiler/scala/tools/nsc/settings/ScalaSettings.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,18 @@ trait ScalaSettings extends AbsScalaSettings
139139
val XnoPatmatAnalysis = BooleanSetting ("-Xno-patmat-analysis", "Don't perform exhaustivity/unreachability analysis. Also, ignore @switch annotation.")
140140
val XfullLubs = BooleanSetting ("-Xfull-lubs", "Retains pre 2.10 behavior of less aggressive truncation of least upper bounds.")
141141

142+
// XML parsing options
143+
object XxmlSettings extends MultiChoiceEnumeration {
144+
val coalescing = Choice("coalescing", "Convert PCData to Text and coalesce sibling nodes")
145+
def isCoalescing = (Xxml contains coalescing) || (!isScala212 && !Xxml.isSetByUser)
146+
}
147+
val Xxml = MultiChoiceSetting(
148+
name = "-Xxml",
149+
helpArg = "property",
150+
descr = "Configure XML parsing",
151+
domain = XxmlSettings
152+
)
153+
142154
/** Compatibility stubs for options whose value name did
143155
* not previously match the option name.
144156
*/

src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import scala.collection.mutable.{ ListBuffer, ArrayBuffer }
1515
import scala.annotation.switch
1616
import scala.reflect.internal.{ JavaAccFlags }
1717
import scala.reflect.internal.pickling.{PickleBuffer, ByteCodecs}
18+
import scala.reflect.io.NoAbstractFile
1819
import scala.tools.nsc.io.AbstractFile
1920
import scala.tools.nsc.util.ClassFileLookup
2021

@@ -1022,11 +1023,18 @@ abstract class ClassfileParser {
10221023
val sflags = jflags.toScalaFlags
10231024
val owner = ownerForFlags(jflags)
10241025
val scope = getScope(jflags)
1025-
val innerClass = owner.newClass(name.toTypeName, NoPosition, sflags) setInfo completer
1026-
val innerModule = owner.newModule(name.toTermName, NoPosition, sflags) setInfo completer
1026+
def newStub(name: Name) =
1027+
owner.newStubSymbol(name, s"Class file for ${entry.externalName} not found").setFlag(JAVA)
10271028

1028-
innerModule.moduleClass setInfo loaders.moduleClassLoader
1029-
List(innerClass, innerModule.moduleClass) foreach (_.associatedFile = file)
1029+
val (innerClass, innerModule) = if (file == NoAbstractFile) {
1030+
(newStub(name.toTypeName), newStub(name.toTermName))
1031+
} else {
1032+
val cls = owner.newClass(name.toTypeName, NoPosition, sflags) setInfo completer
1033+
val mod = owner.newModule(name.toTermName, NoPosition, sflags) setInfo completer
1034+
mod.moduleClass setInfo loaders.moduleClassLoader
1035+
List(cls, mod.moduleClass) foreach (_.associatedFile = file)
1036+
(cls, mod)
1037+
}
10301038

10311039
scope enter innerClass
10321040
scope enter innerModule
@@ -1046,10 +1054,8 @@ abstract class ClassfileParser {
10461054
for (entry <- innerClasses.entries) {
10471055
// create a new class member for immediate inner classes
10481056
if (entry.outerName == currentClass) {
1049-
val file = classFileLookup.findClassFile(entry.externalName.toString) getOrElse {
1050-
throw new AssertionError(s"Class file for ${entry.externalName} not found")
1051-
}
1052-
enterClassAndModule(entry, file)
1057+
val file = classFileLookup.findClassFile(entry.externalName.toString)
1058+
enterClassAndModule(entry, file.getOrElse(NoAbstractFile))
10531059
}
10541060
}
10551061
}

src/compiler/scala/tools/nsc/transform/AddInterfaces.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure =>
207207
}
208208

209209
def transformMixinInfo(tp: Type): Type = tp match {
210-
case ClassInfoType(parents, decls, clazz) =>
210+
case ClassInfoType(parents, decls, clazz) if clazz.isPackageClass || !clazz.isJavaDefined =>
211211
if (clazz.needsImplClass)
212212
implClass(clazz setFlag lateINTERFACE) // generate an impl class
213213

0 commit comments

Comments
 (0)