Преглед изворни кода

Resolve bases before resolving types in contracts

Signed-off-by: Iwan Waitusenok <sleepplease@protonmail.ch>
Iwan Waitusenok пре 4 година
родитељ
комит
f7ebf6483c
3 измењених фајлова са 72 додато и 4 уклоњено
  1. 1 3
      src/sema/contracts.rs
  2. 2 0
      src/sema/mod.rs
  3. 69 1
      tests/solana_tests/create_contract.rs

+ 1 - 3
src/sema/contracts.rs

@@ -70,8 +70,6 @@ pub fn resolve(
     file_no: usize,
     ns: &mut ast::Namespace,
 ) {
-    resolve_base_contracts(contracts, file_no, ns);
-
     resolve_using(contracts, file_no, ns);
 
     // we need to resolve declarations first, so we call functions/constructors of
@@ -101,7 +99,7 @@ pub fn resolve(
 
 /// Resolve the base contracts list and check for cycles. Returns true if no
 /// issues where found.
-fn resolve_base_contracts(
+pub fn resolve_base_contracts(
     contracts: &[(usize, &pt::ContractDefinition)],
     file_no: usize,
     ns: &mut ast::Namespace,

+ 2 - 0
src/sema/mod.rs

@@ -102,6 +102,8 @@ fn sema_file(file: &ResolvedFile, resolver: &mut FileResolver, ns: &mut ast::Nam
         }
     }
 
+    contracts::resolve_base_contracts(&contracts_to_resolve, file_no, ns);
+
     // once all the types are resolved, we can resolve the structs and events. This is because
     // struct fields or event fields can have types defined elsewhere.
     types::resolve_fields(fields, file_no, ns);

+ 69 - 1
tests/solana_tests/create_contract.rs

@@ -1,4 +1,4 @@
-use crate::{build_solidity, first_error, parse_and_resolve};
+use crate::{build_solidity, first_error, no_errors, parse_and_resolve};
 use ethabi::Token;
 use solang::Target;
 
@@ -53,6 +53,74 @@ fn simple_create_contract() {
     assert_eq!(vm.logs, "Hello xywoleh");
 }
 
+#[test]
+fn base_contract() {
+    let ns = parse_and_resolve(
+        r#"
+        contract Math {
+            enum MathError {
+                NO_ERROR
+            }
+        }
+
+        contract IsMath is Math {
+            struct WithMath {
+                MathError math;
+            }
+        }
+    "#,
+        Target::Solana,
+    );
+
+    no_errors(ns.diagnostics);
+
+    let ns = parse_and_resolve(
+        r#"
+        contract Logic {
+            enum LogicError {
+                LE_ERROR
+            }
+        }
+        contract Math is Logic {
+            enum MathError {
+                NO_ERROR
+            }
+        }
+
+        contract IsMath is Math {
+            struct WithMath {
+                MathError math;
+                LogicError logic;
+            }
+        }
+    "#,
+        Target::Solana,
+    );
+
+    no_errors(ns.diagnostics);
+
+    let ns = parse_and_resolve(
+        r#"
+        contract Logic {
+            struct LogicFields {
+                uint logia;
+            }
+        }
+        contract Math is Logic {
+        }
+
+        contract IsMath is Math {
+            struct WithMath {
+                LogicFields logia;
+            }
+        }
+    "#,
+        Target::Solana,
+    );
+
+    no_errors(ns.diagnostics);
+}
+
 #[test]
 // 64424509440 = 15 << 32 (ERROR_NEW_ACCOUNT_NEEDED)
 #[should_panic(expected = "64424509440")]