Skip to content

Commit f7d5fe4

Browse files
authored
Merge pull request #3872 from dotty-staging/topic/sbt1
Upgrade to sbt 1
2 parents 84bf2fa + fed5232 commit f7d5fe4

File tree

330 files changed

+3215
-1253
lines changed

Some content is hidden

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

330 files changed

+3215
-1253
lines changed

.drone.yml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,39 +23,39 @@ pipeline:
2323
# We run tests in parallel. Tests run in a copy of the working directory to avoid conflict
2424
test:
2525
group: test
26-
image: lampepfl/dotty:2018-01-17
26+
image: lampepfl/dotty:2018-04-10
2727
commands:
2828
- cp -R . /tmp/1/ && cd /tmp/1/
2929
- ./project/scripts/sbt ";compile ;test"
3030
- ./project/scripts/cmdTests
3131

3232
test_bootstrapped:
3333
group: test
34-
image: lampepfl/dotty:2018-01-17
34+
image: lampepfl/dotty:2018-04-10
3535
commands:
3636
- cp -R . /tmp/2/ && cd /tmp/2/
3737
- ./project/scripts/sbt ";dotty-bootstrapped/compile ;dotty-bootstrapped/test"
3838

3939
test_optimised:
4040
group: test
41-
image: lampepfl/dotty:2018-01-17
41+
image: lampepfl/dotty:2018-04-10
4242
commands:
4343
- cp -R . /tmp/3/ && cd /tmp/3/
4444
- ./project/scripts/sbt dotty-optimised/test
4545

4646
test_sbt:
4747
group: test
48-
image: lampepfl/dotty:2018-01-17
48+
image: lampepfl/dotty:2018-04-10
4949
commands:
5050
- cp -R . /tmp/4/ && cd /tmp/4/
5151
- ./project/scripts/sbt sbt-dotty/scripted
5252
when:
53-
# sbt scripted tests are slow and don't run on PRs
53+
# sbt scripted tests are slow and only run on nightly or deployment
5454
event: [ tag, deployment ]
5555

5656
# DOCUMENTATION:
5757
documentation:
58-
image: lampepfl/dotty:2018-01-17
58+
image: lampepfl/dotty:2018-04-10
5959
commands:
6060
- ./project/scripts/genDocs
6161
secrets: [ bot_pass ]
@@ -67,7 +67,7 @@ pipeline:
6767
# PUBLISHING:
6868
# Publishing expect NIGHTLYBUILD or RELEASEBUILD to be set. See dottyVersion in Build.scala
6969
publish_nightly:
70-
image: lampepfl/dotty:2018-01-17
70+
image: lampepfl/dotty:2018-04-10
7171
environment:
7272
- NIGHTLYBUILD=yes
7373
commands:
@@ -78,7 +78,7 @@ pipeline:
7878
environment: nightly
7979

8080
publish_release:
81-
image: lampepfl/dotty:2018-01-17
81+
image: lampepfl/dotty:2018-04-10
8282
environment:
8383
- RELEASEBUILD=yes
8484
commands:
@@ -102,7 +102,7 @@ pipeline:
102102
event: tag
103103

104104
publish_sbt_release:
105-
image: lampepfl/dotty:2018-01-17
105+
image: lampepfl/dotty:2018-04-10
106106
environment:
107107
- RELEASEBUILD=yes
108108
commands:

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ project/local-plugins.sbt
1818
.history
1919
.ensime
2020
.ensime_cache/
21+
.sbt-scripted/
2122

2223
# npm
2324
node_modules

build.sbt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ val `dotty-library-optimised` = Build.`dotty-library-optimised`
1414
val `dotty-sbt-bridge` = Build.`dotty-sbt-bridge`
1515
val `dotty-sbt-bridge-bootstrapped` = Build.`dotty-sbt-bridge-bootstrapped`
1616
val `dotty-language-server` = Build.`dotty-language-server`
17-
val sjsSandbox = Build.sjsSandbox
1817
val `dotty-bench` = Build.`dotty-bench`
1918
val `dotty-bench-bootstrapped` = Build.`dotty-bench-bootstrapped`
2019
val `dotty-bench-optimised` = Build.`dotty-bench-optimised`

compiler/src/dotty/tools/backend/jvm/GenBCode.scala

Lines changed: 81 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@ import scala.tools.nsc.backend.jvm._
1313
import dotty.tools.dotc
1414
import dotty.tools.dotc.backend.jvm.DottyPrimitives
1515
import dotty.tools.dotc.transform.Erasure
16+
import dotty.tools.dotc.transform.SymUtils._
1617
import dotty.tools.dotc.interfaces
1718
import java.util.Optional
1819

1920
import scala.reflect.ClassTag
2021
import dotty.tools.dotc.core._
22+
import dotty.tools.dotc.sbt.ExtractDependencies
2123
import Periods._
2224
import SymDenotations._
2325
import Contexts._
@@ -113,14 +115,16 @@ class GenBCodePipeline(val entryPoints: List[Symbol], val int: DottyBackendInter
113115

114116
/* ---------------- q2 ---------------- */
115117

116-
case class Item2(arrivalPos: Int,
117-
mirror: asm.tree.ClassNode,
118-
plain: asm.tree.ClassNode,
119-
outFolder: scala.tools.nsc.io.AbstractFile) {
118+
case class SubItem2(classNode: asm.tree.ClassNode,
119+
file: scala.tools.nsc.io.AbstractFile)
120+
121+
case class Item2(arrivalPos: Int,
122+
mirror: SubItem2,
123+
plain: SubItem2) {
120124
def isPoison = { arrivalPos == Int.MaxValue }
121125
}
122126

123-
private val poison2 = Item2(Int.MaxValue, null, null, null)
127+
private val poison2 = Item2(Int.MaxValue, null, null)
124128
private val q2 = new _root_.java.util.LinkedList[Item2]
125129

126130
/* ---------------- q3 ---------------- */
@@ -134,13 +138,13 @@ class GenBCodePipeline(val entryPoints: List[Symbol], val int: DottyBackendInter
134138
*/
135139
case class SubItem3(
136140
jclassName: String,
137-
jclassBytes: Array[Byte]
141+
jclassBytes: Array[Byte],
142+
jclassFile: scala.tools.nsc.io.AbstractFile
138143
)
139144

140145
case class Item3(arrivalPos: Int,
141146
mirror: SubItem3,
142-
plain: SubItem3,
143-
outFolder: scala.tools.nsc.io.AbstractFile) {
147+
plain: SubItem3) {
144148

145149
def isPoison = { arrivalPos == Int.MaxValue }
146150
}
@@ -151,15 +155,31 @@ class GenBCodePipeline(val entryPoints: List[Symbol], val int: DottyBackendInter
151155
else 1
152156
}
153157
}
154-
private val poison3 = Item3(Int.MaxValue, null, null, null)
158+
private val poison3 = Item3(Int.MaxValue, null, null)
155159
private val q3 = new java.util.PriorityQueue[Item3](1000, i3comparator)
156160

157161
/*
158162
* Pipeline that takes ClassDefs from queue-1, lowers them into an intermediate form, placing them on queue-2
159163
*/
160164
class Worker1(needsOutFolder: Boolean) {
161165

162-
val caseInsensitively = scala.collection.mutable.HashMap.empty[String, Symbol]
166+
private val lowerCaseNames = mutable.HashMap.empty[String, Symbol]
167+
private def checkForCaseConflict(javaClassName: String, classSymbol: Symbol) = {
168+
val lowerCaseName = javaClassName.toLowerCase
169+
lowerCaseNames.get(lowerCaseName) match {
170+
case None =>
171+
lowerCaseNames.put(lowerCaseName, classSymbol)
172+
case Some(dupClassSym) =>
173+
// Order is not deterministic so we enforce lexicographic order between the duplicates for error-reporting
174+
val (cl1, cl2) =
175+
if (classSymbol.effectiveName.toString < dupClassSym.effectiveName.toString) (classSymbol, dupClassSym)
176+
else (dupClassSym, classSymbol)
177+
ctx.atPhase(ctx.typerPhase) { implicit ctx =>
178+
ctx.warning(s"${cl1.show} differs only in case from ${cl2.showLocated}. " +
179+
"Such classes will overwrite one another on case-insensitive filesystems.", cl1.pos)
180+
}
181+
}
182+
}
163183

164184
def run(): Unit = {
165185
while (true) {
@@ -189,30 +209,6 @@ class GenBCodePipeline(val entryPoints: List[Symbol], val int: DottyBackendInter
189209
val Item1(arrivalPos, cd, cunit) = item
190210
val claszSymbol = cd.symbol
191211

192-
// GenASM checks this before classfiles are emitted, https://github.com/scala/scala/commit/e4d1d930693ac75d8eb64c2c3c69f2fc22bec739
193-
def checkName(claszSymbol: Symbol): Unit = {
194-
val lowercaseJavaClassName = claszSymbol.effectiveName.toString.toLowerCase
195-
caseInsensitively.get(lowercaseJavaClassName) match {
196-
case None =>
197-
caseInsensitively.put(lowercaseJavaClassName, claszSymbol)
198-
case Some(dupClassSym) =>
199-
if (claszSymbol.effectiveName.toString != dupClassSym.effectiveName.toString) {
200-
// Order is not deterministic so we enforce lexicographic order between the duplicates for error-reporting
201-
val (cl1, cl2) =
202-
if (claszSymbol.effectiveName.toString < dupClassSym.effectiveName.toString) (claszSymbol, dupClassSym)
203-
else (dupClassSym, claszSymbol)
204-
ctx.warning(s"Class ${cl1.effectiveName} differs only in case from ${cl2.effectiveName}. " +
205-
"Such classes will overwrite one another on case-insensitive filesystems.", cl1.pos)
206-
}
207-
}
208-
}
209-
checkName(claszSymbol)
210-
if (int.symHelper(claszSymbol).isModuleClass) {
211-
val companionModule = claszSymbol.companionModule
212-
if (int.symHelper(companionModule.owner).isPackageClass)
213-
checkName(companionModule)
214-
}
215-
216212
// -------------- mirror class, if needed --------------
217213
val mirrorC =
218214
if (int.symHelper(claszSymbol).isTopLevelModuleClass) {
@@ -253,12 +249,50 @@ class GenBCodePipeline(val entryPoints: List[Symbol], val int: DottyBackendInter
253249
}
254250

255251

252+
// ----------- create files
253+
254+
val classNodes = List(mirrorC, plainC)
255+
val classFiles = classNodes.map(cls =>
256+
if (outF != null && cls != null) {
257+
try {
258+
checkForCaseConflict(cls.name, claszSymbol)
259+
getFileForClassfile(outF, cls.name, ".class")
260+
} catch {
261+
case e: FileConflictException =>
262+
ctx.error(s"error writing ${cls.name}: ${e.getMessage}")
263+
null
264+
}
265+
} else null
266+
)
267+
268+
// ----------- compiler and sbt's callbacks
269+
270+
val (fullClassName, isLocal) = ctx.atPhase(ctx.sbtExtractDependenciesPhase) { implicit ctx =>
271+
(ExtractDependencies.classNameAsString(claszSymbol), claszSymbol.isLocal)
272+
}
273+
274+
for ((cls, clsFile) <- classNodes.zip(classFiles)) {
275+
if (cls != null) {
276+
val className = cls.name.replace('/', '.')
277+
if (ctx.compilerCallback != null)
278+
ctx.compilerCallback.onClassGenerated(sourceFile, convertAbstractFile(clsFile), className)
279+
if (ctx.sbtCallback != null) {
280+
if (isLocal)
281+
ctx.sbtCallback.generatedLocalClass(sourceFile.jfile.orElse(null), clsFile.file)
282+
else {
283+
ctx.sbtCallback.generatedNonLocalClass(sourceFile.jfile.orElse(null), clsFile.file,
284+
className, fullClassName)
285+
}
286+
}
287+
}
288+
}
289+
256290
// ----------- hand over to pipeline-2
257291

258292
val item2 =
259293
Item2(arrivalPos,
260-
mirrorC, plainC,
261-
outF)
294+
SubItem2(mirrorC, classFiles(0)),
295+
SubItem2(plainC, classFiles(1)))
262296

263297
q2 add item2 // at the very end of this method so that no Worker2 thread starts mutating before we're done.
264298

@@ -288,12 +322,12 @@ class GenBCodePipeline(val entryPoints: List[Symbol], val int: DottyBackendInter
288322
}
289323
else {
290324
try {
291-
localOptimizations(item.plain)
325+
localOptimizations(item.plain.classNode)
292326
addToQ3(item)
293327
} catch {
294328
case ex: Throwable =>
295329
ex.printStackTrace()
296-
ctx.error(s"Error while emitting ${item.plain.name}\n${ex.getMessage}")
330+
ctx.error(s"Error while emitting ${item.plain.classNode.name}\n${ex.getMessage}")
297331
}
298332
}
299333
}
@@ -307,18 +341,17 @@ class GenBCodePipeline(val entryPoints: List[Symbol], val int: DottyBackendInter
307341
cw.toByteArray
308342
}
309343

310-
val Item2(arrivalPos, mirror, plain, outFolder) = item
344+
val Item2(arrivalPos, SubItem2(mirror, mirrorFile), SubItem2(plain, plainFile)) = item
311345

312-
val mirrorC = if (mirror == null) null else SubItem3(mirror.name, getByteArray(mirror))
313-
val plainC = SubItem3(plain.name, getByteArray(plain))
346+
val mirrorC = if (mirror == null) null else SubItem3(mirror.name, getByteArray(mirror), mirrorFile)
347+
val plainC = SubItem3(plain.name, getByteArray(plain), plainFile)
314348

315349
if (AsmUtils.traceSerializedClassEnabled && plain.name.contains(AsmUtils.traceSerializedClassPattern)) {
316350
if (mirrorC != null) AsmUtils.traceClass(mirrorC.jclassBytes)
317351
AsmUtils.traceClass(plainC.jclassBytes)
318352
}
319353

320-
q3 add Item3(arrivalPos, mirrorC, plainC, outFolder)
321-
354+
q3 add Item3(arrivalPos, mirrorC, plainC)
322355
}
323356

324357
} // end of class BCodePhase.Worker2
@@ -416,25 +449,10 @@ class GenBCodePipeline(val entryPoints: List[Symbol], val int: DottyBackendInter
416449
/* Pipeline that writes classfile representations to disk. */
417450
private def drainQ3() = {
418451

419-
def sendToDisk(cfr: SubItem3, outFolder: scala.tools.nsc.io.AbstractFile): Unit = {
452+
def sendToDisk(cfr: SubItem3): Unit = {
420453
if (cfr != null){
421-
val SubItem3(jclassName, jclassBytes) = cfr
422-
try {
423-
val outFile =
424-
if (outFolder == null) null
425-
else getFileForClassfile(outFolder, jclassName, ".class")
426-
bytecodeWriter.writeClass(jclassName, jclassName, jclassBytes, outFile)
427-
428-
val className = jclassName.replace('/', '.')
429-
if (ctx.compilerCallback != null)
430-
ctx.compilerCallback.onClassGenerated(sourceFile, convertAbstractFile(outFile), className)
431-
if (ctx.sbtCallback != null)
432-
ctx.sbtCallback.generatedClass(sourceFile.jfile.orElse(null), outFile.file, className)
433-
}
434-
catch {
435-
case e: FileConflictException =>
436-
ctx.error(s"error writing $jclassName: ${e.getMessage}")
437-
}
454+
val SubItem3(jclassName, jclassBytes, jclassFile) = cfr
455+
bytecodeWriter.writeClass(jclassName, jclassName, jclassBytes, jclassFile)
438456
}
439457
}
440458

@@ -447,9 +465,8 @@ class GenBCodePipeline(val entryPoints: List[Symbol], val int: DottyBackendInter
447465
moreComing = !incoming.isPoison
448466
if (moreComing) {
449467
val item = incoming
450-
val outFolder = item.outFolder
451-
sendToDisk(item.mirror, outFolder)
452-
sendToDisk(item.plain, outFolder)
468+
sendToDisk(item.mirror)
469+
sendToDisk(item.plain)
453470
expected += 1
454471
}
455472
}

compiler/src/dotty/tools/dotc/config/JavaPlatform.scala

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,12 @@ class JavaPlatform extends Platform {
2121
}
2222

2323
// The given symbol is a method with the right name and signature to be a runnable java program.
24-
def isJavaMainMethod(sym: SymDenotation)(implicit ctx: Context) =
24+
def isMainMethod(sym: SymDenotation)(implicit ctx: Context) =
2525
(sym.name == nme.main) && (sym.info match {
2626
case MethodTpe(_, defn.ArrayOf(el) :: Nil, restpe) => el =:= defn.StringType && (restpe isRef defn.UnitClass)
2727
case _ => false
2828
})
2929

30-
// The given class has a main method.
31-
def hasJavaMainMethod(sym: Symbol)(implicit ctx: Context): Boolean =
32-
(sym.info member nme.main).hasAltWith {
33-
case x: SymDenotation => isJavaMainMethod(x)
34-
case _ => false
35-
}
36-
3730
/** Update classpath with a substituted subentry */
3831
def updateClassPath(subst: Map[ClassPath, ClassPath]): Unit = currentClassPath.get match {
3932
case AggregateClassPath(entries) =>

compiler/src/dotty/tools/dotc/config/Platform.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ package config
1010
import io.{ClassPath, AbstractFile}
1111
import core.Contexts._, core.Symbols._
1212
import core.SymbolLoader
13+
import core.SymDenotations.SymDenotation
14+
import core.StdNames.nme
1315

1416
/** The platform dependent pieces of Global.
1517
*/
@@ -35,5 +37,15 @@ abstract class Platform {
3537

3638
/** Create a new class loader to load class file `bin` */
3739
def newClassLoader(bin: AbstractFile)(implicit ctx: Context): SymbolLoader
40+
41+
/** The given symbol is a method with the right name and signature to be a runnable program. */
42+
def isMainMethod(sym: SymDenotation)(implicit ctx: Context): Boolean
43+
44+
/** The given class has a main method. */
45+
final def hasMainMethod(sym: Symbol)(implicit ctx: Context): Boolean =
46+
sym.info.member(nme.main).hasAltWith {
47+
case x: SymDenotation => isMainMethod(x)
48+
case _ => false
49+
}
3850
}
3951

compiler/src/dotty/tools/dotc/core/Names.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,8 @@ object Names {
422422
"dotty$tools$dotc$core$NameOps$NameDecorator$$functionArityFor$extension",
423423
"dotty$tools$dotc$typer$Checking$CheckNonCyclicMap$$apply",
424424
"$plus$plus",
425-
"readConstant")
425+
"readConstant",
426+
"extractedName")
426427
.contains(elem.getMethodName))
427428
}
428429

0 commit comments

Comments
 (0)