This commit is contained in:
Daniel Kirchner 2023-06-21 01:50:00 +02:00
parent 3286d1cec2
commit 7a8c997438
8 changed files with 150 additions and 5 deletions

View File

@ -282,6 +282,32 @@ bool TypeInference::visit(Identifier const& _identifier)
return true;
}
bool TypeInference::visit(IdentifierPath const& _identifier)
{
// TODO: deduplicate with Identifier visit
auto& identifierAnnotation = annotation(_identifier);
solAssert(!identifierAnnotation.type);
auto const* referencedDeclaration = _identifier.annotation().referencedDeclaration;
solAssert(referencedDeclaration);
auto& declarationAnnotation = annotation(*referencedDeclaration);
if (!declarationAnnotation.type)
referencedDeclaration->accept(*this);
solAssert(declarationAnnotation.type);
identifierAnnotation.type = declarationAnnotation.type;
return true;
}
bool TypeInference::visit(TypeClassInstantiation const& _typeClassInstantiation)
{
for (auto subNode: _typeClassInstantiation.subNodes())
subNode->accept(*this);
return false;
}
bool TypeInference::visit(FunctionCall const&) { return true; }
void TypeInference::endVisit(FunctionCall const& _functionCall)
{

View File

@ -52,12 +52,15 @@ private:
bool visit(Assignment const&) override;
void endVisit(Assignment const&) override;
bool visit(Identifier const&) override;
bool visit(IdentifierPath const&) override;
bool visit(FunctionCall const& _functionCall) override;
void endVisit(FunctionCall const& _functionCall) override;
bool visit(Return const&) override { return true; }
void endVisit(Return const& _return) override;
// TODO: properly account for it
bool visit(TypeClassDefinition const&) override { return true; }
bool visit(TypeClassInstantiation const&) override;
bool visitNode(ASTNode const& _node) override;

View File

@ -2485,6 +2485,40 @@ private:
ASTPointer<VariableDeclaration> m_typeVariable;
std::vector<ASTPointer<ASTNode>> m_subNodes;
};
class TypeClassInstantiation: public ASTNode, public ScopeOpener
{
public:
TypeClassInstantiation(
int64_t _id,
SourceLocation const& _location,
ASTPointer<TypeName> _typeConstructor,
std::vector<ASTPointer<IdentifierPath>> const& _argumentSorts,
ASTPointer<IdentifierPath> _sort,
std::vector<ASTPointer<ASTNode>> _subNodes
):
ASTNode(_id, _location),
m_typeConstructor(std::move(_typeConstructor)),
m_argumentSorts(std::move(_argumentSorts)),
m_sort(std::move(_sort)),
m_subNodes(std::move(_subNodes))
{}
void accept(ASTVisitor& _visitor) override;
void accept(ASTConstVisitor& _visitor) const override;
TypeName const& typeConstructor() const { return *m_typeConstructor; }
std::vector<ASTPointer<IdentifierPath>> const& argumentSorts() const { return m_argumentSorts; }
IdentifierPath const& sort() const { return *m_sort; }
std::vector<ASTPointer<ASTNode>> const& subNodes() const { return m_subNodes; }
bool experimentalSolidityOnly() const override { return true; }
private:
ASTPointer<TypeName> m_typeConstructor;
std::vector<ASTPointer<IdentifierPath>> m_argumentSorts;
ASTPointer<IdentifierPath> m_sort;
std::vector<ASTPointer<ASTNode>> m_subNodes;
};
/// @}

View File

@ -112,6 +112,7 @@ public:
/// Experimental Solidity nodes
/// @{
virtual bool visit(TypeClassDefinition& _node) { return visitNode(_node); }
virtual bool visit(TypeClassInstantiation& _node) { return visitNode(_node); }
/// @}
virtual void endVisit(SourceUnit& _node) { endVisitNode(_node); }
@ -172,6 +173,7 @@ public:
/// Experimental Solidity nodes
/// @{
virtual void endVisit(TypeClassDefinition& _node) { endVisitNode(_node); }
virtual void endVisit(TypeClassInstantiation& _node) { endVisitNode(_node); }
/// @}
protected:
@ -254,6 +256,7 @@ public:
/// Experimental Solidity nodes
/// @{
virtual bool visit(TypeClassDefinition const& _node) { return visitNode(_node); }
virtual bool visit(TypeClassInstantiation const& _node) { return visitNode(_node); }
/// @}
virtual void endVisit(SourceUnit const& _node) { endVisitNode(_node); }
@ -314,6 +317,7 @@ public:
/// Experimental Solidity nodes
/// @{
virtual void endVisit(TypeClassDefinition const& _node) { endVisitNode(_node); }
virtual void endVisit(TypeClassInstantiation const& _node) { endVisitNode(_node); }
/// @}
protected:

View File

@ -1049,6 +1049,30 @@ void TypeClassDefinition::accept(ASTConstVisitor& _visitor) const
}
_visitor.endVisit(*this);
}
void TypeClassInstantiation::accept(ASTVisitor& _visitor)
{
if (_visitor.visit(*this))
{
m_typeConstructor->accept(_visitor);
listAccept(m_argumentSorts, _visitor);
m_sort->accept(_visitor);
listAccept(m_subNodes, _visitor);
}
_visitor.endVisit(*this);
}
void TypeClassInstantiation::accept(ASTConstVisitor& _visitor) const
{
if (_visitor.visit(*this))
{
m_typeConstructor->accept(_visitor);
listAccept(m_argumentSorts, _visitor);
m_sort->accept(_visitor);
listAccept(m_subNodes, _visitor);
}
_visitor.endVisit(*this);
}
/// @}
}

View File

@ -138,6 +138,10 @@ ASTPointer<SourceUnit> Parser::parse(CharStream& _charStream)
solAssert(m_experimentalSolidityEnabledInCurrentSourceUnit);
nodes.push_back(parseTypeClassDefinition());
break;
case Token::Instantiation:
solAssert(m_experimentalSolidityEnabledInCurrentSourceUnit);
nodes.push_back(parseTypeClassInstantiation());
break;
default:
if (
// Workaround because `error` is not a keyword.
@ -1732,6 +1736,7 @@ ASTPointer<VariableDeclaration> Parser::parsePostfixVariableDeclaration()
ASTPointer<TypeClassDefinition> Parser::parseTypeClassDefinition()
{
solAssert(m_experimentalSolidityEnabledInCurrentSourceUnit);
RecursionGuard recursionGuard(*this);
ASTNodeFactory nodeFactory(*this);
@ -1778,6 +1783,55 @@ ASTPointer<TypeClassDefinition> Parser::parseTypeClassDefinition()
);
}
ASTPointer<TypeClassInstantiation> Parser::parseTypeClassInstantiation()
{
solAssert(m_experimentalSolidityEnabledInCurrentSourceUnit);
RecursionGuard recursionGuard(*this);
ASTNodeFactory nodeFactory(*this);
vector<ASTPointer<ASTNode>> subNodes;
expectToken(Token::Instantiation);
// TODO: parseTypeConstructor()
ASTPointer<TypeName> typeConstructor = parseTypeName();
expectToken(Token::Colon);
vector<ASTPointer<IdentifierPath>> argumentSorts;
if (m_scanner->currentToken() == Token::LParen)
{
expectToken(Token::LParen);
if (m_scanner->currentToken() != Token::RParen)
{
argumentSorts.emplace_back(parseIdentifierPath());
while (m_scanner->currentToken() == Token::Comma)
{
expectToken(Token::Comma);
argumentSorts.emplace_back(parseIdentifierPath());
}
}
expectToken(Token::RParen);
}
ASTPointer<IdentifierPath> sort = parseIdentifierPath();
expectToken(Token::LBrace);
while (true)
{
Token currentTokenValue = m_scanner->currentToken();
if (currentTokenValue == Token::RBrace)
break;
expectToken(Token::Function, false);
// TODO: require body already during parsing?
subNodes.push_back(parseFunctionDefinition(false, true));
}
nodeFactory.markEndPosition();
expectToken(Token::RBrace);
return nodeFactory.createNode<TypeClassInstantiation>(
typeConstructor,
argumentSorts,
sort,
subNodes
);
}
ASTPointer<Statement> Parser::parseSimpleStatement(ASTPointer<ASTString> const& _docString)
{
RecursionGuard recursionGuard(*this);

View File

@ -177,6 +177,7 @@ private:
);
ASTPointer<VariableDeclaration> parsePostfixVariableDeclaration();
ASTPointer<TypeClassDefinition> parseTypeClassDefinition();
ASTPointer<TypeClassInstantiation> parseTypeClassInstantiation();
///@}
///@{

View File

@ -4,13 +4,12 @@ pragma experimental solidity;
class a:StackType {
function stackSize() -> x:integer;
}
/*
instantiate uint256 : StackType {
function stackSize() -> (integer) {
return 1;
instantiation word : StackType {
function stackSize() -> x:integer {
return x;
}
}
*/
function f(a) -> b {
return a;