mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
tmp
This commit is contained in:
parent
955ada39e5
commit
423972883c
@ -82,6 +82,8 @@ set(sources
|
||||
ast/experimental/Type.h
|
||||
ast/experimental/TypeSystem.cpp
|
||||
ast/experimental/TypeSystem.h
|
||||
ast/experimental/TypeSystemHelper.cpp
|
||||
ast/experimental/TypeSystemHelper.h
|
||||
codegen/ABIFunctions.cpp
|
||||
codegen/ABIFunctions.h
|
||||
codegen/ArrayUtils.cpp
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include <libsolidity/analysis/experimental/Analysis.h>
|
||||
#include <libsolidity/analysis/experimental/TypeInference.h>
|
||||
#include <libsolidity/ast/experimental/TypeSystemHelper.h>
|
||||
|
||||
#include <liblangutil/Exceptions.h>
|
||||
|
||||
@ -41,7 +42,7 @@ bool DebugWarner::visitNode(ASTNode const& _node)
|
||||
auto const& typeInferenceAnnotation = m_analysis.annotation<TypeInference>(_node);
|
||||
if (typeInferenceAnnotation.type)
|
||||
{
|
||||
Type type = m_analysis.typeSystem().env().resolveRecursive(*typeInferenceAnnotation.type);
|
||||
Type type = *typeInferenceAnnotation.type;
|
||||
m_errorReporter.info(
|
||||
0000_error,
|
||||
_node.location(),
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include <libsolidity/analysis/experimental/TypeInference.h>
|
||||
#include <libsolidity/analysis/experimental/Analysis.h>
|
||||
#include <libsolidity/ast/experimental/TypeSystemHelper.h>
|
||||
#include <liblangutil/Exceptions.h>
|
||||
|
||||
#include <libyul/AsmAnalysis.h>
|
||||
|
@ -29,69 +29,6 @@ using namespace std;
|
||||
using namespace solidity;
|
||||
using namespace solidity::frontend::experimental;
|
||||
|
||||
std::string frontend::experimental::canonicalTypeName(Type _type)
|
||||
{
|
||||
return std::visit(util::GenericVisitor{
|
||||
[&](TypeConstant const& _type) {
|
||||
std::stringstream stream;
|
||||
auto printTypeArguments = [&]() {
|
||||
if (!_type.arguments.empty())
|
||||
{
|
||||
stream << "$";
|
||||
for (auto type: _type.arguments | ranges::views::drop_last(1))
|
||||
stream << canonicalTypeName(type) << "$";
|
||||
stream << canonicalTypeName(_type.arguments.back());
|
||||
stream << "$";
|
||||
}
|
||||
};
|
||||
std::visit(util::GenericVisitor{
|
||||
[&](Declaration const* _declaration) {
|
||||
printTypeArguments();
|
||||
if (auto const* typeDeclarationAnnotation = dynamic_cast<TypeDeclarationAnnotation const*>(&_declaration->annotation()))
|
||||
stream << *typeDeclarationAnnotation->canonicalName;
|
||||
else
|
||||
// TODO: canonical name
|
||||
stream << _declaration->name();
|
||||
},
|
||||
[&](BuiltinType _builtinType) {
|
||||
printTypeArguments();
|
||||
switch(_builtinType)
|
||||
{
|
||||
case BuiltinType::Type:
|
||||
stream << "type";
|
||||
break;
|
||||
case BuiltinType::Sort:
|
||||
stream << "sort";
|
||||
break;
|
||||
case BuiltinType::Void:
|
||||
stream << "void";
|
||||
break;
|
||||
case BuiltinType::Function:
|
||||
stream << "fun";
|
||||
break;
|
||||
case BuiltinType::Unit:
|
||||
stream << "unit";
|
||||
break;
|
||||
case BuiltinType::Pair:
|
||||
stream << "pair";
|
||||
break;
|
||||
case BuiltinType::Word:
|
||||
stream << "word";
|
||||
break;
|
||||
case BuiltinType::Integer:
|
||||
stream << "integer";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}, _type.constructor);
|
||||
return stream.str();
|
||||
},
|
||||
[](TypeVariable const&)-> string {
|
||||
solAssert(false);
|
||||
},
|
||||
}, _type);
|
||||
}
|
||||
|
||||
bool TypeClass::operator<(TypeClass const& _rhs) const
|
||||
{
|
||||
return std::visit(util::GenericVisitor{
|
||||
|
@ -38,8 +38,6 @@ struct TypeVariable;
|
||||
|
||||
using Type = std::variant<TypeConstant, TypeVariable>;
|
||||
|
||||
std::string canonicalTypeName(Type _type);
|
||||
|
||||
enum class BuiltinType
|
||||
{
|
||||
Type,
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
|
||||
#include <libsolidity/ast/experimental/TypeSystem.h>
|
||||
#include <libsolidity/ast/experimental/TypeSystemHelper.h>
|
||||
#include <libsolidity/ast/AST.h>
|
||||
#include <liblangutil/Exceptions.h>
|
||||
|
||||
@ -35,6 +36,70 @@ using namespace std;
|
||||
using namespace solidity::frontend;
|
||||
using namespace solidity::frontend::experimental;
|
||||
|
||||
std::string TypeEnvironment::canonicalTypeName(Type _type) const
|
||||
{
|
||||
return visit(util::GenericVisitor{
|
||||
[&](TypeConstant const& _type) {
|
||||
std::stringstream stream;
|
||||
auto printTypeArguments = [&]() {
|
||||
if (!_type.arguments.empty())
|
||||
{
|
||||
stream << "$";
|
||||
for (auto type: _type.arguments | ranges::views::drop_last(1))
|
||||
stream << canonicalTypeName(type) << "$";
|
||||
stream << canonicalTypeName(_type.arguments.back());
|
||||
stream << "$";
|
||||
}
|
||||
};
|
||||
std::visit(util::GenericVisitor{
|
||||
[&](Declaration const* _declaration) {
|
||||
printTypeArguments();
|
||||
if (auto const* typeDeclarationAnnotation = dynamic_cast<TypeDeclarationAnnotation const*>(&_declaration->annotation()))
|
||||
stream << *typeDeclarationAnnotation->canonicalName;
|
||||
else
|
||||
// TODO: canonical name
|
||||
stream << _declaration->name();
|
||||
},
|
||||
[&](BuiltinType _builtinType) {
|
||||
printTypeArguments();
|
||||
switch(_builtinType)
|
||||
{
|
||||
case BuiltinType::Type:
|
||||
stream << "type";
|
||||
break;
|
||||
case BuiltinType::Sort:
|
||||
stream << "sort";
|
||||
break;
|
||||
case BuiltinType::Void:
|
||||
stream << "void";
|
||||
break;
|
||||
case BuiltinType::Function:
|
||||
stream << "fun";
|
||||
break;
|
||||
case BuiltinType::Unit:
|
||||
stream << "unit";
|
||||
break;
|
||||
case BuiltinType::Pair:
|
||||
stream << "pair";
|
||||
break;
|
||||
case BuiltinType::Word:
|
||||
stream << "word";
|
||||
break;
|
||||
case BuiltinType::Integer:
|
||||
stream << "integer";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}, _type.constructor);
|
||||
return stream.str();
|
||||
},
|
||||
[](TypeVariable const&)-> string {
|
||||
solAssert(false);
|
||||
},
|
||||
}, resolve(_type));
|
||||
}
|
||||
|
||||
|
||||
std::string TypeEnvironment::typeToString(Type const& _type) const
|
||||
{
|
||||
return std::visit(util::GenericVisitor{
|
||||
@ -350,159 +415,3 @@ void TypeSystem::instantiateClass(TypeConstructor _typeConstructor, Arity _arity
|
||||
solAssert(_arity.argumentSorts.size() == typeConstructorInfo.arguments(), "Invalid arity.");
|
||||
typeConstructorInfo.arities.emplace_back(_arity);
|
||||
}
|
||||
|
||||
experimental::Type TypeSystemHelpers::tupleType(vector<Type> _elements) const
|
||||
{
|
||||
if (_elements.empty())
|
||||
return typeSystem.type(BuiltinType::Unit, {});
|
||||
if (_elements.size() == 1)
|
||||
return _elements.front();
|
||||
Type result = _elements.back();
|
||||
for (Type type: _elements | ranges::views::reverse | ranges::views::drop_exactly(1))
|
||||
result = typeSystem.type(BuiltinType::Pair, {type, result});
|
||||
return result;
|
||||
}
|
||||
|
||||
vector<experimental::Type> TypeSystemHelpers::destTupleType(Type _tupleType) const
|
||||
{
|
||||
if (!isTypeConstant(_tupleType))
|
||||
return {_tupleType};
|
||||
auto [constructor, arguments] = destTypeConstant(_tupleType);
|
||||
if (auto const* builtinType = get_if<BuiltinType>(&constructor))
|
||||
{
|
||||
if (*builtinType == BuiltinType::Unit)
|
||||
return {};
|
||||
else if (*builtinType != BuiltinType::Pair)
|
||||
return {_tupleType};
|
||||
}
|
||||
else
|
||||
return {_tupleType};
|
||||
solAssert(arguments.size() == 2);
|
||||
|
||||
vector<Type> result;
|
||||
result.emplace_back(arguments.front());
|
||||
Type tail = arguments.back();
|
||||
while(true)
|
||||
{
|
||||
if (!isTypeConstant(tail))
|
||||
break;
|
||||
auto [tailConstructor, tailArguments] = destTypeConstant(tail);
|
||||
auto const* builtinType = get_if<BuiltinType>(&tailConstructor);
|
||||
if(!builtinType || *builtinType != BuiltinType::Pair)
|
||||
break;
|
||||
solAssert(tailArguments.size() == 2);
|
||||
result.emplace_back(tailArguments.front());
|
||||
tail = tailArguments.back();
|
||||
}
|
||||
result.emplace_back(tail);
|
||||
return result;
|
||||
}
|
||||
|
||||
experimental::Type TypeSystemHelpers::functionType(experimental::Type _argType, experimental::Type _resultType) const
|
||||
{
|
||||
return typeSystem.type(BuiltinType::Function, {_argType, _resultType});
|
||||
}
|
||||
|
||||
tuple<TypeConstructor, vector<experimental::Type>> TypeSystemHelpers::destTypeConstant(Type _type) const
|
||||
{
|
||||
using ResultType = tuple<TypeConstructor, vector<Type>>;
|
||||
return std::visit(util::GenericVisitor{
|
||||
[&](TypeConstant const& _type) -> ResultType {
|
||||
return std::make_tuple(_type.constructor, _type.arguments);
|
||||
},
|
||||
[](auto const&) -> ResultType {
|
||||
solAssert(false);
|
||||
}
|
||||
}, _type);
|
||||
}
|
||||
|
||||
bool TypeSystemHelpers::isTypeConstant(Type _type) const
|
||||
{
|
||||
return std::visit(util::GenericVisitor{
|
||||
[&](TypeConstant const&) -> bool {
|
||||
return true;
|
||||
},
|
||||
[](auto const&) -> bool {
|
||||
return false;
|
||||
}
|
||||
}, _type);
|
||||
}
|
||||
|
||||
tuple<experimental::Type, experimental::Type> TypeSystemHelpers::destFunctionType(Type _functionType) const
|
||||
{
|
||||
auto [constructor, arguments] = destTypeConstant(_functionType);
|
||||
auto const* builtinType = get_if<BuiltinType>(&constructor);
|
||||
solAssert(builtinType && *builtinType == BuiltinType::Function);
|
||||
solAssert(arguments.size() == 2);
|
||||
return make_tuple(arguments.front(), arguments.back());
|
||||
}
|
||||
|
||||
bool TypeSystemHelpers::isFunctionType(Type _type) const
|
||||
{
|
||||
if (!isTypeConstant(_type))
|
||||
return false;
|
||||
auto constructor = get<0>(destTypeConstant(_type));
|
||||
auto const* builtinType = get_if<BuiltinType>(&constructor);
|
||||
return builtinType && *builtinType == BuiltinType::Function;
|
||||
}
|
||||
|
||||
vector<experimental::Type> TypeSystemHelpers::typeVars(Type _type) const
|
||||
{
|
||||
vector<Type> typeVars;
|
||||
auto typeVarsImpl = [&](Type _type, auto _recurse) -> void {
|
||||
std::visit(util::GenericVisitor{
|
||||
[&](TypeConstant const& _type) {
|
||||
for (auto arg: _type.arguments)
|
||||
_recurse(arg, _recurse);
|
||||
},
|
||||
[&](TypeVariable const& _var) {
|
||||
typeVars.emplace_back(_var);
|
||||
},
|
||||
// TODO: move to env helpers?
|
||||
}, typeSystem.env().resolve(_type));
|
||||
};
|
||||
typeVarsImpl(_type, typeVarsImpl);
|
||||
return typeVars;
|
||||
|
||||
}
|
||||
|
||||
experimental::Type TypeSystemHelpers::kindType(Type _type) const
|
||||
{
|
||||
return typeSystem.type(BuiltinType::Type, {_type});
|
||||
}
|
||||
|
||||
experimental::Type TypeSystemHelpers::destKindType(Type _type) const
|
||||
{
|
||||
auto [constructor, arguments] = destTypeConstant(_type);
|
||||
solAssert(constructor == TypeConstructor{BuiltinType::Type});
|
||||
solAssert(arguments.size() == 1);
|
||||
return arguments.front();
|
||||
}
|
||||
|
||||
bool TypeSystemHelpers::isKindType(Type _type) const
|
||||
{
|
||||
if (!isTypeConstant(_type))
|
||||
return false;
|
||||
auto constructor = get<0>(destTypeConstant(_type));
|
||||
return constructor == TypeConstructor{BuiltinType::Type};
|
||||
}
|
||||
|
||||
std::string TypeSystemHelpers::sortToString(Sort _sort) const
|
||||
{
|
||||
switch (_sort.classes.size())
|
||||
{
|
||||
case 0:
|
||||
return "()";
|
||||
case 1:
|
||||
return _sort.classes.begin()->toString();
|
||||
default:
|
||||
{
|
||||
std::stringstream stream;
|
||||
stream << "(";
|
||||
for (auto typeClass: _sort.classes | ranges::views::drop_last(1))
|
||||
stream << typeClass.toString() << ", ";
|
||||
stream << _sort.classes.rbegin()->toString() << ")";
|
||||
return stream.str();
|
||||
}
|
||||
}
|
||||
}
|
@ -25,12 +25,6 @@
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
namespace solidity::frontend
|
||||
{
|
||||
class Declaration;
|
||||
class TypeClassDefinition;
|
||||
}
|
||||
|
||||
namespace solidity::frontend::experimental
|
||||
{
|
||||
|
||||
@ -48,6 +42,7 @@ public:
|
||||
struct SortMismatch { Type type; Sort sort; };
|
||||
using UnificationFailure = std::variant<TypeMismatch, SortMismatch>;
|
||||
[[nodiscard]] std::vector<UnificationFailure> unify(Type _a, Type _b);
|
||||
std::string canonicalTypeName(Type _type) const;
|
||||
std::string typeToString(Type const& _type) const;
|
||||
Sort sort(Type _type) const;
|
||||
private:
|
||||
@ -107,21 +102,4 @@ private:
|
||||
TypeEnvironment m_globalTypeEnvironment{*this};
|
||||
};
|
||||
|
||||
struct TypeSystemHelpers
|
||||
{
|
||||
TypeSystem const& typeSystem;
|
||||
std::tuple<TypeConstructor, std::vector<Type>> destTypeConstant(Type _type) const;
|
||||
bool isTypeConstant(Type _type) const;
|
||||
Type tupleType(std::vector<Type> _elements) const;
|
||||
std::vector<Type> destTupleType(Type _tupleType) const;
|
||||
Type functionType(Type _argType, Type _resultType) const;
|
||||
std::tuple<Type, Type> destFunctionType(Type _functionType) const;
|
||||
bool isFunctionType(Type _type) const;
|
||||
std::vector<Type> typeVars(Type _type) const;
|
||||
std::string sortToString(Sort _sort) const;
|
||||
Type kindType(Type _type) const;
|
||||
bool isKindType(Type _type) const;
|
||||
Type destKindType(Type _type) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
187
libsolidity/ast/experimental/TypeSystemHelper.cpp
Normal file
187
libsolidity/ast/experimental/TypeSystemHelper.cpp
Normal file
@ -0,0 +1,187 @@
|
||||
/*
|
||||
This file is part of solidity.
|
||||
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
|
||||
|
||||
#include <libsolidity/ast/experimental/TypeSystemHelper.h>
|
||||
|
||||
#include <libsolutil/Visitor.h>
|
||||
|
||||
#include <range/v3/to_container.hpp>
|
||||
#include <range/v3/view/drop_exactly.hpp>
|
||||
#include <range/v3/view/drop_last.hpp>
|
||||
#include <range/v3/view/reverse.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace solidity::frontend;
|
||||
using namespace solidity::frontend::experimental;
|
||||
|
||||
experimental::Type TypeSystemHelpers::tupleType(vector<Type> _elements) const
|
||||
{
|
||||
if (_elements.empty())
|
||||
return typeSystem.type(BuiltinType::Unit, {});
|
||||
if (_elements.size() == 1)
|
||||
return _elements.front();
|
||||
Type result = _elements.back();
|
||||
for (Type type: _elements | ranges::views::reverse | ranges::views::drop_exactly(1))
|
||||
result = typeSystem.type(BuiltinType::Pair, {type, result});
|
||||
return result;
|
||||
}
|
||||
|
||||
vector<experimental::Type> TypeSystemHelpers::destTupleType(Type _tupleType) const
|
||||
{
|
||||
if (!isTypeConstant(_tupleType))
|
||||
return {_tupleType};
|
||||
auto [constructor, arguments] = destTypeConstant(_tupleType);
|
||||
if (auto const* builtinType = get_if<BuiltinType>(&constructor))
|
||||
{
|
||||
if (*builtinType == BuiltinType::Unit)
|
||||
return {};
|
||||
else if (*builtinType != BuiltinType::Pair)
|
||||
return {_tupleType};
|
||||
}
|
||||
else
|
||||
return {_tupleType};
|
||||
solAssert(arguments.size() == 2);
|
||||
|
||||
vector<Type> result;
|
||||
result.emplace_back(arguments.front());
|
||||
Type tail = arguments.back();
|
||||
while(true)
|
||||
{
|
||||
if (!isTypeConstant(tail))
|
||||
break;
|
||||
auto [tailConstructor, tailArguments] = destTypeConstant(tail);
|
||||
auto const* builtinType = get_if<BuiltinType>(&tailConstructor);
|
||||
if(!builtinType || *builtinType != BuiltinType::Pair)
|
||||
break;
|
||||
solAssert(tailArguments.size() == 2);
|
||||
result.emplace_back(tailArguments.front());
|
||||
tail = tailArguments.back();
|
||||
}
|
||||
result.emplace_back(tail);
|
||||
return result;
|
||||
}
|
||||
|
||||
experimental::Type TypeSystemHelpers::functionType(experimental::Type _argType, experimental::Type _resultType) const
|
||||
{
|
||||
return typeSystem.type(BuiltinType::Function, {_argType, _resultType});
|
||||
}
|
||||
|
||||
tuple<TypeConstructor, vector<experimental::Type>> TypeSystemHelpers::destTypeConstant(Type _type) const
|
||||
{
|
||||
using ResultType = tuple<TypeConstructor, vector<Type>>;
|
||||
return std::visit(util::GenericVisitor{
|
||||
[&](TypeConstant const& _type) -> ResultType {
|
||||
return std::make_tuple(_type.constructor, _type.arguments);
|
||||
},
|
||||
[](auto const&) -> ResultType {
|
||||
solAssert(false);
|
||||
}
|
||||
}, _type);
|
||||
}
|
||||
|
||||
bool TypeSystemHelpers::isTypeConstant(Type _type) const
|
||||
{
|
||||
return std::visit(util::GenericVisitor{
|
||||
[&](TypeConstant const&) -> bool {
|
||||
return true;
|
||||
},
|
||||
[](auto const&) -> bool {
|
||||
return false;
|
||||
}
|
||||
}, _type);
|
||||
}
|
||||
|
||||
tuple<experimental::Type, experimental::Type> TypeSystemHelpers::destFunctionType(Type _functionType) const
|
||||
{
|
||||
auto [constructor, arguments] = destTypeConstant(_functionType);
|
||||
auto const* builtinType = get_if<BuiltinType>(&constructor);
|
||||
solAssert(builtinType && *builtinType == BuiltinType::Function);
|
||||
solAssert(arguments.size() == 2);
|
||||
return make_tuple(arguments.front(), arguments.back());
|
||||
}
|
||||
|
||||
bool TypeSystemHelpers::isFunctionType(Type _type) const
|
||||
{
|
||||
if (!isTypeConstant(_type))
|
||||
return false;
|
||||
auto constructor = get<0>(destTypeConstant(_type));
|
||||
auto const* builtinType = get_if<BuiltinType>(&constructor);
|
||||
return builtinType && *builtinType == BuiltinType::Function;
|
||||
}
|
||||
|
||||
vector<experimental::Type> TypeSystemHelpers::typeVars(Type _type) const
|
||||
{
|
||||
vector<Type> typeVars;
|
||||
auto typeVarsImpl = [&](Type _type, auto _recurse) -> void {
|
||||
std::visit(util::GenericVisitor{
|
||||
[&](TypeConstant const& _type) {
|
||||
for (auto arg: _type.arguments)
|
||||
_recurse(arg, _recurse);
|
||||
},
|
||||
[&](TypeVariable const& _var) {
|
||||
typeVars.emplace_back(_var);
|
||||
},
|
||||
// TODO: move to env helpers?
|
||||
}, typeSystem.env().resolve(_type));
|
||||
};
|
||||
typeVarsImpl(_type, typeVarsImpl);
|
||||
return typeVars;
|
||||
|
||||
}
|
||||
|
||||
experimental::Type TypeSystemHelpers::kindType(Type _type) const
|
||||
{
|
||||
return typeSystem.type(BuiltinType::Type, {_type});
|
||||
}
|
||||
|
||||
experimental::Type TypeSystemHelpers::destKindType(Type _type) const
|
||||
{
|
||||
auto [constructor, arguments] = destTypeConstant(_type);
|
||||
solAssert(constructor == TypeConstructor{BuiltinType::Type});
|
||||
solAssert(arguments.size() == 1);
|
||||
return arguments.front();
|
||||
}
|
||||
|
||||
bool TypeSystemHelpers::isKindType(Type _type) const
|
||||
{
|
||||
if (!isTypeConstant(_type))
|
||||
return false;
|
||||
auto constructor = get<0>(destTypeConstant(_type));
|
||||
return constructor == TypeConstructor{BuiltinType::Type};
|
||||
}
|
||||
|
||||
std::string TypeSystemHelpers::sortToString(Sort _sort) const
|
||||
{
|
||||
switch (_sort.classes.size())
|
||||
{
|
||||
case 0:
|
||||
return "()";
|
||||
case 1:
|
||||
return _sort.classes.begin()->toString();
|
||||
default:
|
||||
{
|
||||
std::stringstream stream;
|
||||
stream << "(";
|
||||
for (auto typeClass: _sort.classes | ranges::views::drop_last(1))
|
||||
stream << typeClass.toString() << ", ";
|
||||
stream << _sort.classes.rbegin()->toString() << ")";
|
||||
return stream.str();
|
||||
}
|
||||
}
|
||||
}
|
42
libsolidity/ast/experimental/TypeSystemHelper.h
Normal file
42
libsolidity/ast/experimental/TypeSystemHelper.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
This file is part of solidity.
|
||||
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
#pragma once
|
||||
|
||||
#include <libsolidity/ast/experimental/TypeSystem.h>
|
||||
|
||||
namespace solidity::frontend::experimental
|
||||
{
|
||||
|
||||
struct TypeSystemHelpers
|
||||
{
|
||||
TypeSystem const& typeSystem;
|
||||
std::tuple<TypeConstructor, std::vector<Type>> destTypeConstant(Type _type) const;
|
||||
bool isTypeConstant(Type _type) const;
|
||||
Type tupleType(std::vector<Type> _elements) const;
|
||||
std::vector<Type> destTupleType(Type _tupleType) const;
|
||||
Type functionType(Type _argType, Type _resultType) const;
|
||||
std::tuple<Type, Type> destFunctionType(Type _functionType) const;
|
||||
bool isFunctionType(Type _type) const;
|
||||
std::vector<Type> typeVars(Type _type) const;
|
||||
std::string sortToString(Sort _sort) const;
|
||||
Type kindType(Type _type) const;
|
||||
bool isKindType(Type _type) const;
|
||||
Type destKindType(Type _type) const;
|
||||
};
|
||||
|
||||
}
|
@ -32,12 +32,12 @@ using namespace solidity::yul;
|
||||
namespace solidity::frontend::experimental
|
||||
{
|
||||
|
||||
string IRNames::function(FunctionDefinition const& _function, Type _type)
|
||||
string IRNames::function(TypeEnvironment const& _env, FunctionDefinition const& _function, Type _type)
|
||||
{
|
||||
if (_function.isConstructor())
|
||||
return constructor(*_function.annotation().contract);
|
||||
|
||||
return "fun_" + _function.name() + "_" + to_string(_function.id()) + "$" + canonicalTypeName(_type) + "$";
|
||||
return "fun_" + _function.name() + "_" + to_string(_function.id()) + "$" + _env.canonicalTypeName(_type) + "$";
|
||||
}
|
||||
|
||||
string IRNames::function(VariableDeclaration const& _varDecl)
|
||||
|
@ -29,7 +29,7 @@ namespace solidity::frontend::experimental
|
||||
|
||||
struct IRNames
|
||||
{
|
||||
static std::string function(FunctionDefinition const& _function, Type _type);
|
||||
static std::string function(TypeEnvironment const& _env, FunctionDefinition const& _function, Type _type);
|
||||
static std::string function(VariableDeclaration const& _varDecl);
|
||||
static std::string creationObject(ContractDefinition const& _contract);
|
||||
static std::string deployedObject(ContractDefinition const& _contract);
|
||||
|
@ -99,7 +99,7 @@ string IRGenerator::generate(ContractDefinition const& _contract)
|
||||
auto type = m_context.analysis.annotation<TypeInference>(*_contract.fallbackFunction()).type;
|
||||
solAssert(type);
|
||||
type = m_context.env->resolve(*type);
|
||||
code << IRNames::function(*_contract.fallbackFunction(), *type) << "()\n";
|
||||
code << IRNames::function(*m_context.env, *_contract.fallbackFunction(), *type) << "()\n";
|
||||
m_context.enqueueFunctionDefinition(_contract.fallbackFunction(), *type);
|
||||
}
|
||||
code << "revert(0,0)\n";
|
||||
@ -130,7 +130,7 @@ string IRGenerator::generate(FunctionDefinition const& _function, Type _type)
|
||||
solAssert(false, newEnv.typeToString(*type) + " <-> " + newEnv.typeToString(_type));
|
||||
}
|
||||
std::stringstream code;
|
||||
code << "function " << IRNames::function(_function, _type) << "(";
|
||||
code << "function " << IRNames::function(newEnv, _function, _type) << "(";
|
||||
if (_function.parameters().size() > 1)
|
||||
for (auto const& arg: _function.parameters() | ranges::views::drop_last(1))
|
||||
code << IRNames::localVariable(*arg) << ", ";
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include <libsolidity/analysis/experimental/TypeInference.h>
|
||||
#include <libsolidity/analysis/experimental/TypeRegistration.h>
|
||||
|
||||
#include <libsolidity/ast/experimental/TypeSystemHelper.h>
|
||||
|
||||
#include <libyul/YulStack.h>
|
||||
#include <libyul/AsmPrinter.h>
|
||||
#include <libyul/AST.h>
|
||||
@ -173,7 +175,7 @@ bool IRGeneratorForStatements::visit(FunctionCall const& _functionCall)
|
||||
solAssert(expressionAnnotation.type);
|
||||
|
||||
auto typeConstructor = std::get<0>(TypeSystemHelpers{m_context.analysis.typeSystem()}.destTypeConstant(
|
||||
m_context.analysis.typeSystem().env().resolve(*expressionAnnotation.type)
|
||||
m_context.env->resolve(*expressionAnnotation.type)
|
||||
));
|
||||
auto const* typeClass = dynamic_cast<Identifier const*>(&memberAccess->expression());
|
||||
solAssert(typeClass, "Function call to member access only supported for type classes.");
|
||||
@ -201,7 +203,7 @@ bool IRGeneratorForStatements::visit(FunctionCall const& _functionCall)
|
||||
// TODO: get around resolveRecursive by passing the environment further down?
|
||||
functionType = m_context.env->resolveRecursive(*functionType);
|
||||
m_context.enqueueFunctionDefinition(functionDefinition, *functionType);
|
||||
m_code << "let " << IRNames::localVariable(_functionCall) << " := " << IRNames::function(*functionDefinition, *functionType) << "(";
|
||||
m_code << "let " << IRNames::localVariable(_functionCall) << " := " << IRNames::function(*m_context.env, *functionDefinition, *functionType) << "(";
|
||||
auto const& arguments = _functionCall.arguments();
|
||||
if (arguments.size() > 1)
|
||||
for (auto arg: arguments | ranges::views::drop_last(1))
|
||||
|
Loading…
Reference in New Issue
Block a user