mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Simple aliasing during import.
This commit is contained in:
@@ -56,6 +56,13 @@ Error ASTNode::createTypeError(string const& _description) const
|
||||
return Error(Error::Type::TypeError) << errinfo_sourceLocation(location()) << errinfo_comment(_description);
|
||||
}
|
||||
|
||||
SourceUnitAnnotation& SourceUnit::annotation() const
|
||||
{
|
||||
if (!m_annotation)
|
||||
m_annotation = new SourceUnitAnnotation();
|
||||
return static_cast<SourceUnitAnnotation&>(*m_annotation);
|
||||
}
|
||||
|
||||
ImportAnnotation& ImportDirective::annotation() const
|
||||
{
|
||||
if (!m_annotation)
|
||||
@@ -63,6 +70,12 @@ ImportAnnotation& ImportDirective::annotation() const
|
||||
return static_cast<ImportAnnotation&>(*m_annotation);
|
||||
}
|
||||
|
||||
TypePointer ImportDirective::type() const
|
||||
{
|
||||
solAssert(!!annotation().sourceUnit, "");
|
||||
return make_shared<ModuleType>(*annotation().sourceUnit);
|
||||
}
|
||||
|
||||
map<FixedHash<4>, FunctionTypePointer> ContractDefinition::interfaceFunctions() const
|
||||
{
|
||||
auto exportedFunctionList = interfaceFunctionList();
|
||||
|
||||
+41
-38
@@ -120,6 +120,7 @@ public:
|
||||
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
virtual SourceUnitAnnotation& annotation() const override;
|
||||
|
||||
std::vector<ASTPointer<ASTNode>> nodes() const { return m_nodes; }
|
||||
|
||||
@@ -128,44 +129,7 @@ private:
|
||||
};
|
||||
|
||||
/**
|
||||
* Import directive for referencing other files / source objects.
|
||||
* Example: import "abc.sol" // imports all symbols of "abc.sol" into current scope
|
||||
* Source objects are identified by a string which can be a file name but does not have to be.
|
||||
* Other ways to use it:
|
||||
* import "abc" as x; // creates symbol "x" that contains all symbols in "abc"
|
||||
* import * as x from "abc"; // same as above
|
||||
* import {a as b, c} from "abc"; // creates new symbols "b" and "c" referencing "a" and "c" in "abc", respectively.
|
||||
*/
|
||||
class ImportDirective: public ASTNode
|
||||
{
|
||||
public:
|
||||
ImportDirective(
|
||||
SourceLocation const& _location,
|
||||
ASTPointer<ASTString> const& _path,
|
||||
ASTPointer<ASTString> const& _unitAlias,
|
||||
std::vector<std::pair<ASTPointer<Identifier>, ASTPointer<ASTString>>>&& _symbolAliases
|
||||
):
|
||||
ASTNode(_location), m_path(_path), m_unitAlias(_unitAlias), m_symbolAliases(_symbolAliases) {}
|
||||
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
|
||||
ASTString const& path() const { return *m_path; }
|
||||
virtual ImportAnnotation& annotation() const override;
|
||||
|
||||
private:
|
||||
ASTPointer<ASTString> m_path;
|
||||
/// The alias for the module itself. If present, import the whole unit under that name and
|
||||
/// ignore m_symbolAlias.
|
||||
ASTPointer<ASTString> m_unitAlias;
|
||||
/// The aliases for the specific symbols to import. If non-empty import the specific symbols.
|
||||
/// If the second component is empty, import the identifier unchanged.
|
||||
/// If both m_unitAlias and m_symbolAlias are empty, import all symbols into the current scope.
|
||||
std::vector<std::pair<ASTPointer<Identifier>, ASTPointer<ASTString>>> m_symbolAliases;
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract AST class for a declaration (contract, function, struct, variable).
|
||||
* Abstract AST class for a declaration (contract, function, struct, variable, import directive).
|
||||
*/
|
||||
class Declaration: public ASTNode
|
||||
{
|
||||
@@ -210,6 +174,45 @@ private:
|
||||
ASTNode const* m_scope;
|
||||
};
|
||||
|
||||
/**
|
||||
* Import directive for referencing other files / source objects.
|
||||
* Example: import "abc.sol" // imports all symbols of "abc.sol" into current scope
|
||||
* Source objects are identified by a string which can be a file name but does not have to be.
|
||||
* Other ways to use it:
|
||||
* import "abc" as x; // creates symbol "x" that contains all symbols in "abc"
|
||||
* import * as x from "abc"; // same as above
|
||||
* import {a as b, c} from "abc"; // creates new symbols "b" and "c" referencing "a" and "c" in "abc", respectively.
|
||||
*/
|
||||
class ImportDirective: public Declaration
|
||||
{
|
||||
public:
|
||||
ImportDirective(
|
||||
SourceLocation const& _location,
|
||||
ASTPointer<ASTString> const& _path,
|
||||
ASTPointer<ASTString> const& _unitAlias,
|
||||
std::vector<std::pair<ASTPointer<Identifier>, ASTPointer<ASTString>>>&& _symbolAliases
|
||||
):
|
||||
Declaration(_location, _unitAlias),
|
||||
m_path(_path),
|
||||
m_symbolAliases(_symbolAliases)
|
||||
{ }
|
||||
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
|
||||
ASTString const& path() const { return *m_path; }
|
||||
virtual ImportAnnotation& annotation() const override;
|
||||
|
||||
virtual TypePointer type() const override;
|
||||
|
||||
private:
|
||||
ASTPointer<ASTString> m_path;
|
||||
/// The aliases for the specific symbols to import. If non-empty import the specific symbols.
|
||||
/// If the second component is empty, import the identifier unchanged.
|
||||
/// If both m_unitAlias and m_symbolAlias are empty, import all symbols into the current scope.
|
||||
std::vector<std::pair<ASTPointer<Identifier>, ASTPointer<ASTString>>> m_symbolAliases;
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract class that is added to each AST node that can store local variables.
|
||||
*/
|
||||
|
||||
@@ -54,10 +54,20 @@ struct DocumentedAnnotation
|
||||
std::multimap<std::string, DocTag> docTags;
|
||||
};
|
||||
|
||||
struct SourceUnitAnnotation: ASTAnnotation
|
||||
{
|
||||
/// The "absolute" (in the compiler sense) path of this source unit.
|
||||
std::string path;
|
||||
/// The exported symbols (all global symbols).
|
||||
std::map<ASTString, std::vector<Declaration const*>> exportedSymbols;
|
||||
};
|
||||
|
||||
struct ImportAnnotation: ASTAnnotation
|
||||
{
|
||||
/// The absolute path of the source unit to import.
|
||||
std::string absolutePath;
|
||||
/// The actual source unit.
|
||||
SourceUnit const* sourceUnit = nullptr;
|
||||
};
|
||||
|
||||
struct TypeDeclarationAnnotation: ASTAnnotation
|
||||
|
||||
@@ -1925,9 +1925,25 @@ string ModifierType::toString(bool _short) const
|
||||
return name + ")";
|
||||
}
|
||||
|
||||
MagicType::MagicType(MagicType::Kind _kind):
|
||||
m_kind(_kind)
|
||||
bool ModuleType::operator==(Type const& _other) const
|
||||
{
|
||||
if (_other.category() != category())
|
||||
return false;
|
||||
return &m_sourceUnit == &dynamic_cast<ModuleType const&>(_other).m_sourceUnit;
|
||||
}
|
||||
|
||||
MemberList::MemberMap ModuleType::nativeMembers(ContractDefinition const*) const
|
||||
{
|
||||
MemberList::MemberMap symbols;
|
||||
for (auto const& symbolName: m_sourceUnit.annotation().exportedSymbols)
|
||||
for (Declaration const* symbol: symbolName.second)
|
||||
symbols.push_back(MemberList::Member(symbolName.first, symbol->type(), symbol));
|
||||
return symbols;
|
||||
}
|
||||
|
||||
string ModuleType::toString(bool) const
|
||||
{
|
||||
return string("module \"") + m_sourceUnit.annotation().path + string("\"");
|
||||
}
|
||||
|
||||
bool MagicType::operator==(Type const& _other) const
|
||||
|
||||
+30
-2
@@ -134,7 +134,7 @@ public:
|
||||
{
|
||||
Integer, IntegerConstant, StringLiteral, Bool, Real, Array,
|
||||
FixedBytes, Contract, Struct, Function, Enum, Tuple,
|
||||
Mapping, TypeType, Modifier, Magic
|
||||
Mapping, TypeType, Modifier, Magic, Module
|
||||
};
|
||||
|
||||
/// @{
|
||||
@@ -969,6 +969,34 @@ private:
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Special type for imported modules. These mainly give access to their scope via members.
|
||||
*/
|
||||
class ModuleType: public Type
|
||||
{
|
||||
public:
|
||||
virtual Category category() const override { return Category::Module; }
|
||||
|
||||
explicit ModuleType(SourceUnit const& _source): m_sourceUnit(_source) {}
|
||||
|
||||
virtual TypePointer binaryOperatorResult(Token::Value, TypePointer const&) const override
|
||||
{
|
||||
return TypePointer();
|
||||
}
|
||||
|
||||
virtual bool operator==(Type const& _other) const override;
|
||||
virtual bool canBeStored() const override { return false; }
|
||||
virtual bool canLiveOutsideStorage() const override { return true; }
|
||||
virtual unsigned sizeOnStack() const override { return 0; }
|
||||
virtual MemberList::MemberMap nativeMembers(ContractDefinition const*) const override;
|
||||
|
||||
virtual std::string toString(bool _short) const override;
|
||||
|
||||
private:
|
||||
SourceUnit const& m_sourceUnit;
|
||||
};
|
||||
|
||||
/**
|
||||
* Special type for magic variables (block, msg, tx), similar to a struct but without any reference
|
||||
* (it always references a global singleton by name).
|
||||
@@ -979,7 +1007,7 @@ public:
|
||||
enum class Kind { Block, Message, Transaction };
|
||||
virtual Category category() const override { return Category::Magic; }
|
||||
|
||||
explicit MagicType(Kind _kind);
|
||||
explicit MagicType(Kind _kind): m_kind(_kind) {}
|
||||
|
||||
virtual TypePointer binaryOperatorResult(Token::Value, TypePointer const&) const override
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user