mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
added parsing for constant variables
This commit is contained in:
parent
a16677dcfb
commit
67cd3a7180
6
AST.cpp
6
AST.cpp
@ -197,7 +197,7 @@ vector<pair<FixedHash<4>, FunctionTypePointer>> const& ContractDefinition::getIn
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (ASTPointer<VariableDeclaration> const& v: contract->getStateVariables())
|
for (ASTPointer<VariableDeclaration> const& v: contract->getStateVariables())
|
||||||
if (v->isPublic() && functionsSeen.count(v->getName()) == 0)
|
if (v->isPublic() && functionsSeen.count(v->getName()) == 0 && !v->isConstant())
|
||||||
{
|
{
|
||||||
FunctionType ftype(*v);
|
FunctionType ftype(*v);
|
||||||
functionsSeen.insert(v->getName());
|
functionsSeen.insert(v->getName());
|
||||||
@ -322,8 +322,8 @@ string FunctionDefinition::getCanonicalSignature() const
|
|||||||
|
|
||||||
bool VariableDeclaration::isLValue() const
|
bool VariableDeclaration::isLValue() const
|
||||||
{
|
{
|
||||||
// External function parameters are Read-Only
|
// External function parameters and constant declared variables are Read-Only
|
||||||
return !isExternalFunctionParameter();
|
return !isExternalFunctionParameter() && !m_isConstant;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VariableDeclaration::checkTypeRequirements()
|
void VariableDeclaration::checkTypeRequirements()
|
||||||
|
21
AST.h
21
AST.h
@ -440,13 +440,22 @@ private:
|
|||||||
class VariableDeclaration: public Declaration
|
class VariableDeclaration: public Declaration
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VariableDeclaration(SourceLocation const& _location, ASTPointer<TypeName> const& _type,
|
VariableDeclaration(
|
||||||
ASTPointer<ASTString> const& _name, ASTPointer<Expression> _value,
|
SourceLocation const& _location,
|
||||||
|
ASTPointer<TypeName> const& _type,
|
||||||
|
ASTPointer<ASTString> const& _name,
|
||||||
|
ASTPointer<Expression> _value,
|
||||||
Visibility _visibility,
|
Visibility _visibility,
|
||||||
bool _isStateVar = false, bool _isIndexed = false):
|
bool _isStateVar = false,
|
||||||
|
bool _isIndexed = false,
|
||||||
|
bool _isConstant = false):
|
||||||
Declaration(_location, _name, _visibility),
|
Declaration(_location, _name, _visibility),
|
||||||
m_typeName(_type), m_value(_value),
|
m_typeName(_type),
|
||||||
m_isStateVariable(_isStateVar), m_isIndexed(_isIndexed) {}
|
m_value(_value),
|
||||||
|
m_isStateVariable(_isStateVar),
|
||||||
|
m_isIndexed(_isIndexed),
|
||||||
|
m_isConstant(_isConstant){}
|
||||||
|
|
||||||
virtual void accept(ASTVisitor& _visitor) override;
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||||
|
|
||||||
@ -465,6 +474,7 @@ public:
|
|||||||
bool isExternalFunctionParameter() const;
|
bool isExternalFunctionParameter() const;
|
||||||
bool isStateVariable() const { return m_isStateVariable; }
|
bool isStateVariable() const { return m_isStateVariable; }
|
||||||
bool isIndexed() const { return m_isIndexed; }
|
bool isIndexed() const { return m_isIndexed; }
|
||||||
|
bool isConstant() const { return m_isConstant; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Visibility getDefaultVisibility() const override { return Visibility::Internal; }
|
Visibility getDefaultVisibility() const override { return Visibility::Internal; }
|
||||||
@ -474,6 +484,7 @@ private:
|
|||||||
ASTPointer<Expression> m_value; ///< the assigned value, can be missing
|
ASTPointer<Expression> m_value; ///< the assigned value, can be missing
|
||||||
bool m_isStateVariable; ///< Whether or not this is a contract state variable
|
bool m_isStateVariable; ///< Whether or not this is a contract state variable
|
||||||
bool m_isIndexed; ///< Whether this is an indexed variable (used by events).
|
bool m_isIndexed; ///< Whether this is an indexed variable (used by events).
|
||||||
|
bool m_isConstant; ///< Whether the variable is a compile-time constant.
|
||||||
|
|
||||||
std::shared_ptr<Type const> m_type; ///< derived type, initially empty
|
std::shared_ptr<Type const> m_type; ///< derived type, initially empty
|
||||||
};
|
};
|
||||||
|
@ -276,13 +276,14 @@ void Compiler::registerStateVariables(ContractDefinition const& _contract)
|
|||||||
{
|
{
|
||||||
for (ContractDefinition const* contract: boost::adaptors::reverse(_contract.getLinearizedBaseContracts()))
|
for (ContractDefinition const* contract: boost::adaptors::reverse(_contract.getLinearizedBaseContracts()))
|
||||||
for (ASTPointer<VariableDeclaration> const& variable: contract->getStateVariables())
|
for (ASTPointer<VariableDeclaration> const& variable: contract->getStateVariables())
|
||||||
|
if (!variable->isConstant())
|
||||||
m_context.addStateVariable(*variable);
|
m_context.addStateVariable(*variable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Compiler::initializeStateVariables(ContractDefinition const& _contract)
|
void Compiler::initializeStateVariables(ContractDefinition const& _contract)
|
||||||
{
|
{
|
||||||
for (ASTPointer<VariableDeclaration> const& variable: _contract.getStateVariables())
|
for (ASTPointer<VariableDeclaration> const& variable: _contract.getStateVariables())
|
||||||
if (variable->getValue())
|
if (variable->getValue() && !variable->isConstant())
|
||||||
ExpressionCompiler(m_context, m_optimize).appendStateVariableInitialization(*variable);
|
ExpressionCompiler(m_context, m_optimize).appendStateVariableInitialization(*variable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -855,8 +855,11 @@ void ExpressionCompiler::endVisit(Identifier const& _identifier)
|
|||||||
}
|
}
|
||||||
else if (FunctionDefinition const* functionDef = dynamic_cast<FunctionDefinition const*>(declaration))
|
else if (FunctionDefinition const* functionDef = dynamic_cast<FunctionDefinition const*>(declaration))
|
||||||
m_context << m_context.getVirtualFunctionEntryLabel(*functionDef).pushTag();
|
m_context << m_context.getVirtualFunctionEntryLabel(*functionDef).pushTag();
|
||||||
else if (dynamic_cast<VariableDeclaration const*>(declaration))
|
else if (auto variable = dynamic_cast<VariableDeclaration const*>(declaration))
|
||||||
|
{
|
||||||
|
if (!variable->isConstant())
|
||||||
setLValueFromDeclaration(*declaration, _identifier);
|
setLValueFromDeclaration(*declaration, _identifier);
|
||||||
|
}
|
||||||
else if (dynamic_cast<ContractDefinition const*>(declaration))
|
else if (dynamic_cast<ContractDefinition const*>(declaration))
|
||||||
{
|
{
|
||||||
// no-op
|
// no-op
|
||||||
|
11
Parser.cpp
11
Parser.cpp
@ -135,6 +135,7 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition()
|
|||||||
}
|
}
|
||||||
while (m_scanner->getCurrentToken() == Token::Comma);
|
while (m_scanner->getCurrentToken() == Token::Comma);
|
||||||
expectToken(Token::LBrace);
|
expectToken(Token::LBrace);
|
||||||
|
bool isDeclaredConst = false;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
Token::Value currentToken = m_scanner->getCurrentToken();
|
Token::Value currentToken = m_scanner->getCurrentToken();
|
||||||
@ -152,13 +153,21 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition()
|
|||||||
VarDeclParserOptions options;
|
VarDeclParserOptions options;
|
||||||
options.isStateVariable = true;
|
options.isStateVariable = true;
|
||||||
options.allowInitialValue = true;
|
options.allowInitialValue = true;
|
||||||
|
options.isDeclaredConst = isDeclaredConst;
|
||||||
stateVariables.push_back(parseVariableDeclaration(options));
|
stateVariables.push_back(parseVariableDeclaration(options));
|
||||||
|
isDeclaredConst = false;
|
||||||
expectToken(Token::Semicolon);
|
expectToken(Token::Semicolon);
|
||||||
}
|
}
|
||||||
else if (currentToken == Token::Modifier)
|
else if (currentToken == Token::Modifier)
|
||||||
modifiers.push_back(parseModifierDefinition());
|
modifiers.push_back(parseModifierDefinition());
|
||||||
else if (currentToken == Token::Event)
|
else if (currentToken == Token::Event)
|
||||||
events.push_back(parseEventDefinition());
|
events.push_back(parseEventDefinition());
|
||||||
|
else if (currentToken == Token::Const)
|
||||||
|
{
|
||||||
|
solAssert(Token::isElementaryTypeName(m_scanner->peekNextToken()), "");
|
||||||
|
isDeclaredConst = true;
|
||||||
|
m_scanner->next();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
BOOST_THROW_EXCEPTION(createParserError("Function, variable, struct or modifier declaration expected."));
|
BOOST_THROW_EXCEPTION(createParserError("Function, variable, struct or modifier declaration expected."));
|
||||||
}
|
}
|
||||||
@ -348,7 +357,7 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(
|
|||||||
}
|
}
|
||||||
return nodeFactory.createNode<VariableDeclaration>(type, identifier, value,
|
return nodeFactory.createNode<VariableDeclaration>(type, identifier, value,
|
||||||
visibility, _options.isStateVariable,
|
visibility, _options.isStateVariable,
|
||||||
isIndexed);
|
isIndexed, _options.isDeclaredConst);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTPointer<ModifierDefinition> Parser::parseModifierDefinition()
|
ASTPointer<ModifierDefinition> Parser::parseModifierDefinition()
|
||||||
|
1
Parser.h
1
Parser.h
@ -54,6 +54,7 @@ private:
|
|||||||
bool allowIndexed = false;
|
bool allowIndexed = false;
|
||||||
bool allowEmptyName = false;
|
bool allowEmptyName = false;
|
||||||
bool allowInitialValue = false;
|
bool allowInitialValue = false;
|
||||||
|
bool isDeclaredConst = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
///@{
|
///@{
|
||||||
|
2
Types.h
2
Types.h
@ -516,7 +516,7 @@ private:
|
|||||||
std::vector<std::string> m_parameterNames;
|
std::vector<std::string> m_parameterNames;
|
||||||
std::vector<std::string> m_returnParameterNames;
|
std::vector<std::string> m_returnParameterNames;
|
||||||
Location const m_location;
|
Location const m_location;
|
||||||
/// true iff the function takes an arbitrary number of arguments of arbitrary types
|
/// true if the function takes an arbitrary number of arguments of arbitrary types
|
||||||
bool const m_arbitraryParameters = false;
|
bool const m_arbitraryParameters = false;
|
||||||
bool const m_gasSet = false; ///< true iff the gas value to be used is on the stack
|
bool const m_gasSet = false; ///< true iff the gas value to be used is on the stack
|
||||||
bool const m_valueSet = false; ///< true iff the value to be sent is on the stack
|
bool const m_valueSet = false; ///< true iff the value to be sent is on the stack
|
||||||
|
Loading…
Reference in New Issue
Block a user