Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2817-BinPackingSpeedup/HeuristicLab.ExtLibs/HeuristicLab.NRefactory/5.5.0/NRefactory.CSharp-5.5.0/Parser/mcs/SourceMethodBuilder.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// 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
31using System.Collections.Generic;
32
33namespace 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      MarkSequencePoint (offset, file, line, column, -1, -1, is_hidden);
63    }
64
65    public void MarkSequencePoint (int offset, SourceFileEntry file, int line, int column, int end_line, int end_column, bool is_hidden)
66    {
67      int file_idx = file != null ? file.Index : 0;
68      var lne = new LineNumberEntry (file_idx, line, column, end_line, end_column, offset, is_hidden);
69
70      if (method_lines.Count > 0) {
71        var prev = method_lines[method_lines.Count - 1];
72
73        //
74        // Same offset cannot be used for multiple lines
75        //
76        if (prev.Offset == offset) {
77          //
78          // Use the new location because debugger will adjust
79          // the breakpoint to next line with sequence point
80          //
81          if (LineNumberEntry.LocationComparer.Default.Compare (lne, prev) > 0)
82            method_lines[method_lines.Count - 1] = lne;
83
84          return;
85        }
86      }
87
88      method_lines.Add (lne);
89    }
90
91    public void StartBlock (CodeBlockEntry.Type type, int start_offset)
92    {
93      if (_block_stack == null) {
94        _block_stack = new Stack<CodeBlockEntry> ();
95      }
96     
97      if (_blocks == null)
98        _blocks = new List<CodeBlockEntry> ();
99
100      int parent = CurrentBlock != null ? CurrentBlock.Index : -1;
101
102      CodeBlockEntry block = new CodeBlockEntry (
103        _blocks.Count + 1, parent, type, start_offset);
104
105      _block_stack.Push (block);
106      _blocks.Add (block);
107    }
108
109    public void EndBlock (int end_offset)
110    {
111      CodeBlockEntry block = (CodeBlockEntry) _block_stack.Pop ();
112      block.Close (end_offset);
113    }
114
115    public CodeBlockEntry[] Blocks {
116      get {
117        if (_blocks == null)
118          return new CodeBlockEntry [0];
119
120        CodeBlockEntry[] retval = new CodeBlockEntry [_blocks.Count];
121        _blocks.CopyTo (retval, 0);
122        return retval;
123      }
124    }
125
126    public CodeBlockEntry CurrentBlock {
127      get {
128        if ((_block_stack != null) && (_block_stack.Count > 0))
129          return (CodeBlockEntry) _block_stack.Peek ();
130        else
131          return null;
132      }
133    }
134
135    public LocalVariableEntry[] Locals {
136      get {
137        if (_locals == null)
138          return new LocalVariableEntry [0];
139        else {
140          return _locals.ToArray ();
141        }
142      }
143    }
144
145    public ICompileUnit SourceFile {
146      get {
147        return _comp_unit;
148      }
149    }
150
151    public void AddLocal (int index, string name)
152    {
153      if (_locals == null)
154        _locals = new List<LocalVariableEntry> ();
155      int block_idx = CurrentBlock != null ? CurrentBlock.Index : 0;
156      _locals.Add (new LocalVariableEntry (index, name, block_idx));
157    }
158
159    public ScopeVariable[] ScopeVariables {
160      get {
161        if (_scope_vars == null)
162          return new ScopeVariable [0];
163
164        return _scope_vars.ToArray ();
165      }
166    }
167
168    public void AddScopeVariable (int scope, int index)
169    {
170      if (_scope_vars == null)
171        _scope_vars = new List<ScopeVariable> ();
172      _scope_vars.Add (
173        new ScopeVariable (scope, index));
174    }
175
176    public void DefineMethod (MonoSymbolFile file)
177    {
178      DefineMethod (file, method.Token);
179    }
180
181    public void DefineMethod (MonoSymbolFile file, int token)
182    {
183      MethodEntry entry = new MethodEntry (
184        file, _comp_unit.Entry, token, ScopeVariables,
185        Locals, method_lines.ToArray (), Blocks, null, MethodEntry.Flags.ColumnsInfoIncluded, ns_id);
186
187      file.AddMethod (entry);
188    }
189  }
190}
Note: See TracBrowser for help on using the repository browser.