Browse Source

Allow calling constants from contracts as well

Signed-off-by: Iwan Waitusenok <sleepplease@protonmail.ch>
Iwan Waitusenok 4 years ago
parent
commit
c55722578b
3 changed files with 21 additions and 30 deletions
  1. 10 19
      src/sema/expression.rs
  2. 10 10
      tests/solana_tests/constant.rs
  3. 1 1
      tests/solana_tests/mod.rs

+ 10 - 19
src/sema/expression.rs

@@ -14,8 +14,8 @@ use std::ops::{Add, Shl, Sub};
 
 use super::address::to_hexstr_eip55;
 use super::ast::{
-    Builtin, CallTy, Contract, Diagnostic, Expression, Function, Mutability, Namespace,
-    StringLocation, Symbol, Type,
+    Builtin, CallTy, Diagnostic, Expression, Function, Mutability, Namespace, StringLocation,
+    Symbol, Type,
 };
 use super::builtin;
 use super::contracts::{is_base, visit_bases};
@@ -4907,10 +4907,9 @@ fn member_access(
         return Ok(expr);
     }
 
-    // is it a constant in a library (unless basecontract is a local variable)
-    match library_constant(e, id, file_no, ns, symtable) {
-        None => (),
-        Some(expr) => return Ok(expr),
+    // is it a constant (unless basecontract is a local variable)
+    if let Some(expr) = contract_constant(e, id, file_no, ns, symtable) {
+        return Ok(expr);
     }
 
     // is it a basecontract.function.selector expression (unless basecontract is a local variable)
@@ -5251,7 +5250,7 @@ fn member_access(
     Err(())
 }
 
-fn library_constant(
+fn contract_constant(
     e: &pt::Expression,
     id: &pt::Identifier,
     file_no: usize,
@@ -5267,18 +5266,10 @@ fn library_constant(
         return None;
     };
 
-    let library_no = ns.resolve_contract(file_no, namespace)?;
-
-    let variables = match &mut ns.contracts[library_no] {
-        Contract {
-            ty: pt::ContractTy::Library(_),
-            variables,
-            ..
-        } => variables,
-        _ => return None,
-    };
+    let contract_no = ns.resolve_contract(file_no, namespace)?;
 
-    let (var_no, constant) = variables
+    let (var_no, constant) = ns.contracts[contract_no]
+        .variables
         .iter_mut()
         .enumerate()
         .find(|(_, constant)| constant.name == id.name)?;
@@ -5288,7 +5279,7 @@ fn library_constant(
     Some(Expression::ConstantVariable(
         constant.loc,
         constant.ty.clone(),
-        Some(library_no),
+        Some(contract_no),
         var_no,
     ))
 }

+ 10 - 10
tests/solana_tests/library.rs → tests/solana_tests/constant.rs

@@ -2,7 +2,7 @@ use crate::{build_solidity, first_error, parse_and_resolve, Target};
 use ethabi::Token;
 
 #[test]
-fn library_constant() {
+fn constant() {
     let mut vm = build_solidity(
         r#"
         library Library {
@@ -23,11 +23,8 @@ fn library_constant() {
     let returns = vm.function("f", &[], &[], 0);
 
     assert_eq!(returns, vec![Token::Uint(ethereum_types::U256::from(42))]);
-}
 
-#[test]
-fn contract_constant() {
-    let ns = parse_and_resolve(
+    let mut vm = build_solidity(
         r#"
         contract Library {
             uint256 public constant STATIC = 42;
@@ -40,14 +37,17 @@ fn contract_constant() {
             }
         }
         "#,
-        Target::Solana,
     );
 
-    assert_eq!(
-        first_error(ns.diagnostics),
-        "conversion from function() internal view returns (uint256) to uint256 not possible",
-    );
+    vm.constructor("foo", &[], 0);
 
+    let returns = vm.function("f", &[], &[], 0);
+
+    assert_eq!(returns, vec![Token::Uint(ethereum_types::U256::from(42))]);
+}
+
+#[test]
+fn contract_constant_call() {
     let ns = parse_and_resolve(
         r#"
         contract Library {

+ 1 - 1
tests/solana_tests/mod.rs

@@ -5,12 +5,12 @@ mod assembly;
 mod balance;
 mod builtin;
 mod call;
+mod constant;
 mod create_contract;
 mod destructure;
 mod events;
 mod expressions;
 mod hash;
-mod library;
 mod mappings;
 mod primitives;
 mod signature_verify;