Closed miqm closed 2 months ago
@miqm -- Did this error occur only once, or is it regularly reproducible for you? I have a fix but am a bit worried that I'm missing something since I haven't been able to reproduce using the provided templates.
It was reproducible as in the issue.
Are you only seeing it in certain environments? The following test written from the repro case is passing every time in a Windows desktop environment:
[TestMethod]
public void Symbols_entering_the_import_closure_via_multiple_paths_are_supported()
{
var result = CompilationHelper.Compile(
("main.bicep", """
import * as typesB from 'moduleB.bicep'
import * as typesC from 'moduleC.bicep'
"""),
("moduleA.bicep", """
@export()
type typeA = {
propA: string
}
"""),
("moduleB.bicep", """
import * as typesAinB from 'moduleA.bicep'
@export()
type typeB = {
optionsA: typesAinB.typeA
propB: string
}
"""),
("moduleC.bicep", """
import * as typesAinC from 'moduleA.bicep'
@export()
type typeB = {
optionsA: typesAinC.typeA
propC: string
}
"""));
result.ExcludingLinterDiagnostics().Should().NotHaveAnyDiagnostics();
}
I tried to reproduce it on Windows and I couldn't. however I mainly do bicep work on Mac (M1) so it could be platform-related...
Wait, I have a repro - the names of import as in modB and modC must be equal, not different. it works when they are different, but fails when there are equal. I probably got confused when writing the bug report. sorry.... I updated the issue.
Is that failure also only on a Mac? It seems to be working fine on Windows, but the logic to deduplicate looks like it's relying on some default equality checks. Those shouldn't differ from platform to platform, but I've seen similar issues in the past.
The repro I have it's on Windows, please check where instead import * as typesAinB/C from 'moduleA.bicep'
you have import * as typesA from 'moduleA.bicep'
in both modB and modC
I am able to reproduce on Windows, but only when building main.bicep
from the VS Code UI. (Building the same files with bicep build main.bicep
succeeds without an error.) Does this match your experience on a Mac?
If so, I think the difference is not related to platform but rather caused by how Bicep caches compiled templates. The code that's throwing an error assumes that moduleA.bicep
in the example will always resolve to the same in-memory representation. This appears to be true for the Bicep CLI (and for the unit tests) but may not necessarily be the case for the VS Code extension.
Not sure now, but it definitely was (and is) failing when building from the VSCode. Now that I test, from cli it seems to be fine.
@jeskew any findings?
@miqm From what I have been able to find, this error can only occur when the following conditions are met:
typeA
-> moduleB.bicep
and typeA
-> moduleC.bicep
)main.bicep
and moduleB.bicep
are loaded as tabs in VS Code)moduleA.bicep
is not open in VS Code) moduleB.bicep
is updated in VS Code)The root cause is that the language server stores an "active context" for each open .bicep
or .bicepparam
tab in VS Code, and each active context will retain a compiled model of each file within the tab's transitive closure (i.e., any Bicep files used as either modules or import sources, plus files they use as modules or import sources, etc.). Following the sequence of steps outlined above can result in the VS Code extension combining models from different contexts.
The logic that handles transitive imports was assuming every compiled model would be sourced from the same compilation context. I opened a PR to have that logic deduplicate imports based on the identifiers of the imported symbol rather than using object identity as a basis for comparison.
Bicep version v0.27.1
Describe the bug Module A exports a type. Modules B and C imports that type (crucial - under this same names!) and as a part of it's own type - type from module A is exported Main file includes types from B and C Compilation fails
To Reproduce moduleA.bicep
moduleB.bicep
moduleC.bicep
main.bicep
Additional context This problem does not exist if imports in moduleB and moduleC have same syntax, i.e.
import * as typesA from 'moduleA.bicep'
stacktrace