Explorar el Código

Improve error message on stray semicolon

struct and enums definitions should not be followed by a semicolon, but
I often type one. Give a nicer error message by parsing for this case.

Signed-off-by: Sean Young <sean@mess.org>
Sean Young hace 5 años
padre
commit
dff6635be9
Se han modificado 5 ficheros con 582 adiciones y 544 borrados
  1. 2 0
      src/parser/pt.rs
  2. 2 0
      src/parser/solidity.lalrpop
  3. 548 544
      src/parser/solidity.rs
  4. 19 0
      src/sema/mod.rs
  5. 11 0
      tests/substrate_tests/functions.rs

+ 2 - 0
src/parser/pt.rs

@@ -30,6 +30,7 @@ pub enum SourceUnitPart {
     EventDefinition(Box<EventDefinition>),
     EventDefinition(Box<EventDefinition>),
     FunctionDefinition(Box<FunctionDefinition>),
     FunctionDefinition(Box<FunctionDefinition>),
     VariableDefinition(Box<VariableDefinition>),
     VariableDefinition(Box<VariableDefinition>),
+    StraySemicolon(Loc),
 }
 }
 
 
 #[derive(Debug, PartialEq)]
 #[derive(Debug, PartialEq)]
@@ -128,6 +129,7 @@ pub enum ContractPart {
     EnumDefinition(Box<EnumDefinition>),
     EnumDefinition(Box<EnumDefinition>),
     VariableDefinition(Box<VariableDefinition>),
     VariableDefinition(Box<VariableDefinition>),
     FunctionDefinition(Box<FunctionDefinition>),
     FunctionDefinition(Box<FunctionDefinition>),
+    StraySemicolon(Loc),
     Using(Box<Using>),
     Using(Box<Using>),
 }
 }
 
 

+ 2 - 0
src/parser/solidity.lalrpop

@@ -24,6 +24,7 @@ SourceUnitPart: SourceUnitPart = {
     EventDefinition => SourceUnitPart::EventDefinition(<>),
     EventDefinition => SourceUnitPart::EventDefinition(<>),
     FunctionDefinition => SourceUnitPart::FunctionDefinition(<>),
     FunctionDefinition => SourceUnitPart::FunctionDefinition(<>),
     VariableDefinition => SourceUnitPart::VariableDefinition(<>),
     VariableDefinition => SourceUnitPart::VariableDefinition(<>),
+    <l:@L> ";" <r:@R> => SourceUnitPart::StraySemicolon(Loc(file_no, l, r)),
 }
 }
 
 
 ImportDirective: Import = {
 ImportDirective: Import = {
@@ -149,6 +150,7 @@ ContractPart: ContractPart = {
     FunctionDefinition => ContractPart::FunctionDefinition(<>),
     FunctionDefinition => ContractPart::FunctionDefinition(<>),
     ModifierDefinition => ContractPart::FunctionDefinition(<>),
     ModifierDefinition => ContractPart::FunctionDefinition(<>),
     ConstructorDefinition => ContractPart::FunctionDefinition(<>),
     ConstructorDefinition => ContractPart::FunctionDefinition(<>),
+    <l:@L> ";" <r:@R> => ContractPart::StraySemicolon(Loc(file_no, l, r)),
     Using => ContractPart::Using(<>),
     Using => ContractPart::Using(<>),
 }
 }
 
 

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 548 - 544
src/parser/solidity.rs


+ 19 - 0
src/sema/mod.rs

@@ -115,6 +115,25 @@ pub fn sema(file: ResolvedFile, cache: &mut FileCache, ns: &mut ast::Namespace)
         let _ = statements::resolve_function_body(func, file_no, None, func_no, ns);
         let _ = statements::resolve_function_body(func, file_no, None, func_no, ns);
     }
     }
 
 
+    // check for stray semi colons
+    for part in &pt.0 {
+        match part {
+            pt::SourceUnitPart::StraySemicolon(loc) => {
+                ns.diagnostics
+                    .push(ast::Diagnostic::error(*loc, "stray semicolon".to_string()));
+            }
+            pt::SourceUnitPart::ContractDefinition(contract) => {
+                for part in &contract.parts {
+                    if let pt::ContractPart::StraySemicolon(loc) = part {
+                        ns.diagnostics
+                            .push(ast::Diagnostic::error(*loc, "stray semicolon".to_string()));
+                    }
+                }
+            }
+            _ => (),
+        }
+    }
+
     // now check state mutability for all contracts
     // now check state mutability for all contracts
     mutability::mutablity(file_no, ns);
     mutability::mutablity(file_no, ns);
 }
 }

+ 11 - 0
tests/substrate_tests/functions.rs

@@ -1205,3 +1205,14 @@ fn return_not_returns() {
         "‘return’ unexpected. Did you mean ‘returns’?"
         "‘return’ unexpected. Did you mean ‘returns’?"
     );
     );
 }
 }
+
+#[test]
+fn stray_semicolon() {
+    let ns = parse_and_resolve("struct a { uint32 f1; };", Target::Substrate);
+
+    assert_eq!(first_error(ns.diagnostics), "stray semicolon");
+
+    let ns = parse_and_resolve("contract x { struct a { uint32 f1; }; }", Target::Substrate);
+
+    assert_eq!(first_error(ns.diagnostics), "stray semicolon");
+}

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio