浏览代码

constructors do not need a visibility specifiers

Since solidity 0.7.

Signed-off-by: Sean Young <sean@mess.org>
Sean Young 5 年之前
父节点
当前提交
b6958965e7
共有 8 个文件被更改,包括 55 次插入36 次删除
  1. 1 1
      examples/flipper.sol
  2. 1 1
      examples/full_example.sol
  3. 1 1
      examples/incrementer.sol
  4. 1 1
      src/abi/ethereum.rs
  5. 15 11
      src/parser/pt.rs
  6. 3 3
      src/sema/ast.rs
  7. 20 18
      src/sema/functions.rs
  8. 13 0
      tests/substrate_functions/mod.rs

+ 1 - 1
examples/flipper.sol

@@ -2,7 +2,7 @@ contract flipper {
 	bool private value;
 	bool private value;
 
 
 	/// Constructor that initializes the `bool` value to the given `init_value`.
 	/// Constructor that initializes the `bool` value to the given `init_value`.
-	constructor(bool initvalue) public {
+	constructor(bool initvalue) {
 		value = initvalue;
 		value = initvalue;
 	}
 	}
 
 

+ 1 - 1
examples/full_example.sol

@@ -26,7 +26,7 @@ contract full_example {
 	int32 constant first_pid = 1;
 	int32 constant first_pid = 1;
 
 
 	// Our constructors
 	// Our constructors
-	constructor(int32 _pid) public {
+	constructor(int32 _pid) {
 		// Set contract storage
 		// Set contract storage
 		pid = _pid;
 		pid = _pid;
 	}
 	}

+ 1 - 1
examples/incrementer.sol

@@ -4,7 +4,7 @@ contract incrementer {
 	uint32 private value;
 	uint32 private value;
 
 
 	/// Constructor that initializes the `int32` value to the given `init_value`.
 	/// Constructor that initializes the `int32` value to the given `init_value`.
-	constructor(uint32 initvalue) public {
+	constructor(uint32 initvalue) {
 		value = initvalue;
 		value = initvalue;
 	}
 	}
 
 

+ 1 - 1
src/abi/ethereum.rs

@@ -24,7 +24,7 @@ pub struct ABI {
     // outputs should be skipped if ty is constructor
     // outputs should be skipped if ty is constructor
     pub outputs: Vec<ABIParam>,
     pub outputs: Vec<ABIParam>,
     #[serde(rename = "stateMutability")]
     #[serde(rename = "stateMutability")]
-    pub mutability: &'static str,
+    pub mutability: String,
 }
 }
 
 
 impl Type {
 impl Type {

+ 15 - 11
src/parser/pt.rs

@@ -360,15 +360,17 @@ pub enum StateMutability {
     Payable(Loc),
     Payable(Loc),
 }
 }
 
 
-impl StateMutability {
-    pub fn to_string(&self) -> &'static str {
+impl fmt::Display for StateMutability {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
         match self {
-            StateMutability::Pure(_) => "pure",
-            StateMutability::View(_) => "view",
-            StateMutability::Payable(_) => "payable",
+            StateMutability::Pure(_) => write!(f, "pure"),
+            StateMutability::View(_) => write!(f, "view"),
+            StateMutability::Payable(_) => write!(f, "payable"),
         }
         }
     }
     }
+}
 
 
+impl StateMutability {
     pub fn loc(&self) -> Loc {
     pub fn loc(&self) -> Loc {
         match self {
         match self {
             StateMutability::Pure(loc)
             StateMutability::Pure(loc)
@@ -386,16 +388,18 @@ pub enum Visibility {
     Private(Loc),
     Private(Loc),
 }
 }
 
 
-impl Visibility {
-    pub fn to_string(&self) -> &'static str {
+impl fmt::Display for Visibility {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
         match self {
-            Visibility::Public(_) => "public",
-            Visibility::External(_) => "external",
-            Visibility::Internal(_) => "internal",
-            Visibility::Private(_) => "private",
+            Visibility::Public(_) => write!(f, "public"),
+            Visibility::External(_) => write!(f, "external"),
+            Visibility::Internal(_) => write!(f, "internal"),
+            Visibility::Private(_) => write!(f, "private"),
         }
         }
     }
     }
+}
 
 
+impl Visibility {
     pub fn loc(&self) -> Loc {
     pub fn loc(&self) -> Loc {
         match self {
         match self {
             Visibility::Public(loc)
             Visibility::Public(loc)

+ 3 - 3
src/sema/ast.rs

@@ -241,10 +241,10 @@ impl Function {
     }
     }
 
 
     /// State mutability as string
     /// State mutability as string
-    pub fn print_mutability(&self) -> &'static str {
+    pub fn print_mutability(&self) -> String {
         match &self.mutability {
         match &self.mutability {
-            None => "nonpayable",
-            Some(m) => m.to_string(),
+            None => "nonpayable".to_string(),
+            Some(m) => format!("{}", m),
         }
         }
     }
     }
 }
 }

+ 20 - 18
src/sema/functions.rs

@@ -200,13 +200,27 @@ pub fn function_decl(
     }
     }
 
 
     let visibility = match visibility {
     let visibility = match visibility {
-        Some(v) => v,
+        Some(v) => {
+            if func.ty == pt::FunctionTy::Constructor {
+                ns.diagnostics.push(Diagnostic::warning(
+                    v.loc(),
+                    format!("‘{}’: visibility for constructors is ignored", v),
+                ));
+
+                pt::Visibility::Public(v.loc())
+            } else {
+                v
+            }
+        }
         None => {
         None => {
-            ns.diagnostics.push(Diagnostic::error(
-                func.loc,
-                "no visibility specified".to_string(),
-            ));
-            success = false;
+            if func.ty != pt::FunctionTy::Constructor {
+                ns.diagnostics.push(Diagnostic::error(
+                    func.loc,
+                    "no visibility specified".to_string(),
+                ));
+
+                success = false;
+            }
             // continue processing while assuming it's a public
             // continue processing while assuming it's a public
             pt::Visibility::Public(pt::Loc(0, 0, 0))
             pt::Visibility::Public(pt::Loc(0, 0, 0))
         }
         }
@@ -310,18 +324,6 @@ pub fn function_decl(
             }
             }
         }
         }
 
 
-        // FIXME: Internal visibility is allowed on abstract contracts, but we don't support those yet
-        match fdecl.visibility {
-            pt::Visibility::Public(_) => (),
-            _ => {
-                ns.diagnostics.push(Diagnostic::error(
-                    func.loc,
-                    "constructor function must be declared public".to_owned(),
-                ));
-                return None;
-            }
-        }
-
         match fdecl.mutability {
         match fdecl.mutability {
             Some(pt::StateMutability::Pure(loc)) => {
             Some(pt::StateMutability::Pure(loc)) => {
                 ns.diagnostics.push(Diagnostic::error(
                 ns.diagnostics.push(Diagnostic::error(

+ 13 - 0
tests/substrate_functions/mod.rs

@@ -6,6 +6,19 @@ use solang::Target;
 
 
 #[test]
 #[test]
 fn constructors() {
 fn constructors() {
+    let ns = parse_and_resolve(
+        r##"
+        contract test {
+            constructor() internal {}
+        }"##,
+        Target::Substrate,
+    );
+
+    assert_eq!(
+        first_warning(ns.diagnostics),
+        "‘internal’: visibility for constructors is ignored"
+    );
+
     #[derive(Debug, PartialEq, Encode, Decode)]
     #[derive(Debug, PartialEq, Encode, Decode)]
     struct Val(u64);
     struct Val(u64);