From 1db7c12f400f9e39599e737c5b0c9186801fd0d7 Mon Sep 17 00:00:00 2001 From: Allan Renucci Date: Mon, 16 Apr 2018 16:48:08 +0200 Subject: [PATCH 1/5] Refine dependency extraction: Ignore packages We can ignore packages when collecting dependencies for incremental compilation. We make sure not to ignore dependencies on package object. --- .drone.yml | 6 +++--- .../tools/dotc/sbt/ExtractDependencies.scala | 2 +- .../test/xsbt/DependencySpecification.scala | 19 +++++++++++++++++++ .../xsbt/ExtractUsedNamesSpecification.scala | 14 ++++++++++++++ 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/.drone.yml b/.drone.yml index 07ee3a45f974..53f9516b7a6a 100644 --- a/.drone.yml +++ b/.drone.yml @@ -49,9 +49,9 @@ pipeline: commands: - cp -R . /tmp/4/ && cd /tmp/4/ - ./project/scripts/sbt sbt-dotty/scripted - when: - # sbt scripted tests are slow and only run on nightly or deployment - event: [ tag, deployment ] + # when: + # # sbt scripted tests are slow and only run on nightly or deployment + # event: [ tag, deployment ] # DOCUMENTATION: documentation: diff --git a/compiler/src/dotty/tools/dotc/sbt/ExtractDependencies.scala b/compiler/src/dotty/tools/dotc/sbt/ExtractDependencies.scala index 62955dcb72a7..d17ab5033094 100644 --- a/compiler/src/dotty/tools/dotc/sbt/ExtractDependencies.scala +++ b/compiler/src/dotty/tools/dotc/sbt/ExtractDependencies.scala @@ -315,7 +315,7 @@ private class ExtractDependenciesCollector extends tpd.TreeTraverser { thisTreeT !sym.exists || sym.unforcedIsAbsent || // ignore dependencies that have a symbol but do not exist. // e.g. java.lang.Object companion object - sym.is(PackageClass) || + sym.is(Package) || sym.isEffectiveRoot || sym.isAnonymousFunction || sym.isAnonymousClass diff --git a/sbt-bridge/test/xsbt/DependencySpecification.scala b/sbt-bridge/test/xsbt/DependencySpecification.scala index d702c5993be3..12dd3113a7ac 100644 --- a/sbt-bridge/test/xsbt/DependencySpecification.scala +++ b/sbt-bridge/test/xsbt/DependencySpecification.scala @@ -145,6 +145,25 @@ class DependencySpecification { assertEquals(Set("abc.A"), deps("H")) } + @Test + def extractedClassDependenciesOnPackageObject = { + val srcA = "package object foo { def bar = 1 }" + val srcB = + """|package foo + | + |class Test { + | bar + |} + """.stripMargin + + val compilerForTesting = new ScalaCompilerForUnitTesting + val classDependencies = + compilerForTesting.extractDependenciesFromSrcs(srcA, srcB) + + val memberRef = classDependencies.memberRef + assertEquals(Set("foo.package"), memberRef("foo.Test")) + } + private def extractClassDependenciesPublic: ExtractedClassDependencies = { val srcA = "class A" val srcB = "class B extends D[A]" diff --git a/sbt-bridge/test/xsbt/ExtractUsedNamesSpecification.scala b/sbt-bridge/test/xsbt/ExtractUsedNamesSpecification.scala index 1c05fd3b6394..3d619255c532 100644 --- a/sbt-bridge/test/xsbt/ExtractUsedNamesSpecification.scala +++ b/sbt-bridge/test/xsbt/ExtractUsedNamesSpecification.scala @@ -275,6 +275,20 @@ class ExtractUsedNamesSpecification { assertEquals(Set(), findPatMatUsages(notUsedInPatternMatch)) } + @Test + def extractedNamesInImport = { + val src = + """|import java.util.List + | + |class Test + """.stripMargin + + val compilerForTesting = new ScalaCompilerForUnitTesting + val usedNames = compilerForTesting.extractUsedNamesFromSrc(src) + + assertEquals(standardNames + "List", usedNames("Test")) + } + /** * Standard names that appear in every compilation unit that has any class * definition. From 33da2b6293ab45dd40218662f1f4490bf889d3bc Mon Sep 17 00:00:00 2001 From: Allan Renucci Date: Mon, 16 Apr 2018 17:59:10 +0200 Subject: [PATCH 2/5] Fix tests --- .drone.yml | 6 +++--- sbt-bridge/test/xsbt/ExtractUsedNamesSpecification.scala | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.drone.yml b/.drone.yml index 53f9516b7a6a..07ee3a45f974 100644 --- a/.drone.yml +++ b/.drone.yml @@ -49,9 +49,9 @@ pipeline: commands: - cp -R . /tmp/4/ && cd /tmp/4/ - ./project/scripts/sbt sbt-dotty/scripted - # when: - # # sbt scripted tests are slow and only run on nightly or deployment - # event: [ tag, deployment ] + when: + # sbt scripted tests are slow and only run on nightly or deployment + event: [ tag, deployment ] # DOCUMENTATION: documentation: diff --git a/sbt-bridge/test/xsbt/ExtractUsedNamesSpecification.scala b/sbt-bridge/test/xsbt/ExtractUsedNamesSpecification.scala index 3d619255c532..f39f98a60e4a 100644 --- a/sbt-bridge/test/xsbt/ExtractUsedNamesSpecification.scala +++ b/sbt-bridge/test/xsbt/ExtractUsedNamesSpecification.scala @@ -15,7 +15,7 @@ class ExtractUsedNamesSpecification { |}""".stripMargin val compilerForTesting = new ScalaCompilerForUnitTesting val usedNames = compilerForTesting.extractUsedNamesFromSrc(src) - val expectedNames = standardNames ++ Set("a", "A", "A2", "b") + val expectedNames = standardNames ++ Set("A", "A2") // names used at top level are attributed to the first class defined in a compilation unit assertEquals(expectedNames, usedNames("a.A")) @@ -43,7 +43,7 @@ class ExtractUsedNamesSpecification { |}""".stripMargin val compilerForTesting = new ScalaCompilerForUnitTesting val usedNames = compilerForTesting.extractUsedNamesFromSrc(srcA, srcB) - val expectedNames = standardNames ++ Set("a", "c", "A", "B", "C", "D", "b", "BB") + val expectedNames = standardNames ++ Set("A", "B", "C", "D", "BB") assertEquals(expectedNames, usedNames("b.X")) } From 6f3cd2860a9170ccd2ff34870083bfbf206aaeaa Mon Sep 17 00:00:00 2001 From: Allan Renucci Date: Tue, 17 Apr 2018 11:45:00 +0200 Subject: [PATCH 3/5] Record used name for packages --- .../src/dotty/tools/dotc/sbt/ExtractDependencies.scala | 7 +++++-- sbt-bridge/test/xsbt/ExtractUsedNamesSpecification.scala | 7 ++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/sbt/ExtractDependencies.scala b/compiler/src/dotty/tools/dotc/sbt/ExtractDependencies.scala index d17ab5033094..c03dfba7bc65 100644 --- a/compiler/src/dotty/tools/dotc/sbt/ExtractDependencies.scala +++ b/compiler/src/dotty/tools/dotc/sbt/ExtractDependencies.scala @@ -295,8 +295,12 @@ private class ExtractDependenciesCollector extends tpd.TreeTraverser { thisTreeT val fromClass = resolveDependencySource if (fromClass.exists) { // can happen when visiting imports assert(fromClass.isClass) - _dependencies += ClassDependency(fromClass, enclOrModuleClass, DependencyByMemberRef) + addUsedName(fromClass, mangledName(sym), UseScope.Default) + // packages have class symbol. Only record them as used names but bot dependency + if (!sym.is(Package)) { + _dependencies += ClassDependency(fromClass, enclOrModuleClass, DependencyByMemberRef) + } } } @@ -315,7 +319,6 @@ private class ExtractDependenciesCollector extends tpd.TreeTraverser { thisTreeT !sym.exists || sym.unforcedIsAbsent || // ignore dependencies that have a symbol but do not exist. // e.g. java.lang.Object companion object - sym.is(Package) || sym.isEffectiveRoot || sym.isAnonymousFunction || sym.isAnonymousClass diff --git a/sbt-bridge/test/xsbt/ExtractUsedNamesSpecification.scala b/sbt-bridge/test/xsbt/ExtractUsedNamesSpecification.scala index f39f98a60e4a..befe2dd433d3 100644 --- a/sbt-bridge/test/xsbt/ExtractUsedNamesSpecification.scala +++ b/sbt-bridge/test/xsbt/ExtractUsedNamesSpecification.scala @@ -15,7 +15,7 @@ class ExtractUsedNamesSpecification { |}""".stripMargin val compilerForTesting = new ScalaCompilerForUnitTesting val usedNames = compilerForTesting.extractUsedNamesFromSrc(src) - val expectedNames = standardNames ++ Set("A", "A2") + val expectedNames = standardNames ++ Set("a", "A", "A2", "b") // names used at top level are attributed to the first class defined in a compilation unit assertEquals(expectedNames, usedNames("a.A")) @@ -43,7 +43,7 @@ class ExtractUsedNamesSpecification { |}""".stripMargin val compilerForTesting = new ScalaCompilerForUnitTesting val usedNames = compilerForTesting.extractUsedNamesFromSrc(srcA, srcB) - val expectedNames = standardNames ++ Set("A", "B", "C", "D", "BB") + val expectedNames = standardNames ++ Set("a", "c", "A", "B", "C", "D", "b", "BB") assertEquals(expectedNames, usedNames("b.X")) } @@ -286,7 +286,8 @@ class ExtractUsedNamesSpecification { val compilerForTesting = new ScalaCompilerForUnitTesting val usedNames = compilerForTesting.extractUsedNamesFromSrc(src) - assertEquals(standardNames + "List", usedNames("Test")) + val expectedNames = standardNames ++ Set("java", "util", "List") + assertEquals(expectedNames, usedNames("Test")) } /** From d2ee74546ab559e3e61b3e8c47ebc83fe45b61db Mon Sep 17 00:00:00 2001 From: Allan Renucci Date: Tue, 17 Apr 2018 17:11:32 +0200 Subject: [PATCH 4/5] Add failing test case (pending) --- .../package-object-implicit/Test.scala | 6 ++++++ .../package-object-implicit/changes/package.scala | 3 +++ .../package-object-implicit/pending | 7 +++++++ .../project/DottyInjectedPlugin.scala | 12 ++++++++++++ .../package-object-implicit/project/plugins.sbt | 1 + 5 files changed, 29 insertions(+) create mode 100644 sbt-dotty/sbt-test/source-dependencies/package-object-implicit/Test.scala create mode 100644 sbt-dotty/sbt-test/source-dependencies/package-object-implicit/changes/package.scala create mode 100644 sbt-dotty/sbt-test/source-dependencies/package-object-implicit/pending create mode 100644 sbt-dotty/sbt-test/source-dependencies/package-object-implicit/project/DottyInjectedPlugin.scala create mode 100644 sbt-dotty/sbt-test/source-dependencies/package-object-implicit/project/plugins.sbt diff --git a/sbt-dotty/sbt-test/source-dependencies/package-object-implicit/Test.scala b/sbt-dotty/sbt-test/source-dependencies/package-object-implicit/Test.scala new file mode 100644 index 000000000000..2ae5c84d1eb3 --- /dev/null +++ b/sbt-dotty/sbt-test/source-dependencies/package-object-implicit/Test.scala @@ -0,0 +1,6 @@ +package foo + +object Test { + def test(implicit x: Int = 1): String = x.toString + def main(args: Array[String]): Unit = test +} diff --git a/sbt-dotty/sbt-test/source-dependencies/package-object-implicit/changes/package.scala b/sbt-dotty/sbt-test/source-dependencies/package-object-implicit/changes/package.scala new file mode 100644 index 000000000000..774fa9a700a7 --- /dev/null +++ b/sbt-dotty/sbt-test/source-dependencies/package-object-implicit/changes/package.scala @@ -0,0 +1,3 @@ +package object foo { + implicit val x: Int = ??? +} diff --git a/sbt-dotty/sbt-test/source-dependencies/package-object-implicit/pending b/sbt-dotty/sbt-test/source-dependencies/package-object-implicit/pending new file mode 100644 index 000000000000..7c063eaea347 --- /dev/null +++ b/sbt-dotty/sbt-test/source-dependencies/package-object-implicit/pending @@ -0,0 +1,7 @@ +> run + +$ copy-file changes/package.scala package.scala + +# New implicit in scope from package object that makes run throws +# clean run fails correctly +-> run diff --git a/sbt-dotty/sbt-test/source-dependencies/package-object-implicit/project/DottyInjectedPlugin.scala b/sbt-dotty/sbt-test/source-dependencies/package-object-implicit/project/DottyInjectedPlugin.scala new file mode 100644 index 000000000000..ce3d46d79921 --- /dev/null +++ b/sbt-dotty/sbt-test/source-dependencies/package-object-implicit/project/DottyInjectedPlugin.scala @@ -0,0 +1,12 @@ +import sbt._ +import Keys._ + +object DottyInjectedPlugin extends AutoPlugin { + override def requires = plugins.JvmPlugin + override def trigger = allRequirements + + override val projectSettings = Seq( + scalaVersion := sys.props("plugin.scalaVersion"), + scalacOptions += "-language:Scala2" + ) +} diff --git a/sbt-dotty/sbt-test/source-dependencies/package-object-implicit/project/plugins.sbt b/sbt-dotty/sbt-test/source-dependencies/package-object-implicit/project/plugins.sbt new file mode 100644 index 000000000000..c17caab2d98c --- /dev/null +++ b/sbt-dotty/sbt-test/source-dependencies/package-object-implicit/project/plugins.sbt @@ -0,0 +1 @@ +addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % sys.props("plugin.version")) From 8115009874352715ef47f8524111fbce00284661 Mon Sep 17 00:00:00 2001 From: Allan Renucci Date: Thu, 19 Apr 2018 21:54:37 +0200 Subject: [PATCH 5/5] Fix typo --- compiler/src/dotty/tools/dotc/sbt/ExtractDependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/sbt/ExtractDependencies.scala b/compiler/src/dotty/tools/dotc/sbt/ExtractDependencies.scala index c03dfba7bc65..593801633f76 100644 --- a/compiler/src/dotty/tools/dotc/sbt/ExtractDependencies.scala +++ b/compiler/src/dotty/tools/dotc/sbt/ExtractDependencies.scala @@ -297,7 +297,7 @@ private class ExtractDependenciesCollector extends tpd.TreeTraverser { thisTreeT assert(fromClass.isClass) addUsedName(fromClass, mangledName(sym), UseScope.Default) - // packages have class symbol. Only record them as used names but bot dependency + // packages have class symbol. Only record them as used names but not dependency if (!sym.is(Package)) { _dependencies += ClassDependency(fromClass, enclOrModuleClass, DependencyByMemberRef) }