Skip to content
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 resolution throws exception for non-existing symbols #6457

Closed
wants to merge 41 commits into from

Conversation

Akirathan
Copy link
Member

@Akirathan Akirathan commented Apr 27, 2023

Pull Request Description

Adds a new step to the Compiler's imports/exports resolution, implemented by the SymbolsImportResolution class, that resolves all the symbols from from ... import symbol_1, symbol_2, ... statements and adds these additional information to the appropriate BindingMap.

Important Notes

  • Fills in additional resolved import targets to the BindingMap.
  • SymbolsImportResolution needs to be implemented as a separate step from ImportResolver, as checking for some symbols requires information provided by ExportsResolution that is scheduled by the Compiler after ImportResolver.
  • Adds ImportExportTest that synthetically creates modules with various import/export statements.

Checklist

Please ensure that the following checklist has been satisfied before submitting the PR:

  • The documentation has been updated, if necessary.
  • Screenshots/screencasts have been attached, if there are any visual changes. For interactive or animated visual changes, a screencast is preferred.
  • All code follows the
    Scala,
    Java,
    and
    Rust
    style guides. In case you are using a language not listed above, follow the Rust style guide.
  • All code has been tested:
    • Unit tests have been written where possible.
    • If GUI codebase was changed, the GUI was tested when built using ./run ide build.

@Akirathan Akirathan force-pushed the wip/akirathan/import-from-error-5936 branch from e3e17c7 to 6c06775 Compare May 5, 2023 22:13
@Akirathan Akirathan force-pushed the wip/akirathan/import-from-error-5936 branch from b7c8cbb to 6f4df8c Compare May 11, 2023 16:09
@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


Pavel Marek seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

"Resolving import symbols for module {0}",
Array[Object](module.getName.toString)
)
module.unsafeSetIr(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels a bit dangerous and against the typical pass design. If there are any errors then they should potentially returned as part of this method and it shouldn't be Unit?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly - this is not a typical pass design on purpose. It has similar design to ImportResolver that also does module.unsafeSetIr. Both ImportResolver and SymbolsImportResolution are kind of compiler-internal passes that operate directly on BindingMap and are allowed to set the IR of a module with unsafeSetIR, if I correctly understand the design. The same is true also for ExportResolution.

Comment on lines 167 to 168
val exportedSymbols: ListBuffer[BindingsMap.ImportTarget] = ListBuffer.empty
importedModuleBindingMap.exportedSymbols.foreach {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again flatMap

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know how to do this for these two nested foreach loops. I am bumping into type errors. Would you provide me suggestion here pls?

Comment on lines +242 to +264
val moduleName = if (shouldImportFromType) {
importedName.parts.dropRight(1).map(_.name).mkString(".")
} else {
importedName.name
}
val typeName: Option[String] = if (shouldImportFromType) {
Some(importedName.parts.last.name)
} else {
None
}
logger.log(
Level.FINEST,
"moduleName = {0}, typeName = {1}",
Array[Object](moduleName, typeName)
)

val importedModule = compiler.getModule(moduleName) match {
case Some(module) => module
case None =>
throw new CompilerError(
s"Module ${moduleName} should already be imported"
)
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could be combined into one condition/match

"Trying to resolve symbol {0} from type {1} from module {2} defined entities",
Array[Object](symbolToImport, typeName, module.getName)
)
if (typeName.isDefined) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use pattern match instead of conditionals

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really? I use a conditional here on purpose. The block that follows this conditional is rather complicated and long, and uses a lot of pattern matching. Should I introduce yet another level of pattern match?

Comment on lines 479 to 480
val bindingMap = module.getIr.unsafeGetMetadata(
BindingAnalysis, "Should be here"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be done once and I think this is attempted in other place as well

Comment on lines 520 to 523
case resolvedModule: BindingsMap.ResolvedModule => resolvedModule
case resolvedType: BindingsMap.ResolvedType => resolvedType
case resolvedMethod: BindingsMap.ResolvedMethod => resolvedMethod
case resolvedCtor: BindingsMap.ResolvedConstructor => resolvedCtor
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there anything else? Because it feels like you are just copying the list

Comment on lines 490 to 498
case Some(ctor) => Left(BindingsMap.ResolvedConstructor(resolvedType, ctor))
case None =>
Right(
IR.Error.ImportExport.NoSuchConstructor(
resolvedType.tp.name,
symbolToImport.name
)
)
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

by convention Left is an error value, Right is not

@JaroslavTulach
Copy link
Member

This is an interesting error:

The name Integer is ambiguous. Possible candidates are:
      Type Integer defined in module Standard.Base.Data.Numbers
      Constructor Report_Error defined in module Standard.Base.Errors.Problem_Behavior;
      The method uncurry defined in module Standard.Base.Function
      The method curry defined in module Standard.Base.Function

hopefully it's going to be easy to fix...

})

bindingMap.resolvedImports =
bindingMap.resolvedImports.appendedAll(resolvedImports)
Copy link
Member

@JaroslavTulach JaroslavTulach May 17, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another place that is modifying bindingMap!?

This scares me. Last week I saw how wild operations with BindingMap were. Various parts of BindingMap are filled by various passes. This change makes them even wilder (previously the resolvedImports were only modified at ImportResolver at least) and I am not sure why? Originally we were supposed to fix #5936 - however for that we don't need any changes to bindingMap.resolvedImports.

While #5936 was supposed to be addressed by a bugfix, this PR is implementing some new functionality. I don't think we should integrate new functionality at this time of the release.

@Akirathan
Copy link
Member Author

This PR grew out of hand and contains changes that are not preferable during the Enso release phase. With @JaroslavTulach we have, therefore, concluded that it is best to leave this PR at this moment and to dissect only a subset of the functionality into (preferably a Compiler pass) another PR that only reports an error in case of non-existing symbols, and does not provide additional information in the binding map.

Most of the functionality in this PR stays relevant for symbol resolution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants