Skip to content

Commit cf55b16

Browse files
reidspencerclaude
andcommitted
Add test confirming path resolution works with BAST imports
- Added "resolve references to imported types" test to BASTLoaderTest - Test confirms that imported definitions (e.g., TypeLibrary.UserId) resolve correctly - ResolutionPass already handles BASTImport.contents naturally since it's a Container - Updated SESSION_HANDOFF.md to mark Phase 4 as complete Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 1912674 commit cf55b16

2 files changed

Lines changed: 114 additions & 25 deletions

File tree

bast/SESSION_HANDOFF.md

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -102,26 +102,24 @@ Phase 3 (serialization/deserialization) is fully working. Phase 4 (import integr
102102
- Will need updates when Domain-level imports are added (Step 2)
103103

104104
#### Step 4: Update Resolution Pass
105-
**Status**: PENDING
105+
**Status**: COMPLETE ✅ (no changes needed!)
106106

107-
**Changes needed:**
108-
- Ensure ResolutionPass looks into `BASTImport.contents` when resolving paths
109-
- Since BASTImport is a Container, this may work naturally
110-
- Test that references like `ImportedDomain.SomeType` resolve correctly
107+
**Result:**
108+
- ResolutionPass already looks into `BASTImport.contents` when resolving paths
109+
- Since BASTImport is a Container, the resolution works naturally
110+
- Test confirmed: references like `ImportedDomain.SomeType` resolve correctly
111111

112-
**Files to modify:**
113-
- `passes/shared/src/main/scala/com/ossuminc/riddl/passes/resolve/ResolutionPass.scala`
112+
**No files needed modification** - the pass infrastructure already handles this.
114113

115114
#### Step 5: Update Tests
116-
**Status**: PENDING
115+
**Status**: COMPLETE ✅
117116

118-
**Changes needed:**
119-
- Update BASTLoaderTest to use new syntax (no `as`)
120-
- Add tests for import within domains
121-
- Add tests for duplicate definition errors
122-
- Add tests for path resolution across imports
117+
**Changes made:**
118+
- Updated BASTLoaderTest to use new syntax (no `as`)
119+
- Added test for import within domains
120+
- Added test for path resolution across imports (validates imported type reference)
123121

124-
**Files to modify:**
122+
**Files modified:**
125123
- `bast/jvm/src/test/scala/com/ossuminc/riddl/bast/BASTLoaderTest.scala`
126124

127125
---
@@ -133,8 +131,8 @@ Phase 3 (serialization/deserialization) is fully working. Phase 4 (import integr
133131
| BASTWriterSpec | 7 | ✅ All passing |
134132
| BASTRoundTripTest | 3 | ✅ All passing |
135133
| BASTPerformanceTest | 4 | ✅ All passing |
136-
| BASTLoaderTest | 4 | ✅ All passing |
137-
| **Total** | **18** |**All passing** |
134+
| BASTLoaderTest | 5 | ✅ All passing |
135+
| **Total** | **19** |**All passing** |
138136

139137
---
140138

@@ -188,15 +186,17 @@ d1de8107 Complete BAST Phase 3: Fix Repository/Schema tag collision
188186

189187
**Phase 2 Complete**: Core serialization working for all node types
190188
**Phase 3 Complete**: Deserialization working with full round-trip verification
191-
🚧 **Phase 4 In Progress**: Import integration
192-
- ✅ Initial syntax parsing (`import "x.bast" as y`)
193-
- ✅ BASTLoader utility created
194-
- ✅ Tests for loading functionality
195-
- ⏳ Simplify syntax (remove `as namespace`)
196-
- ⏳ Support import in domains
197-
- ⏳ Update resolution pass
198-
199-
**Next Action**: Step 1 - Simplify import syntax by removing `as namespace` clause
189+
**Phase 4 Complete**: Import integration fully working!
190+
- ✅ Simplified syntax: `import "x.bast"` (no namespace clause)
191+
- ✅ BASTLoader utility loads imports and populates contents
192+
- ✅ Imports supported at root level AND inside domains
193+
- ✅ Path resolution works: `ImportedDomain.SomeType` resolves correctly
194+
- ✅ 5 comprehensive tests for import functionality
195+
196+
**Next Steps** (Future work):
197+
- Add `riddlc bast-gen` command to generate BAST from RIDDL
198+
- Consider duplicate definition error detection
199+
- Performance benchmarking (parse RIDDL vs load BAST)
200200

201201
---
202202

bast/jvm/src/test/scala/com/ossuminc/riddl/bast/BASTLoaderTest.scala

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,5 +287,94 @@ class BASTLoaderTest extends AnyWordSpec {
287287
}
288288
}
289289
}
290+
291+
"resolve references to imported types" in { (td: TestData) =>
292+
// Create a RIDDL source with a reusable type
293+
val libraryRiddl = """domain TypeLibrary is {
294+
| type UserId is UUID
295+
| briefly "Reusable type definitions"
296+
|}
297+
|""".stripMargin
298+
299+
// Parse and convert to BAST
300+
val libInput = RiddlParserInput(libraryRiddl, "test-library")
301+
val libResult = TopLevelParser.parseInput(libInput, withVerboseFailures = true)
302+
303+
libResult match {
304+
case Left(messages) =>
305+
fail(s"Library parse failed: ${messages.format}")
306+
307+
case Right(libRoot: Root) =>
308+
// Write to BAST
309+
val passInput = PassInput(libRoot)
310+
val writerResult = Pass.runThesePasses(passInput, Seq(BASTWriter.creator()))
311+
val output = writerResult.outputOf[BASTOutput](BASTWriter.name).get
312+
313+
val tempDir = Files.createTempDirectory("bast-resolution-test")
314+
val bastFile = tempDir.resolve("types.bast")
315+
Files.write(bastFile, output.bytes)
316+
317+
try {
318+
// Create a RIDDL file that imports and USES the type
319+
val riddlContent = s"""import "${bastFile.toAbsolutePath}"
320+
|
321+
|domain MyApp is {
322+
| context Users is {
323+
| // Reference the imported type
324+
| type LocalUserId is TypeLibrary.UserId
325+
| briefly "User context"
326+
| }
327+
| briefly "Application domain"
328+
|}
329+
|""".stripMargin
330+
331+
val rpi = RiddlParserInput(riddlContent, "test-resolution")
332+
val parseResult = TopLevelParser.parseInput(rpi, withVerboseFailures = true)
333+
334+
parseResult match {
335+
case Left(messages) =>
336+
fail(s"Parse failed: ${messages.format}")
337+
338+
case Right(parsedRoot: Root) =>
339+
// Load the BAST imports first
340+
val baseURL = URL.fromCwdPath(".")
341+
val loadResult = BASTLoader.loadImports(parsedRoot, baseURL)
342+
assert(loadResult.failedCount == 0,
343+
s"Import load failed: ${loadResult.messages.map(_.format).mkString("; ")}")
344+
345+
// Now run validation passes to check if resolution works
346+
// The resolution pass should find TypeLibrary.UserId
347+
import com.ossuminc.riddl.passes.{PassesResult, Riddl}
348+
349+
Riddl.validate(parsedRoot) match {
350+
case Left(parseErrors) =>
351+
fail(s"Validation failed during parsing: ${parseErrors.map(_.format).mkString("; ")}")
352+
353+
case Right(passesResult) =>
354+
val allMessages = passesResult.messages
355+
356+
// Check for resolution errors related to our reference
357+
val resolutionErrors = allMessages.filter { msg =>
358+
msg.format.contains("TypeLibrary") || msg.format.contains("UserId")
359+
}
360+
361+
// Print any errors for debugging
362+
if resolutionErrors.nonEmpty then
363+
println(s"Resolution-related messages: ${resolutionErrors.map(_.format).mkString("\n")}")
364+
end if
365+
366+
// The test passes if there are no errors about unresolved TypeLibrary.UserId
367+
// Note: There may be other validation warnings, but resolution should work
368+
val unresolvedErrors = resolutionErrors.filter(_.kind.isError)
369+
assert(unresolvedErrors.isEmpty,
370+
s"Found unresolved reference errors: ${unresolvedErrors.map(_.format).mkString("\n")}")
371+
}
372+
}
373+
} finally {
374+
Files.deleteIfExists(bastFile)
375+
Files.deleteIfExists(tempDir)
376+
}
377+
}
378+
}
290379
}
291380
}

0 commit comments

Comments
 (0)