implement ProjectInstance.GetItems() which is now actually used.
[mono.git] / mcs / class / Mono.CompilerServices.SymbolWriter / SourceMethodBuilder.cs
1 //
2 // SourceMethodBuilder.cs
3 //
4 // Authors:
5 //   Martin Baulig (martin@ximian.com)
6 //   Marek Safar (marek.safar@gmail.com)
7 //
8 // (C) 2002 Ximian, Inc.  http://www.ximian.com
9 // Copyright (C) 2012 Xamarin Inc (http://www.xamarin.com)
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30
31 using System.Collections.Generic;
32
33 namespace Mono.CompilerServices.SymbolWriter
34 {
35         public class SourceMethodBuilder
36         {
37                 List<LocalVariableEntry> _locals;
38                 List<CodeBlockEntry> _blocks;
39                 List<ScopeVariable> _scope_vars;
40                 Stack<CodeBlockEntry> _block_stack;
41                 readonly List<LineNumberEntry> method_lines;
42
43                 readonly ICompileUnit _comp_unit;
44                 readonly int ns_id;
45                 readonly IMethodDef method;
46
47                 public SourceMethodBuilder (ICompileUnit comp_unit)
48                 {
49                         this._comp_unit = comp_unit;
50                         method_lines = new List<LineNumberEntry> ();
51                 }
52
53                 public SourceMethodBuilder (ICompileUnit comp_unit, int ns_id, IMethodDef method)
54                         : this (comp_unit)
55                 {
56                         this.ns_id = ns_id;
57                         this.method = method;
58                 }
59
60                 public void MarkSequencePoint (int offset, SourceFileEntry file, int line, int column, bool is_hidden)
61                 {
62                         int file_idx = file != null ? file.Index : 0;
63                         var lne = new LineNumberEntry (file_idx, line, column, offset, is_hidden);
64
65                         if (method_lines.Count > 0) {
66                                 var prev = method_lines[method_lines.Count - 1];
67
68                                 //
69                                 // Same offset cannot be used for multiple lines
70                                 // 
71                                 if (prev.Offset == offset) {
72                                         //
73                                         // Use the new location because debugger will adjust
74                                         // the breakpoint to next line with sequence point
75                                         //
76                                         if (LineNumberEntry.LocationComparer.Default.Compare (lne, prev) > 0)
77                                                 method_lines[method_lines.Count - 1] = lne;
78
79                                         return;
80                                 }
81                         }
82
83                         method_lines.Add (lne);
84                 }
85
86                 public void StartBlock (CodeBlockEntry.Type type, int start_offset)
87                 {
88                         if (_block_stack == null) {
89                                 _block_stack = new Stack<CodeBlockEntry> ();
90                         }
91                         
92                         if (_blocks == null)
93                                 _blocks = new List<CodeBlockEntry> ();
94
95                         int parent = CurrentBlock != null ? CurrentBlock.Index : -1;
96
97                         CodeBlockEntry block = new CodeBlockEntry (
98                                 _blocks.Count + 1, parent, type, start_offset);
99
100                         _block_stack.Push (block);
101                         _blocks.Add (block);
102                 }
103
104                 public void EndBlock (int end_offset)
105                 {
106                         CodeBlockEntry block = (CodeBlockEntry) _block_stack.Pop ();
107                         block.Close (end_offset);
108                 }
109
110                 public CodeBlockEntry[] Blocks {
111                         get {
112                                 if (_blocks == null)
113                                         return new CodeBlockEntry [0];
114
115                                 CodeBlockEntry[] retval = new CodeBlockEntry [_blocks.Count];
116                                 _blocks.CopyTo (retval, 0);
117                                 return retval;
118                         }
119                 }
120
121                 public CodeBlockEntry CurrentBlock {
122                         get {
123                                 if ((_block_stack != null) && (_block_stack.Count > 0))
124                                         return (CodeBlockEntry) _block_stack.Peek ();
125                                 else
126                                         return null;
127                         }
128                 }
129
130                 public LocalVariableEntry[] Locals {
131                         get {
132                                 if (_locals == null)
133                                         return new LocalVariableEntry [0];
134                                 else {
135                                         return _locals.ToArray ();
136                                 }
137                         }
138                 }
139
140                 public ICompileUnit SourceFile {
141                         get {
142                                 return _comp_unit;
143                         }
144                 }
145
146                 public void AddLocal (int index, string name)
147                 {
148                         if (_locals == null)
149                                 _locals = new List<LocalVariableEntry> ();
150                         int block_idx = CurrentBlock != null ? CurrentBlock.Index : 0;
151                         _locals.Add (new LocalVariableEntry (index, name, block_idx));
152                 }
153
154                 public ScopeVariable[] ScopeVariables {
155                         get {
156                                 if (_scope_vars == null)
157                                         return new ScopeVariable [0];
158
159                                 return _scope_vars.ToArray ();
160                         }
161                 }
162
163                 public void AddScopeVariable (int scope, int index)
164                 {
165                         if (_scope_vars == null)
166                                 _scope_vars = new List<ScopeVariable> ();
167                         _scope_vars.Add (
168                                 new ScopeVariable (scope, index));
169                 }
170
171                 public void DefineMethod (MonoSymbolFile file)
172                 {
173                         DefineMethod (file, method.Token);
174                 }
175
176                 public void DefineMethod (MonoSymbolFile file, int token)
177                 {
178                         MethodEntry entry = new MethodEntry (
179                                 file, _comp_unit.Entry, token, ScopeVariables,
180                                 Locals, method_lines.ToArray (), Blocks, null, MethodEntry.Flags.ColumnsInfoIncluded, ns_id);
181
182                         file.AddMethod (entry);
183                 }
184         }
185 }