/src/solidity/libsolidity/analysis/DeclarationContainer.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | This file is part of solidity. |
3 | | |
4 | | solidity is free software: you can redistribute it and/or modify |
5 | | it under the terms of the GNU General Public License as published by |
6 | | the Free Software Foundation, either version 3 of the License, or |
7 | | (at your option) any later version. |
8 | | |
9 | | solidity is distributed in the hope that it will be useful, |
10 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | | GNU General Public License for more details. |
13 | | |
14 | | You should have received a copy of the GNU General Public License |
15 | | along with solidity. If not, see <http://www.gnu.org/licenses/>. |
16 | | */ |
17 | | // SPDX-License-Identifier: GPL-3.0 |
18 | | /** |
19 | | * @author Christian <c@ethdev.com> |
20 | | * @date 2014 |
21 | | * Scope - object that holds declaration of names. |
22 | | */ |
23 | | |
24 | | #pragma once |
25 | | |
26 | | #include <libsolidity/ast/ASTForward.h> |
27 | | #include <liblangutil/Exceptions.h> |
28 | | #include <liblangutil/SourceLocation.h> |
29 | | |
30 | | #include <memory> |
31 | | |
32 | | namespace solidity::frontend |
33 | | { |
34 | | |
35 | | /** |
36 | | * Settings for how the function DeclarationContainer::resolveName operates. |
37 | | */ |
38 | | struct ResolvingSettings |
39 | | { |
40 | | /// if true and there are no matching declarations in the current container, |
41 | | /// recursively searches the enclosing containers as well. |
42 | | bool recursive = false; |
43 | | /// if true, include invisible declaration in the results. |
44 | | bool alsoInvisible = false; |
45 | | /// if true, do not include declarations which can never actually be referenced using their |
46 | | /// name alone (without being qualified with the name of scope in which they are declared). |
47 | | bool onlyVisibleAsUnqualifiedNames = false; |
48 | | }; |
49 | | |
50 | | |
51 | | /** |
52 | | * Container that stores mappings between names and declarations. It also contains a link to the |
53 | | * enclosing scope. |
54 | | */ |
55 | | class DeclarationContainer |
56 | | { |
57 | | public: |
58 | | using Homonyms = std::vector<std::pair<langutil::SourceLocation const*, std::vector<Declaration const*>>>; |
59 | | |
60 | 32.8k | DeclarationContainer() = default; |
61 | | explicit DeclarationContainer(ASTNode const* _enclosingNode, DeclarationContainer* _enclosingContainer): |
62 | | m_enclosingNode(_enclosingNode), |
63 | | m_enclosingContainer(_enclosingContainer) |
64 | 440k | { |
65 | 440k | if (_enclosingContainer) |
66 | 440k | _enclosingContainer->m_innerContainers.emplace_back(this); |
67 | 440k | } |
68 | | /// Registers the declaration in the scope unless its name is already declared or the name is empty. |
69 | | /// @param _name the name to register, if nullptr the intrinsic name of @a _declaration is used. |
70 | | /// @param _location alternative location, used to point at homonymous declarations. |
71 | | /// @param _invisible if true, registers the declaration, reports name clashes but does not return it in @a resolveName. |
72 | | /// @param _update if true, replaces a potential declaration that is already present. |
73 | | /// @returns false if the name was already declared. |
74 | | bool registerDeclaration(Declaration const& _declaration, ASTString const* _name, langutil::SourceLocation const* _location, bool _invisible, bool _update); |
75 | | bool registerDeclaration(Declaration const& _declaration, bool _invisible, bool _update); |
76 | | |
77 | | /// Finds all declarations that in the current scope can be referred to using specified name. |
78 | | /// @param _name the name to look for. |
79 | | /// @param _settings see ResolvingSettings |
80 | | std::vector<Declaration const*> resolveName(ASTString const& _name, ResolvingSettings _settings = ResolvingSettings{}) const; |
81 | 523k | ASTNode const* enclosingNode() const { return m_enclosingNode; } |
82 | 0 | DeclarationContainer const* enclosingContainer() const { return m_enclosingContainer; } |
83 | 46.2k | std::map<ASTString, std::vector<Declaration const*>> const& declarations() const { return m_declarations; } |
84 | | /// @returns whether declaration is valid, and if not also returns previous declaration. |
85 | | Declaration const* conflictingDeclaration(Declaration const& _declaration, ASTString const* _name = nullptr) const; |
86 | | |
87 | | /// Activates a previously inactive (invisible) variable. To be used in C99 scoping for |
88 | | /// VariableDeclarationStatements. |
89 | | void activateVariable(ASTString const& _name); |
90 | | |
91 | | /// @returns true if declaration is currently invisible. |
92 | | bool isInvisible(ASTString const& _name) const; |
93 | | |
94 | | /// @returns existing declaration names similar to @a _name. |
95 | | /// Searches this and all parent containers. |
96 | | std::vector<ASTString> similarNames(ASTString const& _name) const; |
97 | | |
98 | | /// Populates a vector of (location, declaration) pairs, where location is a location of an inner-scope declaration, |
99 | | /// and declaration is the corresponding homonymous outer-scope declaration. |
100 | | void populateHomonyms(std::back_insert_iterator<Homonyms> _it) const; |
101 | | |
102 | | private: |
103 | | ASTNode const* m_enclosingNode = nullptr; |
104 | | DeclarationContainer const* m_enclosingContainer = nullptr; |
105 | | std::vector<DeclarationContainer const*> m_innerContainers; |
106 | | std::map<ASTString, std::vector<Declaration const*>> m_declarations; |
107 | | std::map<ASTString, std::vector<Declaration const*>> m_invisibleDeclarations; |
108 | | /// List of declarations (name and location) to check later for homonymity. |
109 | | std::vector<std::pair<std::string, langutil::SourceLocation const*>> m_homonymCandidates; |
110 | | }; |
111 | | |
112 | | } |