-
Notifications
You must be signed in to change notification settings - Fork 3.1k
SI-6623 -Yrepl-use-magic-imports avoids nesting $iw wrappers #8576
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Nice idea! Maybe give it a test run in combination with |
som-snytt
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Way to "level up"!
| 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the user-level use case for that? Something to do with sealed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A lot has changed in four years, including spaces in braces.
| addLevelChangingImport() | ||
| } else { | ||
| addWrapperCode() | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lots of braces.
|
/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.