Ver código fonte

Fix error message for missing override defined in different file

Signed-off-by: Sean Young <sean@mess.org>
Sean Young 4 anos atrás
pai
commit
232b4c90a7

+ 1 - 1
src/parser/mod.rs

@@ -88,7 +88,7 @@ mod test {
         let a = SourceUnit(vec![SourceUnitPart::ContractDefinition(Box::new(
             ContractDefinition {
                 doc: vec![],
-                loc: Loc(0, 0, 325),
+                loc: Loc(0, 0, 13),
                 ty: ContractTy::Contract(Loc(0, 0, 8)),
                 name: Identifier {
                     loc: Loc(0, 9, 12),

+ 2 - 2
src/parser/solidity.lalrpop

@@ -168,8 +168,8 @@ Base: Base = {
 }
 
 ContractDefinition: Box<ContractDefinition> = {
-    <doc:DocComments> <l:@L> <ty:ContractTy> <name:Identifier> <base:Bases>
-    "{" <parts:(<ContractPart>)*> "}" <r:@R> => {
+    <doc:DocComments> <l:@L> <ty:ContractTy> <name:Identifier> <base:Bases> <r:@R>
+    "{" <parts:(<ContractPart>)*> "}" => {
         Box::new(ContractDefinition{doc, loc: Loc(file_no, l, r), ty, name, base, parts})
     }
 }

+ 27 - 27
src/parser/solidity.rs

@@ -1,5 +1,5 @@
 // auto-generated: "lalrpop 0.19.1"
-// sha256: b4ebd3a9fc2db0b519691bda3845e4ffc25268e7429f2e715bb4bd9a87b72
+// sha256: c1a758427bd0bd88a580a61f4a19cb7d57b966a8fb335e8e9b2170878113d21d
 use std::str::FromStr;
 use num_bigint::BigInt;
 use num_bigint::BigUint;
@@ -14402,10 +14402,10 @@ fn __action59<
     (_, ty, _): (usize, ContractTy, usize),
     (_, name, _): (usize, Identifier, usize),
     (_, base, _): (usize, Vec<Base>, usize),
+    (_, r, _): (usize, usize, usize),
     (_, _, _): (usize, Token<'input>, usize),
     (_, parts, _): (usize, ::std::vec::Vec<ContractPart>, usize),
     (_, _, _): (usize, Token<'input>, usize),
-    (_, r, _): (usize, usize, usize),
 ) -> Box<ContractDefinition>
 {
     {
@@ -20077,13 +20077,13 @@ fn __action391<
     __2: (usize, ContractTy, usize),
     __3: (usize, Identifier, usize),
     __4: (usize, Vec<Base>, usize),
-    __5: (usize, Token<'input>, usize),
+    __5: (usize, usize, usize),
     __6: (usize, Token<'input>, usize),
-    __7: (usize, usize, usize),
+    __7: (usize, Token<'input>, usize),
 ) -> Box<ContractDefinition>
 {
-    let __start0 = __5.2.clone();
-    let __end0 = __6.0.clone();
+    let __start0 = __6.2.clone();
+    let __end0 = __7.0.clone();
     let __temp0 = __action261(
         input,
         file_no,
@@ -20100,8 +20100,8 @@ fn __action391<
         __3,
         __4,
         __5,
-        __temp0,
         __6,
+        __temp0,
         __7,
     )
 }
@@ -20117,18 +20117,18 @@ fn __action392<
     __2: (usize, ContractTy, usize),
     __3: (usize, Identifier, usize),
     __4: (usize, Vec<Base>, usize),
-    __5: (usize, Token<'input>, usize),
-    __6: (usize, ::std::vec::Vec<ContractPart>, usize),
-    __7: (usize, Token<'input>, usize),
-    __8: (usize, usize, usize),
+    __5: (usize, usize, usize),
+    __6: (usize, Token<'input>, usize),
+    __7: (usize, ::std::vec::Vec<ContractPart>, usize),
+    __8: (usize, Token<'input>, usize),
 ) -> Box<ContractDefinition>
 {
-    let __start0 = __6.0.clone();
-    let __end0 = __6.2.clone();
+    let __start0 = __7.0.clone();
+    let __end0 = __7.2.clone();
     let __temp0 = __action262(
         input,
         file_no,
-        __6,
+        __7,
     );
     let __temp0 = (__start0, __temp0, __end0);
     __action59(
@@ -20140,8 +20140,8 @@ fn __action392<
         __3,
         __4,
         __5,
+        __6,
         __temp0,
-        __7,
         __8,
     )
 }
@@ -21004,9 +21004,9 @@ fn __action415<
     __1: (usize, ContractTy, usize),
     __2: (usize, Identifier, usize),
     __3: (usize, Vec<Base>, usize),
-    __4: (usize, Token<'input>, usize),
+    __4: (usize, usize, usize),
     __5: (usize, Token<'input>, usize),
-    __6: (usize, usize, usize),
+    __6: (usize, Token<'input>, usize),
 ) -> Box<ContractDefinition>
 {
     let __start0 = __0.2.clone();
@@ -21042,10 +21042,10 @@ fn __action416<
     __1: (usize, ContractTy, usize),
     __2: (usize, Identifier, usize),
     __3: (usize, Vec<Base>, usize),
-    __4: (usize, Token<'input>, usize),
-    __5: (usize, ::std::vec::Vec<ContractPart>, usize),
-    __6: (usize, Token<'input>, usize),
-    __7: (usize, usize, usize),
+    __4: (usize, usize, usize),
+    __5: (usize, Token<'input>, usize),
+    __6: (usize, ::std::vec::Vec<ContractPart>, usize),
+    __7: (usize, Token<'input>, usize),
 ) -> Box<ContractDefinition>
 {
     let __start0 = __0.2.clone();
@@ -25694,8 +25694,8 @@ fn __action560<
     __5: (usize, Token<'input>, usize),
 ) -> Box<ContractDefinition>
 {
-    let __start0 = __5.2.clone();
-    let __end0 = __5.2.clone();
+    let __start0 = __3.2.clone();
+    let __end0 = __4.0.clone();
     let __temp0 = __action283(
         input,
         file_no,
@@ -25710,9 +25710,9 @@ fn __action560<
         __1,
         __2,
         __3,
+        __temp0,
         __4,
         __5,
-        __temp0,
     )
 }
 
@@ -25731,8 +25731,8 @@ fn __action561<
     __6: (usize, Token<'input>, usize),
 ) -> Box<ContractDefinition>
 {
-    let __start0 = __6.2.clone();
-    let __end0 = __6.2.clone();
+    let __start0 = __3.2.clone();
+    let __end0 = __4.0.clone();
     let __temp0 = __action283(
         input,
         file_no,
@@ -25747,10 +25747,10 @@ fn __action561<
         __1,
         __2,
         __3,
+        __temp0,
         __4,
         __5,
         __6,
-        __temp0,
     )
 }
 

+ 15 - 4
src/sema/contracts.rs

@@ -594,16 +594,27 @@ fn layout_contract(contract_no: usize, ns: &mut ast::Namespace) {
 
         // virtual functions without a body
         if list.len() == 1 {
+            let loc = ns.contracts[contract_no].loc;
             match func.ty {
                 pt::FunctionTy::Fallback | pt::FunctionTy::Receive => {
-                    ns.diagnostics.push(ast::Diagnostic::error(
+                    ns.diagnostics.push(ast::Diagnostic::error_with_note(
+                        loc,
+                        format!(
+                            "contract ‘{}’ missing override for ‘{}’ function",
+                            ns.contracts[contract_no].name, func.ty
+                        ),
                         func.loc,
-                        format!("missing override for ‘{}’ function", func.ty),
+                        format!("declaration of ‘{}’ function", func.ty),
                     ));
                 }
-                _ => ns.diagnostics.push(ast::Diagnostic::error(
+                _ => ns.diagnostics.push(ast::Diagnostic::error_with_note(
+                    loc,
+                    format!(
+                        "contract ‘{}’ missing override for function ‘{}’",
+                        ns.contracts[contract_no].name, func.name
+                    ),
                     func.loc,
-                    format!("missing override for function ‘{}’", func.name),
+                    format!("declaration of function ‘{}’", func.name),
                 )),
             }
 

+ 18 - 32
src/sema/diagnostics.rs

@@ -2,7 +2,6 @@ use super::ast::{Diagnostic, ErrorType, Level, Namespace, Note};
 use crate::file_cache::FileCache;
 use crate::parser::pt::Loc;
 use serde::Serialize;
-use std::path::PathBuf;
 
 impl Level {
     pub fn to_string(&self) -> &'static str {
@@ -132,13 +131,10 @@ impl Diagnostic {
         }
     }
 
-    fn formated_message(
-        &self,
-        filename: &PathBuf,
-        offset_converter: &OffsetToLineColumn,
-    ) -> String {
+    fn formated_message(&self, offset_converter: &[OffsetToLineColumn], ns: &Namespace) -> String {
         let mut s = if let Some(pos) = self.pos {
-            let loc = offset_converter.to_string(pos);
+            let loc = offset_converter[pos.0].to_string(pos);
+            let filename = &ns.files[pos.0];
 
             format!(
                 "{}:{}: {}: {}",
@@ -152,7 +148,8 @@ impl Diagnostic {
         };
 
         for note in &self.notes {
-            let loc = offset_converter.to_string(note.pos);
+            let loc = offset_converter[note.pos.0].to_string(note.pos);
+            let filename = &ns.files[note.pos.0];
 
             s.push_str(&format!(
                 "\n\t{}:{}: {}: {}",
@@ -168,25 +165,18 @@ impl Diagnostic {
 }
 
 pub fn print_messages(cache: &mut FileCache, ns: &Namespace, debug: bool) {
-    let mut current_file_no = None;
-    let mut offset_converter = OffsetToLineColumn(Vec::new());
-    let mut filename = &PathBuf::new();
+    let offset_converter: Vec<OffsetToLineColumn> = ns
+        .files
+        .iter()
+        .map(|filename| OffsetToLineColumn::new(&*cache.get_file_contents(filename)))
+        .collect();
 
     for msg in &ns.diagnostics {
         if !debug && msg.level == Level::Debug {
             continue;
         }
 
-        let file_no = msg.pos.map(|pos| pos.0);
-
-        if file_no != current_file_no {
-            filename = &ns.files[file_no.unwrap()];
-
-            offset_converter = OffsetToLineColumn::new(&*cache.get_file_contents(filename));
-            current_file_no = file_no;
-        }
-
-        eprintln!("{}", msg.formated_message(filename, &offset_converter));
+        eprintln!("{}", msg.formated_message(&offset_converter, ns));
     }
 }
 
@@ -217,9 +207,11 @@ pub struct OutputJson {
 pub fn message_as_json(cache: &mut FileCache, ns: &Namespace) -> Vec<OutputJson> {
     let mut json = Vec::new();
 
-    let mut current_file_no = None;
-    let mut offset_converter = OffsetToLineColumn(Vec::new());
-    let mut filename = &PathBuf::new();
+    let offset_converter: Vec<OffsetToLineColumn> = ns
+        .files
+        .iter()
+        .map(|filename| OffsetToLineColumn::new(&*cache.get_file_contents(filename)))
+        .collect();
 
     for msg in &ns.diagnostics {
         if msg.level == Level::Info {
@@ -227,13 +219,7 @@ pub fn message_as_json(cache: &mut FileCache, ns: &Namespace) -> Vec<OutputJson>
         }
 
         let file_no = msg.pos.map(|pos| pos.0);
-
-        if file_no != current_file_no {
-            filename = &ns.files[file_no.unwrap()];
-
-            offset_converter = OffsetToLineColumn::new(&*cache.get_file_contents(filename));
-            current_file_no = file_no;
-        }
+        let filename = &ns.files[file_no.unwrap()];
 
         let loc_json = if let Some(pos) = msg.pos {
             Some(LocJson {
@@ -251,7 +237,7 @@ pub fn message_as_json(cache: &mut FileCache, ns: &Namespace) -> Vec<OutputJson>
             component: "general".to_owned(),
             severity: msg.level.to_string().to_owned(),
             message: msg.message.to_owned(),
-            formattedMessage: msg.formated_message(filename, &offset_converter),
+            formattedMessage: msg.formated_message(&offset_converter, ns),
         });
     }
 

+ 1 - 1
tests/substrate_tests/inheritance.rs

@@ -1140,7 +1140,7 @@ fn test_override() {
 
     assert_eq!(
         first_error(ns.diagnostics),
-        "missing override for function ‘bar’"
+        "contract ‘a’ missing override for function ‘bar’"
     );
 
     let ns = parse_and_resolve(