Coverage Report

Created: 2022-08-24 06:55

/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
}