compiler: fix line numbers in unused variable error messages
							parent
							
								
									f657d70a67
								
							
						
					
					
						commit
						f042dfb861
					
				|  | @ -195,6 +195,7 @@ fn (p mut Parser) fn_decl() { | |||
| 			ref: is_amp | ||||
| 			ptr: is_mut | ||||
| 			line_nr: p.scanner.line_nr | ||||
| 			scanner_pos: p.scanner.get_scanner_pos() | ||||
| 		} | ||||
| 		f.args << receiver | ||||
| 		f.register_var(receiver) | ||||
|  | @ -539,17 +540,11 @@ fn (p mut Parser) check_unused_variables() { | |||
| 			break | ||||
| 		} | ||||
| 		if !var.is_used && !p.pref.is_repl && !var.is_arg && !p.pref.translated && var.name != '_' { | ||||
| 			p.scanner.line_nr = var.line_nr - 1 | ||||
| 			if p.pref.is_prod { | ||||
| 				p.error('`$var.name` declared and not used') | ||||
| 			} else { | ||||
| 				p.warn('`$var.name` declared and not used') | ||||
| 			} | ||||
| 			p.production_error('`$var.name` declared and not used', var.scanner_pos ) | ||||
| 		} | ||||
| 	if !var.is_changed && var.is_mut && !p.pref.is_repl && | ||||
|  !p.pref.translated && var.name != '_' { | ||||
| 			p.scanner.line_nr = var.line_nr - 1 | ||||
| 			p.error('`$var.name` is declared as mutable, but it was never changed') | ||||
| 		if !var.is_changed && var.is_mut && !p.pref.is_repl && | ||||
| 			!p.pref.translated && var.name != '_' { | ||||
| 			p.error_with_position( '`$var.name` is declared as mutable, but it was never changed', var.scanner_pos ) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | @ -723,6 +718,7 @@ fn (p mut Parser) fn_args(f mut Fn) { | |||
| 				is_arg: true | ||||
| 				// is_mut: is_mut
 | ||||
| 				line_nr: p.scanner.line_nr | ||||
| 				scanner_pos: p.scanner.get_scanner_pos()         | ||||
| 			} | ||||
| 			// f.register_var(v)
 | ||||
| 			f.args << v | ||||
|  | @ -766,6 +762,7 @@ fn (p mut Parser) fn_args(f mut Fn) { | |||
| 				is_mut: is_mut | ||||
| 				ptr: is_mut | ||||
| 				line_nr: p.scanner.line_nr | ||||
| 				scanner_pos: p.scanner.get_scanner_pos()         | ||||
| 			} | ||||
| 			f.register_var(v) | ||||
| 			f.args << v | ||||
|  |  | |||
|  | @ -774,6 +774,25 @@ fn (p &Parser) warn(s string) { | |||
| 	println('warning: $p.scanner.file_path:${p.scanner.line_nr+1}: $s') | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| fn (p mut Parser) error_with_position(e string, sp ScannerPos) { | ||||
| 	p.scanner.goto_scanner_position( sp ) | ||||
| 	p.error( e ) | ||||
| } | ||||
| 
 | ||||
| fn (p mut Parser) production_error(e string, sp ScannerPos) { | ||||
| 	if p.pref.is_prod { | ||||
| 		p.scanner.goto_scanner_position( sp ) | ||||
| 		p.error( e ) | ||||
| 	}else { | ||||
| 		// on a warning, restore the scanner state after printing the warning:
 | ||||
| 		cpos := p.scanner.get_scanner_pos() | ||||
| 		p.scanner.goto_scanner_position( sp ) | ||||
| 		p.warn(e) | ||||
| 		p.scanner.goto_scanner_position( cpos ) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (p mut Parser) error(s string) { | ||||
| 	// Dump all vars and types for debugging
 | ||||
| 	if p.pref.is_debug { | ||||
|  | @ -1301,6 +1320,7 @@ fn (p mut Parser) var_decl() { | |||
| 		p.fspace() | ||||
| 	} | ||||
| 	// println('var decl tok=${p.strtok()} ismut=$is_mut')
 | ||||
| 	var_scanner_pos := p.scanner.get_scanner_pos() | ||||
| 	name := p.check_name() | ||||
| 	p.var_decl_name = name | ||||
| 	// Don't allow declaring a variable with the same name. Even in a child scope
 | ||||
|  | @ -1319,6 +1339,8 @@ fn (p mut Parser) var_decl() { | |||
| 		typ: typ | ||||
| 		is_mut: is_mut | ||||
| 		is_alloc: p.is_alloc || typ.starts_with('array_') | ||||
| 		scanner_pos: var_scanner_pos | ||||
| 		line_nr: var_scanner_pos.line_nr | ||||
| 	}) | ||||
| 	//if p.is_alloc { println('REG VAR IS ALLOC $name') }
 | ||||
| 	p.var_decl_name = '' | ||||
|  | @ -3571,8 +3593,8 @@ fn (p mut Parser) go_statement() { | |||
| 
 | ||||
| fn (p mut Parser) register_var(v Var) { | ||||
| 	if v.line_nr == 0 { | ||||
| 		//v.line_nr = p.scanner.line_nr
 | ||||
| 		p.cur_fn.register_var({ v | line_nr: p.scanner.line_nr }) | ||||
| 		spos := p.scanner.get_scanner_pos() | ||||
| 		p.cur_fn.register_var({ v | scanner_pos: spos, line_nr: spos.line_nr }) | ||||
| 	} else { | ||||
| 		p.cur_fn.register_var(v) | ||||
| 	} | ||||
|  |  | |||
|  | @ -61,6 +61,24 @@ fn new_scanner(file_path string) &Scanner { | |||
| 	return scanner | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| struct ScannerPos { | ||||
| mut: | ||||
|    pos int | ||||
|    line_nr int | ||||
| } | ||||
| fn (s ScannerPos) str() string { | ||||
| 	return 'ScannerPos{ ${s.pos:5d} , ${s.line_nr:5d} }' | ||||
| } | ||||
| fn (s &Scanner) get_scanner_pos() ScannerPos { | ||||
| 	return ScannerPos{ pos: s.pos line_nr: s.line_nr }  | ||||
| } | ||||
| fn (s mut Scanner) goto_scanner_position(scp ScannerPos) { | ||||
| 	s.pos = scp.pos  | ||||
| 	s.line_nr = scp.line_nr | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // TODO remove once multiple return values are implemented
 | ||||
| struct ScanRes { | ||||
| 	tok Token | ||||
|  |  | |||
|  | @ -71,7 +71,6 @@ mut: | |||
| 	ref             bool | ||||
| 	parent_fn       string // Variables can only be defined in functions
 | ||||
| 	mod             string // module where this var is stored
 | ||||
| 	line_nr         int | ||||
| 	access_mod      AccessMod | ||||
| 	is_global       bool // __global (translated from C only)
 | ||||
| 	is_used         bool | ||||
|  | @ -79,6 +78,8 @@ mut: | |||
| 	scope_level     int | ||||
| 	is_c            bool // todo remove once `typ` is `Type`, not string
 | ||||
| 	moved           bool | ||||
| 	scanner_pos     ScannerPos // TODO: use only scanner_pos, remove line_nr
 | ||||
| 	line_nr         int | ||||
| } | ||||
| 
 | ||||
| struct Type { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue