11module builder
22
33import os
4+ import crypto.sha256
45import v.pref
56
67fn restore_env_var (name string , old_value ? string ) {
@@ -329,7 +330,7 @@ fn test_external_v3_report_env_round_trip() {
329330 assert v_source.contains (c_error_v_source_truncation_notice)
330331 // The path-based extractor must never reopen an internal-error input after V3 fails.
331332 late_file , late_source := bounded_v3_fallback_source (external_v3_ compiler_error_kind,
332- 'error: v3 failed' , c_file, [] )
333+ 'error: v3 failed' , c_file, map [ string ] string {} )
333334 assert late_file == ''
334335 assert late_source == ''
335336 // ...then forwards only that content; export reads no path and deletes no directory.
@@ -629,7 +630,9 @@ fn test_bounded_v3_fallback_source_maps_generated_c_error() {
629630 os.write_file (generated_c, '#line 100 "${v_path }"\n int a = 1;\n int b = missing;\n ' )!
630631 c_output := '${generated_c }:3:9: error: use of undeclared identifier missing'
631632 // kind '' selects the generated-C mapping path.
632- v_file , v_source := bounded_v3_fallback_source ('' , c_output, generated_c, [v_path])
633+ v_file , v_source := bounded_v3_fallback_source ('' , c_output, generated_c, {
634+ v_path: sha256 .hexhash (whole)
635+ })
633636 assert v_file == 'source.v'
634637 assert v_source != ''
635638 // A bounded strict subset centered on the mapped V line (~100), never the whole file.
@@ -654,11 +657,14 @@ fn test_bounded_v3_fallback_source_rejects_nonblank_whole_file_generated_c() {
654657 lines << 'fn f${i }() { println(${i }) }'
655658 }
656659 // 80 substantive lines plus a whitespace-only final line (81 lines total).
657- os.write_file (v_path, lines.join ('\n ' ) + '\n ' )!
660+ whole := lines.join ('\n ' ) + '\n '
661+ os.write_file (v_path, whole)!
658662 generated_c := os.join_path (dir, 'program.tmp.c' )
659663 os.write_file (generated_c, '#line 40 "${v_path }"\n int b = missing;\n ' )!
660664 c_output := '${generated_c }:2:9: error: use of undeclared identifier missing'
661- v_file , v_source := bounded_v3_fallback_source ('' , c_output, generated_c, [v_path])
665+ v_file , v_source := bounded_v3_fallback_source ('' , c_output, generated_c, {
666+ v_path: sha256 .hexhash (whole)
667+ })
662668 assert v_file == 'source.v'
663669 // The mapped window exposes every nonblank line, so no source is uploaded.
664670 assert v_source == '' , v_source
@@ -681,13 +687,40 @@ fn test_bounded_v3_fallback_source_rejects_unparsed_mapped_file() {
681687 generated_c := os.join_path (dir, 'program.tmp.c' )
682688 os.write_file (generated_c, '#line 1 "${unrelated_path }"\n int exposed = missing;\n ' )!
683689 c_output := '${generated_c }:2:15: error: use of undeclared identifier missing'
684- v_file , v_source := bounded_v3_fallback_source ('' , c_output, generated_c, [
685- parsed_path,
686- ] )
690+ v_file , v_source := bounded_v3_fallback_source ('' , c_output, generated_c, {
691+ parsed_path: sha 256 . hexhash (os. read_file (parsed_path) ! )
692+ } )
687693 assert v_file == ''
688694 assert v_source == ''
689695}
690696
697+ fn test_bounded_v3_fallback_source_rejects_changed_parsed_source () {
698+ dir := os.join_path (os.vtmp_dir (), 'v3_gen_c_changed_${os .getpid ()}' )
699+ os.rmdir_all (dir) or {}
700+ os.mkdir_all (dir) or { panic (err) }
701+ defer {
702+ os.rmdir_all (dir) or {}
703+ }
704+ v_path := os.join_path (dir, 'source.v' )
705+ mut original_lines := []string {}
706+ for i in 0 .. 200 {
707+ original_lines << 'fn original_${i }() { println(${i }) }'
708+ }
709+ original := original_lines.join ('\n ' )
710+ os.write_file (v_path, original)!
711+ parsed_digest := sha256 .hexhash (original)
712+ generated_c := os.join_path (dir, 'program.tmp.c' )
713+ os.write_file (generated_c, '#line 100 "${v_path }"\n int b = missing;\n ' )!
714+ // Simulate an editor/build watcher replacing the mapped input after V3 parsed it.
715+ os.write_file (v_path, original.replace ('original_' , 'new_private_' ))!
716+ c_output := '${generated_c }:2:9: error: use of undeclared identifier missing'
717+ v_file , v_source := bounded_v3_fallback_source ('' , c_output, generated_c, {
718+ v_path: parsed_digest
719+ })
720+ assert v_file == 'source.v'
721+ assert v_source == ''
722+ }
723+
691724fn test_generated_c_reset_line_is_not_reported_as_v_source () {
692725 c_lines := [
693726 '#line 40 "/tmp/program.tmp.c"' ,
0 commit comments