Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/HeuristicLab.ExtLibs/HeuristicLab.NRefactory/5.5.0/NRefactory.CSharp-5.5.0/Analysis/DeclarationSpace/LocalDeclarationSpace.cs

Last change on this file was 11700, checked in by jkarder, 10 years ago

#2077: created branch and added first version

File size: 5.2 KB
Line 
1//
2// LovalVariableDeclarationSpace.cs
3// 
4// Author:
5//       Simon Lindgren <simon.n.lindgren@gmail.com>
6//
7// Copyright (c) 2013 Simon Lindgren
8//
9// Permission is hereby granted, free of charge, to any person obtaining a copy
10// of this software and associated documentation files (the "Software"), to deal
11// in the Software without restriction, including without limitation the rights
12// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13// copies of the Software, and to permit persons to whom the Software is
14// furnished to do so, subject to the following conditions:
15//
16// The above copyright notice and this permission notice shall be included in
17// all copies or substantial portions of the Software.
18//
19// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25// THE SOFTWARE.
26using ICSharpCode.NRefactory.Utils;
27using System.Collections.Generic;
28using System.Linq;
29using System;
30
31namespace ICSharpCode.NRefactory.CSharp.Analysis
32{
33  /// <summary>
34  /// Represents a declaration space. (§3.3)
35  /// </summary>
36  public class LocalDeclarationSpace
37  {
38    /// <summary>
39    /// Maps from variable name to the declarations in this declaration space.
40    /// </summary>
41    /// <remarks>
42    /// This maps from variable name
43    /// </remarks>
44    MultiDictionary<string, AstNode> declarations = new MultiDictionary<string, AstNode> ();
45
46    public LocalDeclarationSpace()
47    {
48      Children = new List<LocalDeclarationSpace> ();
49    }
50
51    /// <summary>
52    /// The child declaration spaces.
53    /// </summary>
54    public IList<LocalDeclarationSpace> Children {
55      get;
56      private set;
57    }
58
59    /// <summary>
60    /// The parent declaration space.
61    /// </summary>
62    /// <value>The parent.</value>
63    public LocalDeclarationSpace Parent {
64      get;
65      private set;
66    }
67
68    /// <summary>
69    /// The names declared in this declaration space, excluding child spaces.
70    /// </summary>
71    /// <value>The declared names.</value>
72    public ICollection<string> DeclaredNames {
73      get {
74        return declarations.Keys;
75      }
76    }
77
78    /// <summary>
79    /// Get all nodes declaring the name specified in <paramref name="name"/>.
80    /// </summary>
81    /// <returns>The declaring nodes.</returns>
82    /// <param name="name">The declaration name.</param>
83    public IEnumerable<AstNode> GetNameDeclarations(string name)
84    {
85      return declarations [name].Concat(Children.SelectMany(child => child.GetNameDeclarations(name)));
86    }
87
88    /// <summary>
89    /// Adds a child declaration space.
90    /// </summary>
91    /// <param name="child">The <see cref="LocalDeclarationSpace"/> to add.</param>
92    public void AddChildSpace(LocalDeclarationSpace child)
93    {
94      if (child == null)
95        throw new ArgumentNullException("child");
96      if (Children.Contains(child))
97        throw new InvalidOperationException("the child was already added");
98
99      Children.Add(child);
100      child.Parent = this;
101    }
102
103    /// <summary>
104    /// Adds a new declaration to the declaration space.
105    /// </summary>
106    /// <param name="name">The name of the declared variable.</param>
107    /// <param name="node">A node associated with the declaration.</param>
108    public void AddDeclaration(string name, AstNode node)
109    {
110      if (name == null)
111        throw new ArgumentNullException("name");
112      if (node == null)
113        throw new ArgumentNullException("node");
114      declarations.Add(name, node);
115    }
116
117    /// <summary>
118    /// Determines if the name exists in the this declaration space.
119    /// </summary>
120    /// <returns><c>true</c>, if the name specified in <paramref name="name"/> is used in this variable declaration space, <c>false</c> otherwise.</returns>
121    /// <param name="name">The name to look for.</param>
122    /// <param name="includeChildren">When <c>true</c>, child declaration spaces are included in the search.</param>
123    public bool ContainsName(string name, bool includeChildren)
124    {
125      if (name == null)
126        throw new ArgumentNullException("name");
127
128      if (declarations.Keys.Contains(name))
129        return true;
130      return includeChildren && Children.Any(child => child.ContainsName(name, true));
131    }
132
133    /// <summary>
134    /// Determines whether the name specified in <paramref name="name"/> is used in surrouding code.
135    /// </summary>
136    /// <returns><c>true</c> if the name is used, <c>false</c> otherwise.</returns>
137    /// <param name="name">The name to check.</param>
138    /// <remarks>
139    /// Contrary to <see cref="ContainsName"/>, this method also checks parent declaration spaces
140    /// for name conflicts. Typically, this will be the right method to use when determining if a name can be used.
141    /// </remarks>
142    public bool IsNameUsed(string name)
143    {
144      if (name == null)
145        throw new ArgumentNullException("name");
146
147      return IsNameUsedBySelfOrParent(name) || Children.Any(child => child.ContainsName(name, true));
148    }
149
150    bool IsNameUsedBySelfOrParent(string name)
151    {
152      if (declarations.Keys.Contains(name))
153        return true;
154      return Parent != null && Parent.IsNameUsedBySelfOrParent(name);
155    }
156  }
157}
Note: See TracBrowser for help on using the repository browser.