2 // SourceMethodBuilder.cs
5 // Martin Baulig (martin@ximian.com)
6 // Marek Safar (marek.safar@gmail.com)
8 // (C) 2002 Ximian, Inc. http://www.ximian.com
9 // Copyright (C) 2012 Xamarin Inc (http://www.xamarin.com)
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:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
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.
31 using System.Collections.Generic;
33 namespace Mono.CompilerServices.SymbolWriter
35 public class SourceMethodBuilder
37 List<LocalVariableEntry> _locals;
38 List<CodeBlockEntry> _blocks;
39 List<ScopeVariable> _scope_vars;
41 System.Collections.Stack _block_stack;
43 Stack<CodeBlockEntry> _block_stack;
45 readonly List<LineNumberEntry> method_lines;
47 readonly ICompileUnit _comp_unit;
49 readonly IMethodDef method;
51 public SourceMethodBuilder (ICompileUnit comp_unit)
53 this._comp_unit = comp_unit;
54 method_lines = new List<LineNumberEntry> ();
57 public SourceMethodBuilder (ICompileUnit comp_unit, int ns_id, IMethodDef method)
64 public void MarkSequencePoint (int offset, SourceFileEntry file, int line, int column, bool is_hidden)
66 int file_idx = file != null ? file.Index : 0;
67 var lne = new LineNumberEntry (file_idx, line, column, offset, is_hidden);
69 if (method_lines.Count > 0) {
70 var prev = method_lines[method_lines.Count - 1];
73 // Same offset cannot be used for multiple lines
75 if (prev.Offset == offset) {
77 // Use the new location because debugger will adjust
78 // the breakpoint to next line with sequence point
80 if (LineNumberEntry.LocationComparer.Default.Compare (lne, prev) > 0)
81 method_lines[method_lines.Count - 1] = lne;
87 method_lines.Add (lne);
90 public void StartBlock (CodeBlockEntry.Type type, int start_offset)
92 if (_block_stack == null) {
94 _block_stack = new System.Collections.Stack ();
96 _block_stack = new Stack<CodeBlockEntry> ();
101 _blocks = new List<CodeBlockEntry> ();
103 int parent = CurrentBlock != null ? CurrentBlock.Index : -1;
105 CodeBlockEntry block = new CodeBlockEntry (
106 _blocks.Count + 1, parent, type, start_offset);
108 _block_stack.Push (block);
112 public void EndBlock (int end_offset)
114 CodeBlockEntry block = (CodeBlockEntry) _block_stack.Pop ();
115 block.Close (end_offset);
118 public CodeBlockEntry[] Blocks {
121 return new CodeBlockEntry [0];
123 CodeBlockEntry[] retval = new CodeBlockEntry [_blocks.Count];
124 _blocks.CopyTo (retval, 0);
129 public CodeBlockEntry CurrentBlock {
131 if ((_block_stack != null) && (_block_stack.Count > 0))
132 return (CodeBlockEntry) _block_stack.Peek ();
138 public LocalVariableEntry[] Locals {
141 return new LocalVariableEntry [0];
143 return _locals.ToArray ();
148 public ICompileUnit SourceFile {
154 public void AddLocal (int index, string name)
157 _locals = new List<LocalVariableEntry> ();
158 int block_idx = CurrentBlock != null ? CurrentBlock.Index : 0;
159 _locals.Add (new LocalVariableEntry (index, name, block_idx));
162 public ScopeVariable[] ScopeVariables {
164 if (_scope_vars == null)
165 return new ScopeVariable [0];
167 return _scope_vars.ToArray ();
171 public void AddScopeVariable (int scope, int index)
173 if (_scope_vars == null)
174 _scope_vars = new List<ScopeVariable> ();
176 new ScopeVariable (scope, index));
179 public void DefineMethod (MonoSymbolFile file)
181 DefineMethod (file, method.Token);
184 public void DefineMethod (MonoSymbolFile file, int token)
186 MethodEntry entry = new MethodEntry (
187 file, _comp_unit.Entry, token, ScopeVariables,
188 Locals, method_lines.ToArray (), Blocks, null, MethodEntry.Flags.ColumnsInfoIncluded, ns_id);
190 file.AddMethod (entry);