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;
40 Stack<CodeBlockEntry> _block_stack;
41 readonly List<LineNumberEntry> method_lines;
43 readonly ICompileUnit _comp_unit;
45 readonly IMethodDef method;
47 public SourceMethodBuilder (ICompileUnit comp_unit)
49 this._comp_unit = comp_unit;
50 method_lines = new List<LineNumberEntry> ();
53 public SourceMethodBuilder (ICompileUnit comp_unit, int ns_id, IMethodDef method)
60 public void MarkSequencePoint (int offset, SourceFileEntry file, int line, int column, bool is_hidden)
62 int file_idx = file != null ? file.Index : 0;
63 var lne = new LineNumberEntry (file_idx, line, column, offset, is_hidden);
65 if (method_lines.Count > 0) {
66 var prev = method_lines[method_lines.Count - 1];
69 // Same offset cannot be used for multiple lines
71 if (prev.Offset == offset) {
73 // Use the new location because debugger will adjust
74 // the breakpoint to next line with sequence point
76 if (LineNumberEntry.LocationComparer.Default.Compare (lne, prev) > 0)
77 method_lines[method_lines.Count - 1] = lne;
83 method_lines.Add (lne);
86 public void StartBlock (CodeBlockEntry.Type type, int start_offset)
88 if (_block_stack == null) {
89 _block_stack = new Stack<CodeBlockEntry> ();
93 _blocks = new List<CodeBlockEntry> ();
95 int parent = CurrentBlock != null ? CurrentBlock.Index : -1;
97 CodeBlockEntry block = new CodeBlockEntry (
98 _blocks.Count + 1, parent, type, start_offset);
100 _block_stack.Push (block);
104 public void EndBlock (int end_offset)
106 CodeBlockEntry block = (CodeBlockEntry) _block_stack.Pop ();
107 block.Close (end_offset);
110 public CodeBlockEntry[] Blocks {
113 return new CodeBlockEntry [0];
115 CodeBlockEntry[] retval = new CodeBlockEntry [_blocks.Count];
116 _blocks.CopyTo (retval, 0);
121 public CodeBlockEntry CurrentBlock {
123 if ((_block_stack != null) && (_block_stack.Count > 0))
124 return (CodeBlockEntry) _block_stack.Peek ();
130 public LocalVariableEntry[] Locals {
133 return new LocalVariableEntry [0];
135 return _locals.ToArray ();
140 public ICompileUnit SourceFile {
146 public void AddLocal (int index, string name)
149 _locals = new List<LocalVariableEntry> ();
150 int block_idx = CurrentBlock != null ? CurrentBlock.Index : 0;
151 _locals.Add (new LocalVariableEntry (index, name, block_idx));
154 public ScopeVariable[] ScopeVariables {
156 if (_scope_vars == null)
157 return new ScopeVariable [0];
159 return _scope_vars.ToArray ();
163 public void AddScopeVariable (int scope, int index)
165 if (_scope_vars == null)
166 _scope_vars = new List<ScopeVariable> ();
168 new ScopeVariable (scope, index));
171 public void DefineMethod (MonoSymbolFile file)
173 DefineMethod (file, method.Token);
176 public void DefineMethod (MonoSymbolFile file, int token)
178 MethodEntry entry = new MethodEntry (
179 file, _comp_unit.Entry, token, ScopeVariables,
180 Locals, method_lines.ToArray (), Blocks, null, MethodEntry.Flags.ColumnsInfoIncluded, ns_id);
182 file.AddMethod (entry);