Skip to content

Commit 86e36e7

Browse files
authored
Add -Yimports compiler flag (#16218)
Fixes lampepfl/dotty-feature-requests#138
2 parents ef8cc3e + e0e61bd commit 86e36e7

32 files changed

+214
-9
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ private sealed trait YSettings:
281281
val Yscala2Unpickler: Setting[String] = StringSetting("-Yscala2-unpickler", "", "Control where we may get Scala 2 symbols from. This is either \"always\", \"never\", or a classpath.", "always")
282282

283283
val YnoImports: Setting[Boolean] = BooleanSetting("-Yno-imports", "Compile without importing scala.*, java.lang.*, or Predef.")
284+
val Yimports: Setting[List[String]] = MultiStringSetting("-Yimports", helpArg="", "Custom root imports. If set, none of scala.*, java.lang.*, or Predef.* will be imported unless explicitly included.")
284285
val YnoGenericSig: Setting[Boolean] = BooleanSetting("-Yno-generic-signatures", "Suppress generation of generic signatures for Java.")
285286
val YnoPredef: Setting[Boolean] = BooleanSetting("-Yno-predef", "Compile without importing Predef.")
286287
val Yskip: Setting[List[String]] = PhasesSetting("-Yskip", "Skip")

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

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1558,12 +1558,21 @@ class Definitions {
15581558
private val PredefImportFns: RootRef =
15591559
RootRef(() => ScalaPredefModule.termRef, isPredef=true)
15601560

1561-
@tu private lazy val JavaRootImportFns: List[RootRef] =
1562-
if ctx.settings.YnoImports.value then Nil
1563-
else JavaImportFns
1561+
@tu private lazy val YimportsImportFns: List[RootRef] = ctx.settings.Yimports.value.map { name =>
1562+
val denot =
1563+
getModuleIfDefined(name).suchThat(_.is(Module)) `orElse`
1564+
getPackageClassIfDefined(name).suchThat(_.is(Package))
1565+
if !denot.exists then
1566+
report.error(s"error: bad preamble import $name")
1567+
val termRef = denot.symbol.termRef
1568+
RootRef(() => termRef)
1569+
}
1570+
1571+
@tu private lazy val JavaRootImportFns: List[RootRef] = JavaImportFns
15641572

15651573
@tu private lazy val ScalaRootImportFns: List[RootRef] =
1566-
if ctx.settings.YnoImports.value then Nil
1574+
if !ctx.settings.Yimports.isDefault then YimportsImportFns
1575+
else if ctx.settings.YnoImports.value then Nil
15671576
else if ctx.settings.YnoPredef.value then ScalaImportFns
15681577
else ScalaImportFns :+ PredefImportFns
15691578

compiler/test/dotty/tools/dotc/CompilationTests.scala

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,6 @@ class CompilationTests {
151151
compileFile("tests/neg-custom-args/ovlazy.scala", scala2CompatMode.and("-Xfatal-warnings")),
152152
compileFile("tests/neg-custom-args/newline-braces.scala", scala2CompatMode.and("-Xfatal-warnings")),
153153
compileFile("tests/neg-custom-args/autoTuplingTest.scala", defaultOptions.andLanguageFeature("noAutoTupling")),
154-
compileFile("tests/neg-custom-args/nopredef.scala", defaultOptions.and("-Yno-predef")),
155-
compileFile("tests/neg-custom-args/noimports.scala", defaultOptions.and("-Yno-imports")),
156-
compileFile("tests/neg-custom-args/noimports2.scala", defaultOptions.and("-Yno-imports")),
157154
compileFile("tests/neg-custom-args/i1650.scala", allowDeepSubtypes),
158155
compileFile("tests/neg-custom-args/i3882.scala", allowDeepSubtypes),
159156
compileFile("tests/neg-custom-args/i4372.scala", allowDeepSubtypes),

tests/neg/missing-import.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
class annotation extends Annotation // error
2+
val s: String = "str"
3+
val regex: Regex = s.r // error

tests/neg/noimports-additional.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// scalac: -Yno-imports -Yimports:scala.annotation,scala.util.matching
2+
class annotation extends Annotation
3+
val s: String = "str" // error
4+
val regex: Regex = new Regex("str")
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// scalac: -Yno-imports
12
object Test {
23
val t: Int = 1 // error: not found Int
34
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// scalac: -Yno-imports
12
object Test {
23
assert("asdf" == "asdf") // error: not found assert
34
}

tests/neg/nopredef-additional.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// scalac: -Yno-predef -Yimports:java.lang,scala.annotation,scala.util.matching
2+
class annotation extends Annotation
3+
val s: String = "str"
4+
val regex: Regex = s.r // error

tests/neg/nopredef.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import Predef.{assert as _}
2-
1+
// scalac: -Yno-predef
32
object Test {
43
assert("asdf" == "asdf") // error: not found assert
54
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import Predef.{assert as _}
2+
13
object Test {
24
assert("asdf" == "asdf") // error: not found assert
35
}

0 commit comments

Comments
 (0)