SI-6623 -Yrepl-use-magic-imports avoids nesting $iw wrappers#8576
SI-6623 -Yrepl-use-magic-imports avoids nesting $iw wrappers#8576retronym merged 9 commits intoscala:2.12.xfrom
Conversation
|
Nice idea! Maybe give it a test run in combination with |
| val YmacroFresh = BooleanSetting ("-Ymacro-global-fresh-names", "Should fresh names in macros be unique across all compilation units") | ||
| val Yreplsync = BooleanSetting ("-Yrepl-sync", "Do not use asynchronous code for repl startup") | ||
| val Yreplclassbased = BooleanSetting ("-Yrepl-class-based", "Use classes to wrap REPL snippets instead of objects") | ||
| val YreplMagicImport = BooleanSetting ("-Yrepl-use-magic-imports", "In the code the wraps REPL snippes, use magic imports to rather than nesting wrapper object/classes") |
There was a problem hiding this comment.
sorry to snipe at snippes, which I guess is the French.
In the code that wraps REPL snippets, use magic imports rather
| tree match { | ||
| case Import(expr, selector :: Nil) => | ||
| // Just a syntactic check to avoid forcing typechecking of imports | ||
| selector.name.string_==(nme.INTERPRETER_IMPORT_LEVEL_UP) && owner.enclosingTopLevelClass.isInterpreterWrapper |
There was a problem hiding this comment.
My other use case was to submit a directory of source files as a single compilation unit, with files wrapped in LEVEL_UP and LEVEL_DOWN and then concatenated in a single source, so that top-level statements would not collide. That would not be in a repl wrapper. If double brace isn't magical enough, how about ${{?
Maybe also call it WRAPL.
There was a problem hiding this comment.
What's the user-level use case for that? Something to do with sealed?
There was a problem hiding this comment.
Yes, on that thread they were complaining that their files get too big when they cram everything in. That also covers companionship. Sometimes I feel like I'm crammed in with my companion.
| // warn proactively if specific import loses to definition in scope, | ||
| // since it may result in desired implicit not imported into scope. | ||
| def checkNotRedundant(pos: Position, from: Name, to0: Name): Unit = { | ||
| def check(to: Name): Unit = { |
There was a problem hiding this comment.
Um. I guess since we're talking import magic. I know the check used to be wrong, false positive. Now I'm not sure what the user story is. Oh, this is covered by unused import. So is this check only guarding against old bugs in name binding? Including implicit shadowing?
object X {
val global = 0
import concurrent.ExecutionContext.global
println(global)
}
There was a problem hiding this comment.
Yes, I see bug 2866 is due to Jason: "I have five unanswered questions"... after grepping for permanently hidden again in the check files...
There was a problem hiding this comment.
Yeah, I dropped your changes to this code from #5220 as I didn't understand the original code or the change. 🤷♂
There was a problem hiding this comment.
I'm not sure it's very meaningful, even if it had a bug-compatible meaning once.
| def addWrapper() { | ||
| import nme.{ INTERPRETER_IMPORT_WRAPPER => iw } | ||
| def addWrapperCode(): Unit = { | ||
| import nme.{INTERPRETER_IMPORT_WRAPPER => iw} |
There was a problem hiding this comment.
A lot has changed in four years, including spaces in braces.
| addLevelChangingImport() | ||
| } else { | ||
| addWrapperCode() | ||
| } |
|
/rebuild 09063fc |
I've enabled I eliminated some of these failures by:
The remaining problems are:
We need some sort of story for these use cases before we could enable class-based mode by default. |
ca0d6ee to
6527e07
Compare
- Make `ImportContext` a nested class
- Avoid the constructor of the superclass `Context` needing to
call methods on the unitialized subclass ImportContext by
computing `isRootContext` / `depth` externally in the
factory method.
Rather than adding a wrapper object for each import in the session history, just use a single wrapper preceded by the imports which have been interspersed with a magic import to bump context depth. Code is still ordinarily wrapped in a `$read` object. This is a step toward 6623-like transparency. `retronym` takes the blame for this innovation. `adriaanm` collaborated in its commission. `somsnytt` batted clean-up.
To be reverted.
… bug By default, the parser tries to heal incomplete source files by inserting missing braces. Compilation will still error out, but any subsequent parser/type errors make more sense to the user when this healing works. The healing uses indentation to figure out the intent of the code. Wrapped REPL snippets aren't properly indented, and in the test case I added the healing seems counterproductive. This commit disables it in REPL tab completion, in line with the way that IMain parses the wrapped code for real compilation.
- add comments describing a problem I discovered with imports
and a possible solution
- Make strip wrappers from REPL output for the wrappers generated in this mode
6527e07 to
952e561
Compare
952e561 to
cfaf9f8
Compare
This detail changes under -Yrepl-class-based. We prefer tests that operate under either mode.
cfaf9f8 to
b63b7dc
Compare
b63b7dc to
50c74cd
Compare
|
I was about to rebase when I realized this is on an old version of Scala. I was just doing |
|
I'll do the hand-woven forward port of this to 2.13.x: https://github.com/scala/scala/compare/2.13.x...retronym:topic/repl-magic-forward-port?expand=1 |
Rather than adding a wrapper object for each import in the session history,
just use a single wrapper preceded by the imports which have been
interspersed with a magic import to bump context depth.
Code is still ordinarily wrapped in a
$readobject.This is a step toward 6623-like transparency.
retronymtakes the blame for this innovation.adriaanmcollaborated in its commission.somsnyttbatted clean-up.The following stress test now completes; before it exhausted memory after 70 iterations.