-
Notifications
You must be signed in to change notification settings - Fork 322
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
Import syntax including namespace #1806
Conversation
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.
Don't include the image at distribution/std-lib/Examples/data/image.png
. It was ignored in .gitignore
but its path has changed. Please adapt .gitignore
.
Additionally, please test and confirm that we still get the suggestions in the IDE as expected.
Finally, you're missing a changelog entry. Please put one in RELEASES.md
.
@@ -169,7 +169,7 @@ case object DocumentationComments extends IRPass { | |||
case expr: IR.Expression => resolveExpression(expr) | |||
case df: IR.Module.Scope.Definition => resolveDefinition(df) | |||
case imp: IR.Module.Scope.Import => imp | |||
case exp: IR.Module.Scope.Export => exp | |||
case exp: IR.Module.Scope.Export.Module => exp |
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.
Formatting.
val exp = ir.exports | ||
.collect { case ex: IR.Module.Scope.Export.Module => ex } | ||
.find(_.name.name == impName) |
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.
Given you're touching the imports resolver, how much work would it be to fix #1569?
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.
More than I can spend :P Probably ~2 days.
@@ -1,3 +1,4 @@ | |||
import Cycle_Test.Sub.Imp | |||
import project.Sub.Imp |
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.
Can we still import by the project name itself?
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 would think so, because the desugar process converts to exactly that, so there should be no reason why that would be disallowed.
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.
Project name + name space. So the original import here is invalid, but you could write import local.Cycle_Test.Sub.Imp
.collect { | ||
case AST.Ident.Cons.any(n) => n | ||
case AST.Ident.Var.any(n) => n | ||
} |
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.
Do you mean to implicitly ignore anything that somehow slips through to here? .collect
will discard things that don't match.
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 think given how the qualNamePat
is defined, nothing else could show up here, right?
But then if it is ever changed, indeed an error could be introduced that will go unnoticed here, so I think I'd +1 that it would be good to somehow handle the unexpected (currently, but not necessarily forever, impossible) case.
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.
It also contains the Opr('.')
segments, this is a way of filtering them.
tools/ci/Test.enso
Outdated
@@ -1,3 +1,3 @@ | |||
from Builtins import all | |||
from Standard.Builtins import all | |||
|
|||
main = IO.println "Test successful." |
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.
Missing line ending.
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.
Looks good overall
Below are some comments
|
||
## Returns the namespace of the project. | ||
|
||
> Example | ||
Get the name of the current project. | ||
|
||
Enso_Project.namespace | ||
Builtins.Project_Description.namespace : Text | ||
Builtins.Project_Description.namespace = this.prim_config.namespace |
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.
This doc is unclear to me about what is the behaviour if I do the following:
Library Foo.Bar defines a method baz = Builtins.Project_Description.namespace
and then in a project radeusgd.Hmm
I do import Foo.Bar
and then IO.println Foo.Bar.baz
. Will it return Hmm
or Foo
?
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.
Project_Descritption
is just an atom, so you call namespace
on its instance, obtained through calling the enso_project
method of some module. The wording is unclear indeed, I'll fix this (and the method above, as this one is a copy-paste :P )
@@ -10,7 +10,7 @@ object RefactoringApi { | |||
|
|||
case object RenameProject extends Method("refactoring/renameProject") { | |||
|
|||
case class Params(oldName: String, newName: String) | |||
case class Params(namespace: String, oldName: String, newName: String) |
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 think it may be worth noting somewhere explicitly that the rename can (currently) only change the project name, but not the namespace
.
/** Signals that project has been renamed. | ||
* | ||
* @param newName the new project name | ||
*/ | ||
case class ProjectRenamed(newName: String) extends ApiResponse | ||
case class ProjectRenamed(namespace: String, newName: String) | ||
extends ApiResponse |
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.
Missing doc for namespace
* @param name the qualified name of this module. | ||
* @param sourceFile the module's source file. | ||
*/ | ||
public Module(QualifiedName name, TruffleFile sourceFile) { | ||
public Module(QualifiedName name, Package<TruffleFile> pkg, TruffleFile sourceFile) { |
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.
Missing doc for the added parameter
def copy( | ||
name: IR.Name.Qualified = name, | ||
rename: Option[IR.Name.Literal] = rename, | ||
isAll: Boolean = isAll, |
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 know that this is not part of this PR, but this name isAll
seems a bit confusing to me, especially as below there are special cases where isAll
does not really mean all
. Maybe it could be renamed to something more appropriate, like isQualified
?
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, it maybe could, when someone works on this
* @param dependencies a list of package dependencies | ||
* @param originalJson a Json object holding the original values that this | ||
* Config was created from, used to preserve configuration | ||
* keys that are not known | ||
*/ | ||
case class Config( | ||
name: String, | ||
namespace: String, |
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.
Namespace is not documented.
I think it's important to note here that this is just a temporary workaround that will be removed once it is possible.
Also that it falls back to local
if not provided.
"from Foo.Bar.Quux import Baz", | ||
"from Foo.Bar.Test import Baz, Spam", |
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.
Why these two are not prefixed by username? Or is Foo
meant to be the username here? It's a bit confusing as in other examples Foo
is used as project/module name. If this is meant to test capitalised usernames, I'd suggest making this Username
instead of Foo
.
val id1 = meta.addItem(33, 36) | ||
val id2 = meta.addItem(58, 8) | ||
val id1 = meta.addItem(42, 36) | ||
val id2 = meta.addItem(67, 8) |
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.
It's worrying to me that so many of our tests rely on these locations.
Because, if the tests are being updated it's so extremely tempting to just run them, see what are the new locations and paste them here without checking if they correspond to the right entities.
It's certainly not within scope of this PR to fix that, but just wanted to mention that maybe at some point we could consider taking some other approach, which could maybe be based on identifying the locations by some infix or something more readable than just an integer location.
cc: @iamrecursion
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.
Because, if the tests are being updated it's so extremely tempting to just run them, see what are the new locations and paste them here without checking if they correspond to the right entities.
Would be very tempting, if that was possible... But the only feedback these give you is "the node you want doesn't exist". Nonetheless, the idea of having special markers for metadata is awesome (and I'm pretty sure @mwu-tow already has something like that in the IDE?)
this.copy(path = newName :: path.tail) | ||
val namespace = path.head | ||
this.copy(path = namespace :: newName :: path.drop(2)) |
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 understand that we can assume that the project
sugar is already not present here, correct?
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
.collect { | ||
case AST.Ident.Cons.any(n) => n | ||
case AST.Ident.Var.any(n) => n | ||
} |
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 think given how the qualNamePat
is defined, nothing else could show up here, right?
But then if it is ever changed, indeed an error could be introduced that will go unnoticed here, so I think I'd +1 that it would be good to somehow handle the unexpected (currently, but not necessarily forever, impossible) case.
builtins -> standard.builtins progress towards tests fixing more tests more tests more tests (almost) all tests untangle std untangle std all e2e tests error handling licenses CR feedback remove image.png
c27a234
to
6422ef2
Compare
RELEASES.md
Outdated
- Implemented changes to the import and export syntax, requiring to provide the | ||
project namespace, or use the new `project` keyword to import from the current | ||
project. |
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.
Please put this under Interpreter/Runtime
and add the PR number.
"from Username.Bar export all", | ||
"from Username.Bar as Eggs export all hiding Spam", | ||
"from Username.Bar export all hiding Spam, eggs" |
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.
Probably should test with project
and lowercase username
.
@@ -324,7 +324,9 @@ polyglot java import org.enso.base.Text_Utils | |||
Token::line( | |||
vec![ | |||
Token::variable("from", 0), | |||
Token::referent("Builtins", 1), | |||
Token::referent("Standard", 1), | |||
Token::operator(".",0), |
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.
Token::operator(".",0), | |
Token::operator(".", 0), |
@kustosz I think the change in the import syntax should be reflected in docs: https://enso.org/docs/developer/enso/syntax/imports.html#imports-and-exports or https://enso.org/docs/developer/enso/semantics/modules.html#referring-to-modules What namespace will the stdlib have?
|
Pull Request Description
Modifies the import syntax to include the author/namespace prefix in project names. Also introduces a special
project
keyword for imports of modules from the current project.Important Notes
This introduces a
namespace
field topackage.yaml
. This is a temporary solution, as this is supposed to be mediated by the libraries repository in the future.It's a very breaking change.
Also introduces a breaking change to the
refactoring/renameProject
method of the language server, requiring the namespace to be provided for project identification.Checklist
Please include the following checklist in your PR: