Browse Source

Added some missing mcs files.

newNRvisualizers
Mike Krüger 15 years ago
parent
commit
bfb071de89
  1. 754
      ICSharpCode.NRefactory/CSharp/Parser/mcs/CryptoConvert.cs
  2. 729
      ICSharpCode.NRefactory/CSharp/Parser/mcs/MonoSymbolFile.cs
  3. 1376
      ICSharpCode.NRefactory/CSharp/Parser/mcs/MonoSymbolTable.cs
  4. 403
      ICSharpCode.NRefactory/CSharp/Parser/mcs/MonoSymbolWriter.cs
  5. 1024
      ICSharpCode.NRefactory/CSharp/Parser/mcs/outline.cs

754
ICSharpCode.NRefactory/CSharp/Parser/mcs/CryptoConvert.cs

@ -0,0 +1,754 @@ @@ -0,0 +1,754 @@
//
// CryptoConvert.cs - Crypto Convertion Routines
//
// Author:
// Sebastien Pouliot <sebastien@ximian.com>
//
// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
// Copyright (C) 2004-2006 Novell Inc. (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Globalization;
using System.Security.Cryptography;
using System.Text;
namespace Mono.Security.Cryptography {
#if INSIDE_CORLIB
internal
#else
public
#endif
sealed class CryptoConvert {
private CryptoConvert ()
{
}
static private int ToInt32LE (byte [] bytes, int offset)
{
return (bytes [offset+3] << 24) | (bytes [offset+2] << 16) | (bytes [offset+1] << 8) | bytes [offset];
}
static private uint ToUInt32LE (byte [] bytes, int offset)
{
return (uint)((bytes [offset+3] << 24) | (bytes [offset+2] << 16) | (bytes [offset+1] << 8) | bytes [offset]);
}
static private byte [] GetBytesLE (int val)
{
return new byte [] {
(byte) (val & 0xff),
(byte) ((val >> 8) & 0xff),
(byte) ((val >> 16) & 0xff),
(byte) ((val >> 24) & 0xff)
};
}
static private byte[] Trim (byte[] array)
{
for (int i=0; i < array.Length; i++) {
if (array [i] != 0x00) {
byte[] result = new byte [array.Length - i];
Buffer.BlockCopy (array, i, result, 0, result.Length);
return result;
}
}
return null;
}
// convert the key from PRIVATEKEYBLOB to RSA
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/Security/private_key_blobs.asp
// e.g. SNK files, PVK files
static public RSA FromCapiPrivateKeyBlob (byte[] blob)
{
return FromCapiPrivateKeyBlob (blob, 0);
}
static public RSA FromCapiPrivateKeyBlob (byte[] blob, int offset)
{
if (blob == null)
throw new ArgumentNullException ("blob");
if (offset >= blob.Length)
throw new ArgumentException ("blob is too small.");
RSAParameters rsap = new RSAParameters ();
try {
if ((blob [offset] != 0x07) || // PRIVATEKEYBLOB (0x07)
(blob [offset+1] != 0x02) || // Version (0x02)
(blob [offset+2] != 0x00) || // Reserved (word)
(blob [offset+3] != 0x00) ||
(ToUInt32LE (blob, offset+8) != 0x32415352)) // DWORD magic = RSA2
throw new CryptographicException ("Invalid blob header");
// ALGID (CALG_RSA_SIGN, CALG_RSA_KEYX, ...)
// int algId = ToInt32LE (blob, offset+4);
// DWORD bitlen
int bitLen = ToInt32LE (blob, offset+12);
// DWORD public exponent
byte[] exp = new byte [4];
Buffer.BlockCopy (blob, offset+16, exp, 0, 4);
Array.Reverse (exp);
rsap.Exponent = Trim (exp);
int pos = offset+20;
// BYTE modulus[rsapubkey.bitlen/8];
int byteLen = (bitLen >> 3);
rsap.Modulus = new byte [byteLen];
Buffer.BlockCopy (blob, pos, rsap.Modulus, 0, byteLen);
Array.Reverse (rsap.Modulus);
pos += byteLen;
// BYTE prime1[rsapubkey.bitlen/16];
int byteHalfLen = (byteLen >> 1);
rsap.P = new byte [byteHalfLen];
Buffer.BlockCopy (blob, pos, rsap.P, 0, byteHalfLen);
Array.Reverse (rsap.P);
pos += byteHalfLen;
// BYTE prime2[rsapubkey.bitlen/16];
rsap.Q = new byte [byteHalfLen];
Buffer.BlockCopy (blob, pos, rsap.Q, 0, byteHalfLen);
Array.Reverse (rsap.Q);
pos += byteHalfLen;
// BYTE exponent1[rsapubkey.bitlen/16];
rsap.DP = new byte [byteHalfLen];
Buffer.BlockCopy (blob, pos, rsap.DP, 0, byteHalfLen);
Array.Reverse (rsap.DP);
pos += byteHalfLen;
// BYTE exponent2[rsapubkey.bitlen/16];
rsap.DQ = new byte [byteHalfLen];
Buffer.BlockCopy (blob, pos, rsap.DQ, 0, byteHalfLen);
Array.Reverse (rsap.DQ);
pos += byteHalfLen;
// BYTE coefficient[rsapubkey.bitlen/16];
rsap.InverseQ = new byte [byteHalfLen];
Buffer.BlockCopy (blob, pos, rsap.InverseQ, 0, byteHalfLen);
Array.Reverse (rsap.InverseQ);
pos += byteHalfLen;
// ok, this is hackish but CryptoAPI support it so...
// note: only works because CRT is used by default
// http://bugzilla.ximian.com/show_bug.cgi?id=57941
rsap.D = new byte [byteLen]; // must be allocated
if (pos + byteLen + offset <= blob.Length) {
// BYTE privateExponent[rsapubkey.bitlen/8];
Buffer.BlockCopy (blob, pos, rsap.D, 0, byteLen);
Array.Reverse (rsap.D);
}
}
catch (Exception e) {
throw new CryptographicException ("Invalid blob.", e);
}
#if NET_2_1
RSA rsa = RSA.Create ();
rsa.ImportParameters (rsap);
#else
RSA rsa = null;
try {
rsa = RSA.Create ();
rsa.ImportParameters (rsap);
}
catch (CryptographicException ce) {
// this may cause problem when this code is run under
// the SYSTEM identity on Windows (e.g. ASP.NET). See
// http://bugzilla.ximian.com/show_bug.cgi?id=77559
try {
CspParameters csp = new CspParameters ();
csp.Flags = CspProviderFlags.UseMachineKeyStore;
rsa = new RSACryptoServiceProvider (csp);
rsa.ImportParameters (rsap);
}
catch {
// rethrow original, not the later, exception if this fails
throw ce;
}
}
#endif
return rsa;
}
static public DSA FromCapiPrivateKeyBlobDSA (byte[] blob)
{
return FromCapiPrivateKeyBlobDSA (blob, 0);
}
static public DSA FromCapiPrivateKeyBlobDSA (byte[] blob, int offset)
{
if (blob == null)
throw new ArgumentNullException ("blob");
if (offset >= blob.Length)
throw new ArgumentException ("blob is too small.");
DSAParameters dsap = new DSAParameters ();
try {
if ((blob [offset] != 0x07) || // PRIVATEKEYBLOB (0x07)
(blob [offset + 1] != 0x02) || // Version (0x02)
(blob [offset + 2] != 0x00) || // Reserved (word)
(blob [offset + 3] != 0x00) ||
(ToUInt32LE (blob, offset + 8) != 0x32535344)) // DWORD magic
throw new CryptographicException ("Invalid blob header");
int bitlen = ToInt32LE (blob, offset + 12);
int bytelen = bitlen >> 3;
int pos = offset + 16;
dsap.P = new byte [bytelen];
Buffer.BlockCopy (blob, pos, dsap.P, 0, bytelen);
Array.Reverse (dsap.P);
pos += bytelen;
dsap.Q = new byte [20];
Buffer.BlockCopy (blob, pos, dsap.Q, 0, 20);
Array.Reverse (dsap.Q);
pos += 20;
dsap.G = new byte [bytelen];
Buffer.BlockCopy (blob, pos, dsap.G, 0, bytelen);
Array.Reverse (dsap.G);
pos += bytelen;
dsap.X = new byte [20];
Buffer.BlockCopy (blob, pos, dsap.X, 0, 20);
Array.Reverse (dsap.X);
pos += 20;
dsap.Counter = ToInt32LE (blob, pos);
pos += 4;
dsap.Seed = new byte [20];
Buffer.BlockCopy (blob, pos, dsap.Seed, 0, 20);
Array.Reverse (dsap.Seed);
pos += 20;
}
catch (Exception e) {
throw new CryptographicException ("Invalid blob.", e);
}
#if NET_2_1
DSA dsa = (DSA)DSA.Create ();
dsa.ImportParameters (dsap);
#else
DSA dsa = null;
try {
dsa = (DSA)DSA.Create ();
dsa.ImportParameters (dsap);
}
catch (CryptographicException ce) {
// this may cause problem when this code is run under
// the SYSTEM identity on Windows (e.g. ASP.NET). See
// http://bugzilla.ximian.com/show_bug.cgi?id=77559
try {
CspParameters csp = new CspParameters ();
csp.Flags = CspProviderFlags.UseMachineKeyStore;
dsa = new DSACryptoServiceProvider (csp);
dsa.ImportParameters (dsap);
}
catch {
// rethrow original, not the later, exception if this fails
throw ce;
}
}
#endif
return dsa;
}
static public byte[] ToCapiPrivateKeyBlob (RSA rsa)
{
RSAParameters p = rsa.ExportParameters (true);
int keyLength = p.Modulus.Length; // in bytes
byte[] blob = new byte [20 + (keyLength << 2) + (keyLength >> 1)];
blob [0] = 0x07; // Type - PRIVATEKEYBLOB (0x07)
blob [1] = 0x02; // Version - Always CUR_BLOB_VERSION (0x02)
// [2], [3] // RESERVED - Always 0
blob [5] = 0x24; // ALGID - Always 00 24 00 00 (for CALG_RSA_SIGN)
blob [8] = 0x52; // Magic - RSA2 (ASCII in hex)
blob [9] = 0x53;
blob [10] = 0x41;
blob [11] = 0x32;
byte[] bitlen = GetBytesLE (keyLength << 3);
blob [12] = bitlen [0]; // bitlen
blob [13] = bitlen [1];
blob [14] = bitlen [2];
blob [15] = bitlen [3];
// public exponent (DWORD)
int pos = 16;
int n = p.Exponent.Length;
while (n > 0)
blob [pos++] = p.Exponent [--n];
// modulus
pos = 20;
byte[] part = p.Modulus;
int len = part.Length;
Array.Reverse (part, 0, len);
Buffer.BlockCopy (part, 0, blob, pos, len);
pos += len;
// private key
part = p.P;
len = part.Length;
Array.Reverse (part, 0, len);
Buffer.BlockCopy (part, 0, blob, pos, len);
pos += len;
part = p.Q;
len = part.Length;
Array.Reverse (part, 0, len);
Buffer.BlockCopy (part, 0, blob, pos, len);
pos += len;
part = p.DP;
len = part.Length;
Array.Reverse (part, 0, len);
Buffer.BlockCopy (part, 0, blob, pos, len);
pos += len;
part = p.DQ;
len = part.Length;
Array.Reverse (part, 0, len);
Buffer.BlockCopy (part, 0, blob, pos, len);
pos += len;
part = p.InverseQ;
len = part.Length;
Array.Reverse (part, 0, len);
Buffer.BlockCopy (part, 0, blob, pos, len);
pos += len;
part = p.D;
len = part.Length;
Array.Reverse (part, 0, len);
Buffer.BlockCopy (part, 0, blob, pos, len);
return blob;
}
static public byte[] ToCapiPrivateKeyBlob (DSA dsa)
{
DSAParameters p = dsa.ExportParameters (true);
int keyLength = p.P.Length; // in bytes
// header + P + Q + G + X + count + seed
byte[] blob = new byte [16 + keyLength + 20 + keyLength + 20 + 4 + 20];
blob [0] = 0x07; // Type - PRIVATEKEYBLOB (0x07)
blob [1] = 0x02; // Version - Always CUR_BLOB_VERSION (0x02)
// [2], [3] // RESERVED - Always 0
blob [5] = 0x22; // ALGID
blob [8] = 0x44; // Magic
blob [9] = 0x53;
blob [10] = 0x53;
blob [11] = 0x32;
byte[] bitlen = GetBytesLE (keyLength << 3);
blob [12] = bitlen [0];
blob [13] = bitlen [1];
blob [14] = bitlen [2];
blob [15] = bitlen [3];
int pos = 16;
byte[] part = p.P;
Array.Reverse (part);
Buffer.BlockCopy (part, 0, blob, pos, keyLength);
pos += keyLength;
part = p.Q;
Array.Reverse (part);
Buffer.BlockCopy (part, 0, blob, pos, 20);
pos += 20;
part = p.G;
Array.Reverse (part);
Buffer.BlockCopy (part, 0, blob, pos, keyLength);
pos += keyLength;
part = p.X;
Array.Reverse (part);
Buffer.BlockCopy (part, 0, blob, pos, 20);
pos += 20;
Buffer.BlockCopy (GetBytesLE (p.Counter), 0, blob, pos, 4);
pos += 4;
part = p.Seed;
Array.Reverse (part);
Buffer.BlockCopy (part, 0, blob, pos, 20);
return blob;
}
static public RSA FromCapiPublicKeyBlob (byte[] blob)
{
return FromCapiPublicKeyBlob (blob, 0);
}
static public RSA FromCapiPublicKeyBlob (byte[] blob, int offset)
{
if (blob == null)
throw new ArgumentNullException ("blob");
if (offset >= blob.Length)
throw new ArgumentException ("blob is too small.");
try {
if ((blob [offset] != 0x06) || // PUBLICKEYBLOB (0x06)
(blob [offset+1] != 0x02) || // Version (0x02)
(blob [offset+2] != 0x00) || // Reserved (word)
(blob [offset+3] != 0x00) ||
(ToUInt32LE (blob, offset+8) != 0x31415352)) // DWORD magic = RSA1
throw new CryptographicException ("Invalid blob header");
// ALGID (CALG_RSA_SIGN, CALG_RSA_KEYX, ...)
// int algId = ToInt32LE (blob, offset+4);
// DWORD bitlen
int bitLen = ToInt32LE (blob, offset+12);
// DWORD public exponent
RSAParameters rsap = new RSAParameters ();
rsap.Exponent = new byte [3];
rsap.Exponent [0] = blob [offset+18];
rsap.Exponent [1] = blob [offset+17];
rsap.Exponent [2] = blob [offset+16];
int pos = offset+20;
// BYTE modulus[rsapubkey.bitlen/8];
int byteLen = (bitLen >> 3);
rsap.Modulus = new byte [byteLen];
Buffer.BlockCopy (blob, pos, rsap.Modulus, 0, byteLen);
Array.Reverse (rsap.Modulus);
#if NET_2_1
RSA rsa = RSA.Create ();
rsa.ImportParameters (rsap);
#else
RSA rsa = null;
try {
rsa = RSA.Create ();
rsa.ImportParameters (rsap);
}
catch (CryptographicException) {
// this may cause problem when this code is run under
// the SYSTEM identity on Windows (e.g. ASP.NET). See
// http://bugzilla.ximian.com/show_bug.cgi?id=77559
CspParameters csp = new CspParameters ();
csp.Flags = CspProviderFlags.UseMachineKeyStore;
rsa = new RSACryptoServiceProvider (csp);
rsa.ImportParameters (rsap);
}
#endif
return rsa;
}
catch (Exception e) {
throw new CryptographicException ("Invalid blob.", e);
}
}
static public DSA FromCapiPublicKeyBlobDSA (byte[] blob)
{
return FromCapiPublicKeyBlobDSA (blob, 0);
}
static public DSA FromCapiPublicKeyBlobDSA (byte[] blob, int offset)
{
if (blob == null)
throw new ArgumentNullException ("blob");
if (offset >= blob.Length)
throw new ArgumentException ("blob is too small.");
try {
if ((blob [offset] != 0x06) || // PUBLICKEYBLOB (0x06)
(blob [offset + 1] != 0x02) || // Version (0x02)
(blob [offset + 2] != 0x00) || // Reserved (word)
(blob [offset + 3] != 0x00) ||
(ToUInt32LE (blob, offset + 8) != 0x31535344)) // DWORD magic
throw new CryptographicException ("Invalid blob header");
int bitlen = ToInt32LE (blob, offset + 12);
DSAParameters dsap = new DSAParameters ();
int bytelen = bitlen >> 3;
int pos = offset + 16;
dsap.P = new byte [bytelen];
Buffer.BlockCopy (blob, pos, dsap.P, 0, bytelen);
Array.Reverse (dsap.P);
pos += bytelen;
dsap.Q = new byte [20];
Buffer.BlockCopy (blob, pos, dsap.Q, 0, 20);
Array.Reverse (dsap.Q);
pos += 20;
dsap.G = new byte [bytelen];
Buffer.BlockCopy (blob, pos, dsap.G, 0, bytelen);
Array.Reverse (dsap.G);
pos += bytelen;
dsap.Y = new byte [bytelen];
Buffer.BlockCopy (blob, pos, dsap.Y, 0, bytelen);
Array.Reverse (dsap.Y);
pos += bytelen;
dsap.Counter = ToInt32LE (blob, pos);
pos += 4;
dsap.Seed = new byte [20];
Buffer.BlockCopy (blob, pos, dsap.Seed, 0, 20);
Array.Reverse (dsap.Seed);
pos += 20;
DSA dsa = (DSA)DSA.Create ();
dsa.ImportParameters (dsap);
return dsa;
}
catch (Exception e) {
throw new CryptographicException ("Invalid blob.", e);
}
}
static public byte[] ToCapiPublicKeyBlob (RSA rsa)
{
RSAParameters p = rsa.ExportParameters (false);
int keyLength = p.Modulus.Length; // in bytes
byte[] blob = new byte [20 + keyLength];
blob [0] = 0x06; // Type - PUBLICKEYBLOB (0x06)
blob [1] = 0x02; // Version - Always CUR_BLOB_VERSION (0x02)
// [2], [3] // RESERVED - Always 0
blob [5] = 0x24; // ALGID - Always 00 24 00 00 (for CALG_RSA_SIGN)
blob [8] = 0x52; // Magic - RSA1 (ASCII in hex)
blob [9] = 0x53;
blob [10] = 0x41;
blob [11] = 0x31;
byte[] bitlen = GetBytesLE (keyLength << 3);
blob [12] = bitlen [0]; // bitlen
blob [13] = bitlen [1];
blob [14] = bitlen [2];
blob [15] = bitlen [3];
// public exponent (DWORD)
int pos = 16;
int n = p.Exponent.Length;
while (n > 0)
blob [pos++] = p.Exponent [--n];
// modulus
pos = 20;
byte[] part = p.Modulus;
int len = part.Length;
Array.Reverse (part, 0, len);
Buffer.BlockCopy (part, 0, blob, pos, len);
pos += len;
return blob;
}
static public byte[] ToCapiPublicKeyBlob (DSA dsa)
{
DSAParameters p = dsa.ExportParameters (false);
int keyLength = p.P.Length; // in bytes
// header + P + Q + G + Y + count + seed
byte[] blob = new byte [16 + keyLength + 20 + keyLength + keyLength + 4 + 20];
blob [0] = 0x06; // Type - PUBLICKEYBLOB (0x06)
blob [1] = 0x02; // Version - Always CUR_BLOB_VERSION (0x02)
// [2], [3] // RESERVED - Always 0
blob [5] = 0x22; // ALGID
blob [8] = 0x44; // Magic
blob [9] = 0x53;
blob [10] = 0x53;
blob [11] = 0x31;
byte[] bitlen = GetBytesLE (keyLength << 3);
blob [12] = bitlen [0];
blob [13] = bitlen [1];
blob [14] = bitlen [2];
blob [15] = bitlen [3];
int pos = 16;
byte[] part;
part = p.P;
Array.Reverse (part);
Buffer.BlockCopy (part, 0, blob, pos, keyLength);
pos += keyLength;
part = p.Q;
Array.Reverse (part);
Buffer.BlockCopy (part, 0, blob, pos, 20);
pos += 20;
part = p.G;
Array.Reverse (part);
Buffer.BlockCopy (part, 0, blob, pos, keyLength);
pos += keyLength;
part = p.Y;
Array.Reverse (part);
Buffer.BlockCopy (part, 0, blob, pos, keyLength);
pos += keyLength;
Buffer.BlockCopy (GetBytesLE (p.Counter), 0, blob, pos, 4);
pos += 4;
part = p.Seed;
Array.Reverse (part);
Buffer.BlockCopy (part, 0, blob, pos, 20);
return blob;
}
// PRIVATEKEYBLOB
// PUBLICKEYBLOB
static public RSA FromCapiKeyBlob (byte[] blob)
{
return FromCapiKeyBlob (blob, 0);
}
static public RSA FromCapiKeyBlob (byte[] blob, int offset)
{
if (blob == null)
throw new ArgumentNullException ("blob");
if (offset >= blob.Length)
throw new ArgumentException ("blob is too small.");
switch (blob [offset]) {
case 0x00:
// this could be a public key inside an header
// like "sn -e" would produce
if (blob [offset + 12] == 0x06) {
return FromCapiPublicKeyBlob (blob, offset + 12);
}
break;
case 0x06:
return FromCapiPublicKeyBlob (blob, offset);
case 0x07:
return FromCapiPrivateKeyBlob (blob, offset);
}
throw new CryptographicException ("Unknown blob format.");
}
static public DSA FromCapiKeyBlobDSA (byte[] blob)
{
return FromCapiKeyBlobDSA (blob, 0);
}
static public DSA FromCapiKeyBlobDSA (byte[] blob, int offset)
{
if (blob == null)
throw new ArgumentNullException ("blob");
if (offset >= blob.Length)
throw new ArgumentException ("blob is too small.");
switch (blob [offset]) {
case 0x06:
return FromCapiPublicKeyBlobDSA (blob, offset);
case 0x07:
return FromCapiPrivateKeyBlobDSA (blob, offset);
}
throw new CryptographicException ("Unknown blob format.");
}
static public byte[] ToCapiKeyBlob (AsymmetricAlgorithm keypair, bool includePrivateKey)
{
if (keypair == null)
throw new ArgumentNullException ("keypair");
// check between RSA and DSA (and potentially others like DH)
if (keypair is RSA)
return ToCapiKeyBlob ((RSA)keypair, includePrivateKey);
else if (keypair is DSA)
return ToCapiKeyBlob ((DSA)keypair, includePrivateKey);
else
return null; // TODO
}
static public byte[] ToCapiKeyBlob (RSA rsa, bool includePrivateKey)
{
if (rsa == null)
throw new ArgumentNullException ("rsa");
if (includePrivateKey)
return ToCapiPrivateKeyBlob (rsa);
else
return ToCapiPublicKeyBlob (rsa);
}
static public byte[] ToCapiKeyBlob (DSA dsa, bool includePrivateKey)
{
if (dsa == null)
throw new ArgumentNullException ("dsa");
if (includePrivateKey)
return ToCapiPrivateKeyBlob (dsa);
else
return ToCapiPublicKeyBlob (dsa);
}
static public string ToHex (byte[] input)
{
if (input == null)
return null;
StringBuilder sb = new StringBuilder (input.Length * 2);
foreach (byte b in input) {
sb.Append (b.ToString ("X2", CultureInfo.InvariantCulture));
}
return sb.ToString ();
}
static private byte FromHexChar (char c)
{
if ((c >= 'a') && (c <= 'f'))
return (byte) (c - 'a' + 10);
if ((c >= 'A') && (c <= 'F'))
return (byte) (c - 'A' + 10);
if ((c >= '0') && (c <= '9'))
return (byte) (c - '0');
throw new ArgumentException ("invalid hex char");
}
static public byte[] FromHex (string hex)
{
if (hex == null)
return null;
if ((hex.Length & 0x1) == 0x1)
throw new ArgumentException ("Length must be a multiple of 2");
byte[] result = new byte [hex.Length >> 1];
int n = 0;
int i = 0;
while (n < result.Length) {
result [n] = (byte) (FromHexChar (hex [i++]) << 4);
result [n++] += FromHexChar (hex [i++]);
}
return result;
}
}
}

729
ICSharpCode.NRefactory/CSharp/Parser/mcs/MonoSymbolFile.cs

@ -0,0 +1,729 @@ @@ -0,0 +1,729 @@
//
// Mono.CSharp.Debugger/MonoSymbolFile.cs
//
// Author:
// Martin Baulig (martin@ximian.com)
//
// (C) 2003 Ximian, Inc. http://www.ximian.com
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Reflection;
using SRE = System.Reflection.Emit;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.IO;
namespace Mono.CompilerServices.SymbolWriter
{
public class MonoSymbolFileException : Exception
{
public MonoSymbolFileException ()
: base ()
{ }
public MonoSymbolFileException (string message, params object[] args)
: base (String.Format (message, args))
{ }
}
internal class MyBinaryWriter : BinaryWriter
{
public MyBinaryWriter (Stream stream)
: base (stream)
{ }
public void WriteLeb128 (int value)
{
base.Write7BitEncodedInt (value);
}
}
internal class MyBinaryReader : BinaryReader
{
public MyBinaryReader (Stream stream)
: base (stream)
{ }
public int ReadLeb128 ()
{
return base.Read7BitEncodedInt ();
}
public string ReadString (int offset)
{
long old_pos = BaseStream.Position;
BaseStream.Position = offset;
string text = ReadString ();
BaseStream.Position = old_pos;
return text;
}
}
public interface ISourceFile
{
SourceFileEntry Entry {
get;
}
}
public interface ICompileUnit
{
CompileUnitEntry Entry {
get;
}
}
public interface IMethodDef
{
string Name {
get;
}
int Token {
get;
}
}
#if !CECIL
internal class MonoDebuggerSupport
{
static GetMethodTokenFunc get_method_token;
static GetGuidFunc get_guid;
static GetLocalIndexFunc get_local_index;
delegate int GetMethodTokenFunc (MethodBase method);
delegate Guid GetGuidFunc (Module module);
delegate int GetLocalIndexFunc (SRE.LocalBuilder local);
static Delegate create_delegate (Type type, Type delegate_type, string name)
{
MethodInfo mi = type.GetMethod (name, BindingFlags.Static |
BindingFlags.NonPublic);
if (mi == null)
throw new Exception ("Can't find " + name);
return Delegate.CreateDelegate (delegate_type, mi);
}
static MonoDebuggerSupport ()
{
get_method_token = (GetMethodTokenFunc) create_delegate (
typeof (Assembly), typeof (GetMethodTokenFunc),
"MonoDebugger_GetMethodToken");
get_guid = (GetGuidFunc) create_delegate (
typeof (Module), typeof (GetGuidFunc), "Mono_GetGuid");
get_local_index = (GetLocalIndexFunc) create_delegate (
typeof (SRE.LocalBuilder), typeof (GetLocalIndexFunc),
"Mono_GetLocalIndex");
}
public static int GetMethodToken (MethodBase method)
{
return get_method_token (method);
}
public static Guid GetGuid (Module module)
{
return get_guid (module);
}
public static int GetLocalIndex (SRE.LocalBuilder local)
{
return get_local_index (local);
}
}
#endif
public class MonoSymbolFile : IDisposable
{
List<MethodEntry> methods = new List<MethodEntry> ();
List<SourceFileEntry> sources = new List<SourceFileEntry> ();
List<CompileUnitEntry> comp_units = new List<CompileUnitEntry> ();
Dictionary<Type, int> type_hash = new Dictionary<Type, int> ();
Dictionary<int, AnonymousScopeEntry> anonymous_scopes;
OffsetTable ot;
int last_type_index;
int last_method_index;
int last_namespace_index;
public readonly string FileName = "<dynamic>";
public readonly int MajorVersion = OffsetTable.MajorVersion;
public readonly int MinorVersion = OffsetTable.MinorVersion;
public int NumLineNumbers;
internal MonoSymbolFile ()
{
ot = new OffsetTable ();
}
internal int AddSource (SourceFileEntry source)
{
sources.Add (source);
return sources.Count;
}
internal int AddCompileUnit (CompileUnitEntry entry)
{
comp_units.Add (entry);
return comp_units.Count;
}
internal int DefineType (Type type)
{
int index;
if (type_hash.TryGetValue (type, out index))
return index;
index = ++last_type_index;
type_hash.Add (type, index);
return index;
}
internal void AddMethod (MethodEntry entry)
{
methods.Add (entry);
}
public MethodEntry DefineMethod (CompileUnitEntry comp_unit, int token,
ScopeVariable[] scope_vars, LocalVariableEntry[] locals,
LineNumberEntry[] lines, CodeBlockEntry[] code_blocks,
string real_name, MethodEntry.Flags flags,
int namespace_id)
{
if (reader != null)
throw new InvalidOperationException ();
MethodEntry method = new MethodEntry (
this, comp_unit, token, scope_vars, locals, lines, code_blocks,
real_name, flags, namespace_id);
AddMethod (method);
return method;
}
internal void DefineAnonymousScope (int id)
{
if (reader != null)
throw new InvalidOperationException ();
if (anonymous_scopes == null)
anonymous_scopes = new Dictionary<int, AnonymousScopeEntry> ();
anonymous_scopes.Add (id, new AnonymousScopeEntry (id));
}
internal void DefineCapturedVariable (int scope_id, string name, string captured_name,
CapturedVariable.CapturedKind kind)
{
if (reader != null)
throw new InvalidOperationException ();
AnonymousScopeEntry scope = anonymous_scopes [scope_id];
scope.AddCapturedVariable (name, captured_name, kind);
}
internal void DefineCapturedScope (int scope_id, int id, string captured_name)
{
if (reader != null)
throw new InvalidOperationException ();
AnonymousScopeEntry scope = anonymous_scopes [scope_id];
scope.AddCapturedScope (id, captured_name);
}
internal int GetNextTypeIndex ()
{
return ++last_type_index;
}
internal int GetNextMethodIndex ()
{
return ++last_method_index;
}
internal int GetNextNamespaceIndex ()
{
return ++last_namespace_index;
}
void Write (MyBinaryWriter bw, Guid guid)
{
// Magic number and file version.
bw.Write (OffsetTable.Magic);
bw.Write (MajorVersion);
bw.Write (MinorVersion);
bw.Write (guid.ToByteArray ());
//
// Offsets of file sections; we must write this after we're done
// writing the whole file, so we just reserve the space for it here.
//
long offset_table_offset = bw.BaseStream.Position;
ot.Write (bw, MajorVersion, MinorVersion);
//
// Sort the methods according to their tokens and update their index.
//
methods.Sort ();
for (int i = 0; i < methods.Count; i++)
((MethodEntry) methods [i]).Index = i + 1;
//
// Write data sections.
//
ot.DataSectionOffset = (int) bw.BaseStream.Position;
foreach (SourceFileEntry source in sources)
source.WriteData (bw);
foreach (CompileUnitEntry comp_unit in comp_units)
comp_unit.WriteData (bw);
foreach (MethodEntry method in methods)
method.WriteData (this, bw);
ot.DataSectionSize = (int) bw.BaseStream.Position - ot.DataSectionOffset;
//
// Write the method index table.
//
ot.MethodTableOffset = (int) bw.BaseStream.Position;
for (int i = 0; i < methods.Count; i++) {
MethodEntry entry = (MethodEntry) methods [i];
entry.Write (bw);
}
ot.MethodTableSize = (int) bw.BaseStream.Position - ot.MethodTableOffset;
//
// Write source table.
//
ot.SourceTableOffset = (int) bw.BaseStream.Position;
for (int i = 0; i < sources.Count; i++) {
SourceFileEntry source = (SourceFileEntry) sources [i];
source.Write (bw);
}
ot.SourceTableSize = (int) bw.BaseStream.Position - ot.SourceTableOffset;
//
// Write compilation unit table.
//
ot.CompileUnitTableOffset = (int) bw.BaseStream.Position;
for (int i = 0; i < comp_units.Count; i++) {
CompileUnitEntry unit = (CompileUnitEntry) comp_units [i];
unit.Write (bw);
}
ot.CompileUnitTableSize = (int) bw.BaseStream.Position - ot.CompileUnitTableOffset;
//
// Write anonymous scope table.
//
ot.AnonymousScopeCount = anonymous_scopes != null ? anonymous_scopes.Count : 0;
ot.AnonymousScopeTableOffset = (int) bw.BaseStream.Position;
if (anonymous_scopes != null) {
foreach (AnonymousScopeEntry scope in anonymous_scopes.Values)
scope.Write (bw);
}
ot.AnonymousScopeTableSize = (int) bw.BaseStream.Position - ot.AnonymousScopeTableOffset;
//
// Fixup offset table.
//
ot.TypeCount = last_type_index;
ot.MethodCount = methods.Count;
ot.SourceCount = sources.Count;
ot.CompileUnitCount = comp_units.Count;
//
// Write offset table.
//
ot.TotalFileSize = (int) bw.BaseStream.Position;
bw.Seek ((int) offset_table_offset, SeekOrigin.Begin);
ot.Write (bw, MajorVersion, MinorVersion);
bw.Seek (0, SeekOrigin.End);
#if false
Console.WriteLine ("TOTAL: {0} line numbes, {1} bytes, extended {2} bytes, " +
"{3} methods.", NumLineNumbers, LineNumberSize,
ExtendedLineNumberSize, methods.Count);
#endif
}
public void CreateSymbolFile (Guid guid, FileStream fs)
{
if (reader != null)
throw new InvalidOperationException ();
Write (new MyBinaryWriter (fs), guid);
}
MyBinaryReader reader;
Dictionary<int, SourceFileEntry> source_file_hash;
Dictionary<int, CompileUnitEntry> compile_unit_hash;
List<MethodEntry> method_list;
Dictionary<int, MethodEntry> method_token_hash;
Dictionary<string, int> source_name_hash;
Guid guid;
MonoSymbolFile (string filename)
{
this.FileName = filename;
FileStream stream = new FileStream (filename, FileMode.Open, FileAccess.Read);
reader = new MyBinaryReader (stream);
try {
long magic = reader.ReadInt64 ();
int major_version = reader.ReadInt32 ();
int minor_version = reader.ReadInt32 ();
if (magic != OffsetTable.Magic)
throw new MonoSymbolFileException (
"Symbol file `{0}' is not a valid " +
"Mono symbol file", filename);
if (major_version != OffsetTable.MajorVersion)
throw new MonoSymbolFileException (
"Symbol file `{0}' has version {1}, " +
"but expected {2}", filename, major_version,
OffsetTable.MajorVersion);
if (minor_version != OffsetTable.MinorVersion)
throw new MonoSymbolFileException (
"Symbol file `{0}' has version {1}.{2}, " +
"but expected {3}.{4}", filename, major_version,
minor_version, OffsetTable.MajorVersion,
OffsetTable.MinorVersion);
MajorVersion = major_version;
MinorVersion = minor_version;
guid = new Guid (reader.ReadBytes (16));
ot = new OffsetTable (reader, major_version, minor_version);
} catch {
throw new MonoSymbolFileException (
"Cannot read symbol file `{0}'", filename);
}
source_file_hash = new Dictionary<int, SourceFileEntry> ();
compile_unit_hash = new Dictionary<int, CompileUnitEntry> ();
}
void CheckGuidMatch (Guid other, string filename, string assembly)
{
if (other == guid)
return;
throw new MonoSymbolFileException (
"Symbol file `{0}' does not match assembly `{1}'",
filename, assembly);
}
#if CECIL
protected MonoSymbolFile (string filename, Mono.Cecil.AssemblyDefinition assembly) : this (filename)
{
Guid mvid = assembly.MainModule.Mvid;
CheckGuidMatch (mvid, filename, assembly.MainModule.Image.FileInformation.FullName);
}
public static MonoSymbolFile ReadSymbolFile (Mono.Cecil.AssemblyDefinition assembly, string filename)
{
string name = filename + ".mdb";
return new MonoSymbolFile (name, assembly);
}
#else
protected MonoSymbolFile (string filename, Assembly assembly) : this (filename)
{
// Check that the MDB file matches the assembly, if we have been
// passed an assembly.
if (assembly == null)
return;
Module[] modules = assembly.GetModules ();
Guid assembly_guid = MonoDebuggerSupport.GetGuid (modules [0]);
CheckGuidMatch (assembly_guid, filename, assembly.Location);
}
public static MonoSymbolFile ReadSymbolFile (Assembly assembly)
{
string filename = assembly.Location;
string name = filename + ".mdb";
return new MonoSymbolFile (name, assembly);
}
#endif
public static MonoSymbolFile ReadSymbolFile (string mdbFilename)
{
return new MonoSymbolFile (mdbFilename, null);
}
public int CompileUnitCount {
get { return ot.CompileUnitCount; }
}
public int SourceCount {
get { return ot.SourceCount; }
}
public int MethodCount {
get { return ot.MethodCount; }
}
public int TypeCount {
get { return ot.TypeCount; }
}
public int AnonymousScopeCount {
get { return ot.AnonymousScopeCount; }
}
public int NamespaceCount {
get { return last_namespace_index; }
}
public Guid Guid {
get { return guid; }
}
public OffsetTable OffsetTable {
get { return ot; }
}
internal int LineNumberCount = 0;
internal int LocalCount = 0;
internal int StringSize = 0;
internal int LineNumberSize = 0;
internal int ExtendedLineNumberSize = 0;
public SourceFileEntry GetSourceFile (int index)
{
if ((index < 1) || (index > ot.SourceCount))
throw new ArgumentException ();
if (reader == null)
throw new InvalidOperationException ();
lock (this) {
SourceFileEntry source;
if (source_file_hash.TryGetValue (index, out source))
return source;
long old_pos = reader.BaseStream.Position;
reader.BaseStream.Position = ot.SourceTableOffset +
SourceFileEntry.Size * (index - 1);
source = new SourceFileEntry (this, reader);
source_file_hash.Add (index, source);
reader.BaseStream.Position = old_pos;
return source;
}
}
public SourceFileEntry[] Sources {
get {
if (reader == null)
throw new InvalidOperationException ();
SourceFileEntry[] retval = new SourceFileEntry [SourceCount];
for (int i = 0; i < SourceCount; i++)
retval [i] = GetSourceFile (i + 1);
return retval;
}
}
public CompileUnitEntry GetCompileUnit (int index)
{
if ((index < 1) || (index > ot.CompileUnitCount))
throw new ArgumentException ();
if (reader == null)
throw new InvalidOperationException ();
lock (this) {
CompileUnitEntry unit;
if (compile_unit_hash.TryGetValue (index, out unit))
return unit;
long old_pos = reader.BaseStream.Position;
reader.BaseStream.Position = ot.CompileUnitTableOffset +
CompileUnitEntry.Size * (index - 1);
unit = new CompileUnitEntry (this, reader);
compile_unit_hash.Add (index, unit);
reader.BaseStream.Position = old_pos;
return unit;
}
}
public CompileUnitEntry[] CompileUnits {
get {
if (reader == null)
throw new InvalidOperationException ();
CompileUnitEntry[] retval = new CompileUnitEntry [CompileUnitCount];
for (int i = 0; i < CompileUnitCount; i++)
retval [i] = GetCompileUnit (i + 1);
return retval;
}
}
void read_methods ()
{
lock (this) {
if (method_token_hash != null)
return;
method_token_hash = new Dictionary<int, MethodEntry> ();
method_list = new List<MethodEntry> ();
long old_pos = reader.BaseStream.Position;
reader.BaseStream.Position = ot.MethodTableOffset;
for (int i = 0; i < MethodCount; i++) {
MethodEntry entry = new MethodEntry (this, reader, i + 1);
method_token_hash.Add (entry.Token, entry);
method_list.Add (entry);
}
reader.BaseStream.Position = old_pos;
}
}
public MethodEntry GetMethodByToken (int token)
{
if (reader == null)
throw new InvalidOperationException ();
lock (this) {
read_methods ();
MethodEntry me;
method_token_hash.TryGetValue (token, out me);
return me;
}
}
public MethodEntry GetMethod (int index)
{
if ((index < 1) || (index > ot.MethodCount))
throw new ArgumentException ();
if (reader == null)
throw new InvalidOperationException ();
lock (this) {
read_methods ();
return (MethodEntry) method_list [index - 1];
}
}
public MethodEntry[] Methods {
get {
if (reader == null)
throw new InvalidOperationException ();
lock (this) {
read_methods ();
MethodEntry[] retval = new MethodEntry [MethodCount];
method_list.CopyTo (retval, 0);
return retval;
}
}
}
public int FindSource (string file_name)
{
if (reader == null)
throw new InvalidOperationException ();
lock (this) {
if (source_name_hash == null) {
source_name_hash = new Dictionary<string, int> ();
for (int i = 0; i < ot.SourceCount; i++) {
SourceFileEntry source = GetSourceFile (i + 1);
source_name_hash.Add (source.FileName, i);
}
}
int value;
if (!source_name_hash.TryGetValue (file_name, out value))
return -1;
return value;
}
}
public AnonymousScopeEntry GetAnonymousScope (int id)
{
if (reader == null)
throw new InvalidOperationException ();
AnonymousScopeEntry scope;
lock (this) {
if (anonymous_scopes != null) {
anonymous_scopes.TryGetValue (id, out scope);
return scope;
}
anonymous_scopes = new Dictionary<int, AnonymousScopeEntry> ();
reader.BaseStream.Position = ot.AnonymousScopeTableOffset;
for (int i = 0; i < ot.AnonymousScopeCount; i++) {
scope = new AnonymousScopeEntry (reader);
anonymous_scopes.Add (scope.ID, scope);
}
return anonymous_scopes [id];
}
}
internal MyBinaryReader BinaryReader {
get {
if (reader == null)
throw new InvalidOperationException ();
return reader;
}
}
public void Dispose ()
{
Dispose (true);
}
protected virtual void Dispose (bool disposing)
{
if (disposing) {
if (reader != null) {
reader.Close ();
reader = null;
}
}
}
}
}

1376
ICSharpCode.NRefactory/CSharp/Parser/mcs/MonoSymbolTable.cs

File diff suppressed because it is too large Load Diff

403
ICSharpCode.NRefactory/CSharp/Parser/mcs/MonoSymbolWriter.cs

@ -0,0 +1,403 @@ @@ -0,0 +1,403 @@
//
// Mono.CSharp.Debugger/MonoSymbolWriter.cs
//
// Author:
// Martin Baulig (martin@ximian.com)
//
// This is the default implementation of the System.Diagnostics.SymbolStore.ISymbolWriter
// interface.
//
// (C) 2002 Ximian, Inc. http://www.ximian.com
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Runtime.CompilerServices;
using System.Collections.Generic;
using System.IO;
namespace Mono.CompilerServices.SymbolWriter
{
public class MonoSymbolWriter
{
List<SourceMethodBuilder> methods;
List<SourceFileEntry> sources;
List<CompileUnitEntry> comp_units;
protected readonly MonoSymbolFile file;
string filename;
private SourceMethodBuilder current_method;
#if NET_2_1
System.Collections.Stack current_method_stack = new System.Collections.Stack ();
#else
Stack<SourceMethodBuilder> current_method_stack = new Stack<SourceMethodBuilder> ();
#endif
public MonoSymbolWriter (string filename)
{
this.methods = new List<SourceMethodBuilder> ();
this.sources = new List<SourceFileEntry> ();
this.comp_units = new List<CompileUnitEntry> ();
this.file = new MonoSymbolFile ();
this.filename = filename + ".mdb";
}
public MonoSymbolFile SymbolFile {
get { return file; }
}
public void CloseNamespace ()
{ }
public void DefineLocalVariable (int index, string name)
{
if (current_method == null)
return;
current_method.AddLocal (index, name);
}
public void DefineCapturedLocal (int scope_id, string name, string captured_name)
{
file.DefineCapturedVariable (scope_id, name, captured_name,
CapturedVariable.CapturedKind.Local);
}
public void DefineCapturedParameter (int scope_id, string name, string captured_name)
{
file.DefineCapturedVariable (scope_id, name, captured_name,
CapturedVariable.CapturedKind.Parameter);
}
public void DefineCapturedThis (int scope_id, string captured_name)
{
file.DefineCapturedVariable (scope_id, "this", captured_name,
CapturedVariable.CapturedKind.This);
}
public void DefineCapturedScope (int scope_id, int id, string captured_name)
{
file.DefineCapturedScope (scope_id, id, captured_name);
}
public void DefineScopeVariable (int scope, int index)
{
if (current_method == null)
return;
current_method.AddScopeVariable (scope, index);
}
public void MarkSequencePoint (int offset, SourceFileEntry file, int line, int column,
bool is_hidden)
{
if (current_method == null)
return;
current_method.MarkSequencePoint (offset, file, line, column, is_hidden);
}
public SourceMethodBuilder OpenMethod (ICompileUnit file, int ns_id, IMethodDef method)
{
SourceMethodBuilder builder = new SourceMethodBuilder (file, ns_id, method);
current_method_stack.Push (current_method);
current_method = builder;
methods.Add (current_method);
return builder;
}
public void CloseMethod ()
{
current_method = (SourceMethodBuilder) current_method_stack.Pop ();
}
public SourceFileEntry DefineDocument (string url)
{
SourceFileEntry entry = new SourceFileEntry (file, url);
sources.Add (entry);
return entry;
}
public SourceFileEntry DefineDocument (string url, byte[] guid, byte[] checksum)
{
SourceFileEntry entry = new SourceFileEntry (file, url, guid, checksum);
sources.Add (entry);
return entry;
}
public CompileUnitEntry DefineCompilationUnit (SourceFileEntry source)
{
CompileUnitEntry entry = new CompileUnitEntry (file, source);
comp_units.Add (entry);
return entry;
}
public int DefineNamespace (string name, CompileUnitEntry unit,
string[] using_clauses, int parent)
{
if ((unit == null) || (using_clauses == null))
throw new NullReferenceException ();
return unit.DefineNamespace (name, using_clauses, parent);
}
public int OpenScope (int start_offset)
{
if (current_method == null)
return 0;
current_method.StartBlock (CodeBlockEntry.Type.Lexical, start_offset);
return 0;
}
public void CloseScope (int end_offset)
{
if (current_method == null)
return;
current_method.EndBlock (end_offset);
}
public void OpenCompilerGeneratedBlock (int start_offset)
{
if (current_method == null)
return;
current_method.StartBlock (CodeBlockEntry.Type.CompilerGenerated,
start_offset);
}
public void CloseCompilerGeneratedBlock (int end_offset)
{
if (current_method == null)
return;
current_method.EndBlock (end_offset);
}
public void StartIteratorBody (int start_offset)
{
current_method.StartBlock (CodeBlockEntry.Type.IteratorBody,
start_offset);
}
public void EndIteratorBody (int end_offset)
{
current_method.EndBlock (end_offset);
}
public void StartIteratorDispatcher (int start_offset)
{
current_method.StartBlock (CodeBlockEntry.Type.IteratorDispatcher,
start_offset);
}
public void EndIteratorDispatcher (int end_offset)
{
current_method.EndBlock (end_offset);
}
public void DefineAnonymousScope (int id)
{
file.DefineAnonymousScope (id);
}
public void WriteSymbolFile (Guid guid)
{
foreach (SourceMethodBuilder method in methods)
method.DefineMethod (file);
try {
// We mmap the file, so unlink the previous version since it may be in use
File.Delete (filename);
} catch {
// We can safely ignore
}
using (FileStream fs = new FileStream (filename, FileMode.Create, FileAccess.Write)) {
file.CreateSymbolFile (guid, fs);
}
}
}
public class SourceMethodBuilder
{
List<LocalVariableEntry> _locals;
List<CodeBlockEntry> _blocks;
List<ScopeVariable> _scope_vars;
#if NET_2_1
System.Collections.Stack _block_stack;
#else
Stack<CodeBlockEntry> _block_stack;
#endif
string _real_name;
IMethodDef _method;
ICompileUnit _comp_unit;
// MethodEntry.Flags _method_flags;
int _ns_id;
public SourceMethodBuilder (ICompileUnit comp_unit, int ns_id, IMethodDef method)
{
this._comp_unit = comp_unit;
this._method = method;
this._ns_id = ns_id;
method_lines = new LineNumberEntry [32];
}
private LineNumberEntry [] method_lines;
private int method_lines_pos = 0;
public void MarkSequencePoint (int offset, SourceFileEntry file, int line, int column,
bool is_hidden)
{
if (method_lines_pos == method_lines.Length) {
LineNumberEntry [] tmp = method_lines;
method_lines = new LineNumberEntry [method_lines.Length * 2];
Array.Copy (tmp, method_lines, method_lines_pos);
}
int file_idx = file != null ? file.Index : 0;
method_lines [method_lines_pos++] = new LineNumberEntry (
file_idx, line, offset, is_hidden);
}
public void StartBlock (CodeBlockEntry.Type type, int start_offset)
{
if (_block_stack == null) {
#if NET_2_1
_block_stack = new System.Collections.Stack ();
#else
_block_stack = new Stack<CodeBlockEntry> ();
#endif
}
if (_blocks == null)
_blocks = new List<CodeBlockEntry> ();
int parent = CurrentBlock != null ? CurrentBlock.Index : -1;
CodeBlockEntry block = new CodeBlockEntry (
_blocks.Count + 1, parent, type, start_offset);
_block_stack.Push (block);
_blocks.Add (block);
}
public void EndBlock (int end_offset)
{
CodeBlockEntry block = (CodeBlockEntry) _block_stack.Pop ();
block.Close (end_offset);
}
public CodeBlockEntry[] Blocks {
get {
if (_blocks == null)
return new CodeBlockEntry [0];
CodeBlockEntry[] retval = new CodeBlockEntry [_blocks.Count];
_blocks.CopyTo (retval, 0);
return retval;
}
}
public CodeBlockEntry CurrentBlock {
get {
if ((_block_stack != null) && (_block_stack.Count > 0))
return (CodeBlockEntry) _block_stack.Peek ();
else
return null;
}
}
public LocalVariableEntry[] Locals {
get {
if (_locals == null)
return new LocalVariableEntry [0];
else {
LocalVariableEntry[] retval =
new LocalVariableEntry [_locals.Count];
_locals.CopyTo (retval, 0);
return retval;
}
}
}
public void AddLocal (int index, string name)
{
if (_locals == null)
_locals = new List<LocalVariableEntry> ();
int block_idx = CurrentBlock != null ? CurrentBlock.Index : 0;
_locals.Add (new LocalVariableEntry (index, name, block_idx));
}
public ScopeVariable[] ScopeVariables {
get {
if (_scope_vars == null)
return new ScopeVariable [0];
ScopeVariable[] retval = new ScopeVariable [_scope_vars.Count];
_scope_vars.CopyTo (retval);
return retval;
}
}
public void AddScopeVariable (int scope, int index)
{
if (_scope_vars == null)
_scope_vars = new List<ScopeVariable> ();
_scope_vars.Add (
new ScopeVariable (scope, index));
}
public string RealMethodName {
get { return _real_name; }
}
public void SetRealMethodName (string name)
{
_real_name = name;
}
public ICompileUnit SourceFile {
get { return _comp_unit; }
}
public IMethodDef Method {
get { return _method; }
}
public void DefineMethod (MonoSymbolFile file)
{
LineNumberEntry[] lines = new LineNumberEntry [method_lines_pos];
Array.Copy (method_lines, lines, method_lines_pos);
MethodEntry entry = new MethodEntry (
file, _comp_unit.Entry, _method.Token, ScopeVariables,
Locals, lines, Blocks, RealMethodName, 0, //_method_flags,
_ns_id);
file.AddMethod (entry);
}
}
}

1024
ICSharpCode.NRefactory/CSharp/Parser/mcs/outline.cs

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save