Skip to content

Commit 81a7b63

Browse files
mattgodboltclaude
andcommitted
Fix SourceMapping validation to handle optional fields
Make file and column fields optional in SourceMapping to handle real compiler output where some assembly lines have missing column information or include file references. Add comprehensive tests for various source mapping scenarios. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 96e79dc commit 81a7b63

File tree

3 files changed

+80
-2
lines changed

3 files changed

+80
-2
lines changed

app/explain_api.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@
1010
class SourceMapping(BaseModel):
1111
"""Source code mapping for assembly lines."""
1212

13+
file: str | None = None
1314
line: int
14-
column: int
15+
column: int | None = None
1516

1617

1718
class LabelRange(BaseModel):

app/explain_test.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,3 +349,80 @@ def test_request_validation_invalid_assembly_item(self):
349349

350350
with pytest.raises(ValueError):
351351
ExplainRequest.model_validate(request_data)
352+
353+
def test_source_mapping_optional_fields(self):
354+
"""Test that SourceMapping handles optional file and column fields."""
355+
# Test with all fields present
356+
source_full = SourceMapping(file="test.c", line=10, column=5)
357+
assert source_full.file == "test.c"
358+
assert source_full.line == 10
359+
assert source_full.column == 5
360+
361+
# Test with only required line field
362+
source_minimal = SourceMapping(line=10)
363+
assert source_minimal.file is None
364+
assert source_minimal.line == 10
365+
assert source_minimal.column is None
366+
367+
# Test with file but no column (like in your legitimate document)
368+
source_no_column = SourceMapping(file=None, line=0)
369+
assert source_no_column.file is None
370+
assert source_no_column.line == 0
371+
assert source_no_column.column is None
372+
373+
def test_assembly_item_with_source_variations(self):
374+
"""Test AssemblyItem with different source mapping variations."""
375+
# Assembly with full source info
376+
asm_full = AssemblyItem(text="mov eax, edi", source=SourceMapping(file="test.c", line=5, column=10))
377+
assert asm_full.source.file == "test.c"
378+
assert asm_full.source.line == 5
379+
assert asm_full.source.column == 10
380+
381+
# Assembly with minimal source info (just line)
382+
asm_minimal = AssemblyItem(text="ret", source=SourceMapping(line=0))
383+
assert asm_minimal.source.file is None
384+
assert asm_minimal.source.line == 0
385+
assert asm_minimal.source.column is None
386+
387+
# Assembly with no source info
388+
asm_no_source = AssemblyItem(text="label:")
389+
assert asm_no_source.source is None
390+
391+
def test_legitimate_document_validation(self):
392+
"""Test validation with the legitimate document structure that was failing."""
393+
# This represents the structure from your legitimate document
394+
request_data = {
395+
"language": "ispc",
396+
"compiler": "ispc 1.25.3",
397+
"code": "// Test code",
398+
"compilationOptions": ["--target=avx2-i32x8", "-g"],
399+
"instructionSet": "amd64",
400+
"asm": [
401+
{"text": "square_even___vyi:", "source": None, "labels": []},
402+
{
403+
"text": " vblendvps ymm0, ymm0, ymm2, ymm3",
404+
"source": {"file": None, "line": 6, "column": 16},
405+
"labels": [],
406+
},
407+
{
408+
"text": " ret",
409+
"source": {"file": None, "line": 0}, # Missing column field
410+
"labels": [],
411+
},
412+
],
413+
}
414+
415+
# This should not raise a validation error
416+
request = ExplainRequest.model_validate(request_data)
417+
assert request.language == "ispc"
418+
assert request.compiler == "ispc 1.25.3"
419+
assert len(request.asm) == 3
420+
421+
# Check the source mappings
422+
assert request.asm[0].source is None
423+
assert request.asm[1].source.file is None
424+
assert request.asm[1].source.line == 6
425+
assert request.asm[1].source.column == 16
426+
assert request.asm[2].source.file is None
427+
assert request.asm[2].source.line == 0
428+
assert request.asm[2].source.column is None # This was the missing field

claude_explain.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ The service will accept POST requests with JSON bodies containing a subset of th
5252
"text": " cmp edi, 1",
5353
"source": {
5454
"line": 2, // Source line number
55-
"column": 6 // Source column number
55+
"column": 6 // Source column number (optional)
5656
},
5757
"labels": []
5858
},

0 commit comments

Comments
 (0)