Unmanaged interfaces
От: Блудов Павел Россия  
Дата: 19.09.06 09:45
Оценка:
    #region MetaDataImport

    [StructLayout(LayoutKind.Sequential)]
    public struct COR_FIELD_OFFSET
    {
        public uint ridOfField;
        public uint ulOffset;
    }

    [ComImport, Guid("7DAC8207-D3AE-4c75-9B67-92801A497D44"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IMetaDataImport
    {
        [PreserveSig]
        void CloseEnum(uint hEnum);
        uint CountEnum(uint hEnum);
        void ResetEnum(uint hEnum, uint ulPos);
        uint EnumTypeDefs(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rTypeDefs, uint cMax);
        uint EnumInterfaceImpls(ref uint phEnum, uint td, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] rImpls, uint cMax);
        uint EnumTypeRefs(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rTypeRefs, uint cMax);
        uint FindTypeDefByName(string szTypeDef, uint tkEnclosingClass);
        Guid GetScopeProps(StringBuilder szName, uint cchName, out uint pchName);
        uint GetModuleFromScope();
        uint GetTypeDefProps(uint td, IntPtr szTypeDef, uint cchTypeDef, out uint pchTypeDef, IntPtr pdwTypeDefFlags);
        uint GetInterfaceImplProps(uint iiImpl, out uint pClass);
        uint GetTypeRefProps(uint tr, out uint ptkResolutionScope, StringBuilder szName, uint cchName);
        uint ResolveTypeRef(uint tr, [In] ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out object ppIScope);
        uint EnumMembers(ref uint phEnum, uint cl, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] rMembers, uint cMax);
        uint EnumMembersWithName(ref uint phEnum, uint cl, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rMembers, uint cMax);
        //uint EnumMethods(ref uint phEnum, uint cl, uint* rMethods, uint cMax);
        uint EnumMethods();
        uint EnumMethodsWithName(ref uint phEnum, uint cl, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rMethods, uint cMax);
        //uint EnumFields(ref uint phEnum, uint cl, uint* rFields, uint cMax);
        uint EnumFields();
        uint EnumFieldsWithName(ref uint phEnum, uint cl, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rFields, uint cMax);
        uint EnumParams(ref uint phEnum, uint mb, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] rParams, uint cMax);
        uint EnumMemberRefs(ref uint phEnum, uint tkParent, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] rMemberRefs, uint cMax);
        uint EnumMethodImpls(ref uint phEnum, uint td, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rMethodBody, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rMethodDecl, uint cMax);
        uint EnumPermissionSets(ref uint phEnum, uint tk, uint dwActions, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rPermission, uint cMax);
        uint FindMember(uint td, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] pvSigBlob, uint cbSigBlob);
        uint FindMethod(uint td, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] pvSigBlob, uint cbSigBlob);
        uint FindField(uint td, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] pvSigBlob, uint cbSigBlob);
        uint FindMemberRef(uint td, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] pvSigBlob, uint cbSigBlob);
        uint GetMethodProps(uint mb, out uint pClass, IntPtr szMethod, uint cchMethod, out uint pchMethod, IntPtr pdwAttr, IntPtr ppvSigBlob, IntPtr pcbSigBlob, IntPtr pulCodeRVA);
        //uint GetMemberRefProps(uint mr, ref uint ptk, StringBuilder szMember, uint cchMember, out uint pchMember, out byte* ppvSigBlob);
        uint GetMemberRefProps();
        //uint EnumProperties(ref uint phEnum, uint td, uint* rProperties, uint cMax);
        uint EnumProperties();
        //uint EnumEvents(ref uint phEnum, uint td, uint* rEvents, uint cMax);
        uint EnumEvents();
        uint GetEventProps(uint ev, out uint pClass, StringBuilder szEvent, uint cchEvent, out uint pchEvent, out uint pdwEventFlags, out uint ptkEventType, out uint pmdAddOn, out uint pmdRemoveOn, out uint pmdFire, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 11)] uint[] rmdOtherMethod, uint cMax);
        uint EnumMethodSemantics(ref uint phEnum, uint mb, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] rEventProp, uint cMax);
        uint GetMethodSemantics(uint mb, uint tkEventProp);
        uint GetClassLayout(uint td, out uint pdwPackSize, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] COR_FIELD_OFFSET[] rFieldOffset, uint cMax, out uint pcFieldOffset);
        //uint GetFieldMarshal(uint tk, out byte* ppvNativeType);
        uint GetFieldMarshal();
        uint GetRVA(uint tk, out uint pulCodeRVA);
        //uint GetPermissionSetProps(uint pm, out uint pdwAction, out void* ppvPermission);
        uint GetPermissionSetProps();
        //uint GetSigFromToken(uint mdSig, out byte* ppvSig);
        uint GetSigFromToken();
        uint GetModuleRefProps(uint mur, StringBuilder szName, uint cchName);
        uint EnumModuleRefs(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rModuleRefs, uint cmax);
        //uint GetTypeSpecFromToken(uint typespec, out byte* ppvSig);
        uint GetTypeSpecFromToken();
        uint GetNameFromToken(uint tk);
        uint EnumUnresolvedMethods(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rMethods, uint cMax);
        uint GetUserString(uint stk, StringBuilder szString, uint cchString);
        uint GetPinvokeMap(uint tk, out uint pdwMappingFlags, StringBuilder szImportName, uint cchImportName, out uint pchImportName);
        uint EnumSignatures(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rSignatures, uint cmax);
        uint EnumTypeSpecs(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rTypeSpecs, uint cmax);
        uint EnumUserStrings(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rStrings, uint cmax);
        [PreserveSig]
        int GetParamForMethodIndex(uint md, uint ulParamSeq, out uint pParam);
        uint EnumCustomAttributes(ref uint phEnum, uint tk, uint tkType, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rCustomAttributes, uint cMax);
        //uint GetCustomAttributeProps(uint cv, out uint ptkObj, out uint ptkType, out void* ppBlob);
        uint GetCustomAttributeProps();
        uint FindTypeRef(uint tkResolutionScope, string szName);
        //uint GetMemberProps(uint mb, out uint pClass, StringBuilder szMember, uint cchMember, out uint pchMember, out uint pdwAttr, out byte* ppvSigBlob, out uint pcbSigBlob, out uint pulCodeRVA, out uint pdwImplFlags, out uint pdwCPlusTypeFlag, out void* ppValue);
        uint GetMemberProps();
        //uint GetFieldProps(uint mb, out uint pClass, StringBuilder szField, uint cchField, out uint pchField, out uint pdwAttr, out byte* ppvSigBlob, out uint pcbSigBlob, out uint pdwCPlusTypeFlag, out void* ppValue);
        uint GetFieldProps();
        //uint GetPropertyProps(uint prop, out uint pClass, StringBuilder szProperty, uint cchProperty, out uint pchProperty, out uint pdwPropFlags, out byte* ppvSig, out uint pbSig, out uint pdwCPlusTypeFlag, out void* ppDefaultValue, out uint pcchDefaultValue, out uint pmdSetter, out uint pmdGetter, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=14)] uint[] rmdOtherMethod, uint cMax);
        uint GetPropertyProps();
        //uint GetParamProps(uint tk, out uint pmd, out uint pulSequence, StringBuilder szName, uint cchName, out uint pchName, out uint pdwAttr, out uint pdwCPlusTypeFlag, out void* ppValue);
        uint GetParamProps();
        //uint GetCustomAttributeByName(uint tkObj, string szName, out void* ppData);
        uint GetCustomAttributeByName();
        [return: MarshalAs(UnmanagedType.Bool)]
        [PreserveSig]
        bool IsValidToken(uint tk);
        uint GetNestedClassProps(uint tdNestedClass);
        //uint GetNativeCallConvFromSig(void* pvSig, uint cbSig);
        uint GetNativeCallConvFromSig();
        int IsGlobal(uint pd);
    }

    [ComImport, Guid("809c652e-7396-11d2-9771-00a0c9b4d50c"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), TypeLibType(TypeLibTypeFlags.FRestricted)]
    internal interface IMetaDataDispenser
    {
        [return: MarshalAs(UnmanagedType.Interface)]
        object DefineScope([In] ref Guid rclsid, [In] uint dwCreateFlags, [In] ref Guid riid);
        [return: MarshalAs(UnmanagedType.Interface)]
        object OpenScope([In, MarshalAs(UnmanagedType.LPWStr)] string szScope, [In] uint dwOpenFlags, [In] ref Guid riid);
        [return: MarshalAs(UnmanagedType.Interface)]
        object OpenScopeOnMemory([In] IntPtr pData, [In] uint cbData, [In] uint dwOpenFlags, [In] ref Guid riid);
    }

    [ComImport, Guid("E5CB7A31-7512-11d2-89CE-0080C792E5D8"), ClassInterface(ClassInterfaceType.None), TypeLibType(TypeLibTypeFlags.FCanCreate)]
    internal class CorMetaDataDispenser
    {
    }

    #endregion MetaDataImport

    #region SymUnmanaged

    [ComImport, Guid("40DE4037-7C81-3E1E-B022-AE1ABFF2CA08"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface ISymUnmanagedDocument
    {
        void GetURL(int size, out uint length, [MarshalAs(UnmanagedType.LPWStr, SizeParamIndex = 0)] StringBuilder url);
        void GetDocumentType(out Guid retval);
        void GetLanguage(out Guid retval);
        void GetLanguageVendor(out Guid retval);
        void GetCheckSumAlgorithmId(out Guid retval);
        void GetCheckSum(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] byte[] data);
        uint FindClosestLine(uint line);
        bool HasEmbeddedSource();
        uint GetSourceLength();
        void GetSourceRange(uint startLine, uint startColumn, uint endLine, uint endColumn, uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] byte[] source);
    }

    [ComImport, Guid("B62B923C-B500-3158-A543-24F307A8B7E1"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface ISymUnmanagedMethod
    {
        uint GetToken();
        uint GetSequencePointCount();
        ISymUnmanagedScope GetRootScope();
        ISymUnmanagedScope GetScopeFromOffset(uint offset);
        uint Getoffset(ISymUnmanagedDocument document, uint line, uint column);
        void GetRanges(ISymUnmanagedDocument document, uint line, uint column, uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] ranges);
        void GetParameters(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] ISymUnmanagedVariable[] parms);
        IntPtr GetNamespace();
        bool GetSourceStartEnd([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0, SizeConst = 2)] ISymUnmanagedDocument[] docs, [MarshalAs(UnmanagedType.LPArray)] uint[] lines, [MarshalAs(UnmanagedType.LPArray)] uint[] columns);
        void GetSequencePoints(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] uint[] offsets, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.IUnknown, SizeParamIndex = 0)] IntPtr[] documents, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] uint[] lines, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] uint[] columns, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] uint[] endLines, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] uint[] endColumns);
    }

    [ComImport, Guid("B4CE6286-2A6B-3712-A3B7-1EE1DAD467B5"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface ISymUnmanagedReader
    {
        ISymUnmanagedDocument GetDocument(string url, ref Guid language, ref Guid languageVendor, ref Guid documentType);
        void GetDocuments(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] ISymUnmanagedDocument[] docs);
        uint GetUserEntryPoint();
        ISymUnmanagedMethod GetMethod(uint token);
        ISymUnmanagedMethod GetMethodByVersion(uint token, int version);
        void GetVariables(uint parent, uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] ISymUnmanagedVariable[] vars);
        void GetGlobalVariables(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] ISymUnmanagedVariable[] vars);
        ISymUnmanagedMethod GetMethodFromDocumentPosition(ISymUnmanagedDocument document, uint line, uint column);
        void GetSymAttribute(uint parent, string name, ulong size, ref uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] buffer);
        void GetNamespaces(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] IntPtr[] namespaces);
        void Initialize([MarshalAs(UnmanagedType.IUnknown)] object importer, string filename, string searchPath, [MarshalAs(UnmanagedType.IUnknown)] object stream);
        void UpdateSymbolStore(string filename, [MarshalAs(UnmanagedType.IUnknown)] object stream);
        void ReplaceSymbolStore(string filename, [MarshalAs(UnmanagedType.IUnknown)] object stream);
        void GetSymbolStoreFileName(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] char[] name);
        void GetMethodsFromDocumentPosition(ISymUnmanagedDocument document, uint line, uint column, uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] ISymUnmanagedMethod[] retval);
        void GetDocumentVersion(ISymUnmanagedDocument doc, out int version, out bool isLatest);
        void GetMethodVersion(ISymUnmanagedMethod method, out int version);
    }

    [ComImport, Guid("68005D0F-B8E0-3B01-84D5-A11A94154942"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface ISymUnmanagedScope
    {
        ISymUnmanagedMethod GetMethod();
        ISymUnmanagedScope GetParent();
        void GetChildren(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] IntPtr[] children);
        uint GetStartOffset();
        uint GetEndOffset();
        uint GetLocalCount();
        void GetLocals(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] IntPtr[] locals);
        void GetNamespaces(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] IntPtr[] namespaces);
    }

    [ComImport, Guid("9F60EEBE-2D9A-3F7C-BF58-80BC991C60BB"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface ISymUnmanagedVariable
    {
        void GetName(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] char[] name);
        uint GetAttributes();
        void GetSignature(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] byte[] name);
        uint GetAddressKind();
        uint GetAddressField1();
        uint GetAddressField2();
        uint GetAddressField3();
        uint GetStartOffset();
        uint GetEndOffset();
    }

    [ComImport, Guid("ACCEE350-89AF-4ccb-8B40-1C2C4C6F9434"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), ComVisible(false)]
    internal interface ISymUnmanagedBinder
    {
        ISymUnmanagedReader GetReaderForFile([MarshalAs(UnmanagedType.IUnknown)] object importer, string filename, string searchPath);
        ISymUnmanagedReader GetReaderForStream([MarshalAs(UnmanagedType.IUnknown)] object importer, [MarshalAs(UnmanagedType.IUnknown)] object stream);
        ISymUnmanagedReader GetReaderForFile2([MarshalAs(UnmanagedType.IUnknown)] object importer, [MarshalAs(UnmanagedType.LPWStr)] string fileName, [MarshalAs(UnmanagedType.LPWStr)] string searchPath, int searchPolicy);
    }

    [ComImport, Guid("0A29FF9E-7F9C-4437-8B11-F424491E3931")]
    internal class CorSymBinder
    {
    }

    #endregion SymUnmanaged
... << RSDN@Home 1.2.0 alpha rev. 642>>
И ещё в догонку: isymwrapper.dll
От: Блудов Павел Россия  
Дата: 19.09.06 09:57
Оценка:
Если добавить reference на %SystemRoot%\Microsoft.Net\Framework\v2.0.50727\isymwrapper.dll, то можно ISymUnmanagedXXXX не использовать, там вполне нормальные врапперы на c#:
    public class TestClass
    {
        public void TestMethod()
        {
        }
    }

    public class PdbTest
    {
        [STAThread]
        public static void Main(string[] args)
        {
            Guid IMetaDataImportGuid = typeof(IMetaDataImport).GUID;

            // Для интергации нужно использовать IVsSmartOpenScope::OpenScope
            // из VisualStudioIntegration\Common\IDL\compsvcspkg80.idl
            //
            IMetaDataDispenser metaDispenser = (IMetaDataDispenser)new CorMetaDataDispenser();
            IMetaDataImport metaDataImport = (IMetaDataImport)metaDispenser.OpenScope(ExecutableLocation, 0, ref IMetaDataImportGuid);

            // Получаем токен нужного метода
            //
            uint classToken = metaDataImport.FindTypeDefByName("dotNetJim.TestClass", 0);
            uint methodToken = metaDataImport.FindMethod(classToken, "TestMethod", null, 0);

            // Вот собственно работа с .pdb
            //
            ISymbolBinder1 binder = new SymBinder();
            ISymbolReader  reader = binder.GetReader(Marshal.GetIUnknownForObject(metaDataImport), ExecutableLocation, null);
            ISymbolMethod  method = reader.GetMethod(new SymbolToken((int)methodToken));

            int seqPoints = method.SequencePointCount;

            ISymbolDocument[] documents  = new ISymbolDocument[seqPoints];
            int[]   lines      = new int[seqPoints];
            int[]   columns    = new int[seqPoints];
            int[]   endLines   = new int[seqPoints];
            int[]   endColumns = new int[seqPoints];
            int[]   offsets    = new int[seqPoints];
            method.GetSequencePoints(offsets, documents, lines, columns, endLines, endColumns);

            for (int i = 0; i < seqPoints; i++)
                Console.WriteLine("file {0}, line {1} col {2}", documents[i].URL, lines[i], columns[i]);
        }

        public static string ExecutableLocation
        {
            get { return Assembly.GetEntryAssembly().Location; }
        }
    }
... << RSDN@Home 1.2.0 alpha rev. 642>>
И напоследок полезная ссылочка
От: Блудов Павел Россия  
Дата: 19.09.06 10:30
Оценка:
http://blogs.msdn.com/jmstall/archive/2005/10/08/symbol_apis.aspx
... << RSDN@Home 1.2.0 alpha rev. 642>>
Re: И ещё в догонку: isymwrapper.dll
От: IT Россия linq2db.com
Дата: 19.09.06 18:14
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

БП>Если добавить reference на %SystemRoot%\Microsoft.Net\Framework\v2.0.50727\isymwrapper.dll, то можно ISymUnmanagedXXXX не использовать, там вполне нормальные врапперы на c#:


Лишних референсов плодить не желательно.

Я не нашёл как получить местонахождение класса и не понятно что делать, если имеется несколько методов с одним названием. Выдается толи первый, толи последний попавшийся.
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: И ещё в догонку: isymwrapper.dll
От: Блудов Павел Россия  
Дата: 20.09.06 00:08
Оценка:
Здравствуйте, IT, Вы писали:

IT>Я не нашёл как получить местонахождение класса и не понятно что делать, если имеется несколько методов с одним названием. Выдается толи первый, толи последний попавшийся.


Я так понял, если есть сигнатура метода и известно, в какой сборке он живёт, то нет проблем получить его metadata token. Хоть через рефлексию, хоть через IMetaDataImport (первое явно сделано через второе). Ну а имея конкретный токен, его pdb-потроха получить не проблема.
... << RSDN@Home 1.2.0 alpha rev. 642>>
Re[2]: И ещё в догонку: isymwrapper.dll
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.09.06 00:15
Оценка:
Здравствуйте, IT, Вы писали:

IT>Лишних референсов плодить не желательно.


От тут я не согласен. Ссылку на сборку из фрэймворка можно давать без каких либо проблем. Это лучше чем копипэст. Вот если это левая сборка или ради одного интерфейса, то другое дело.

IT>Я не нашёл как получить местонахождение класса и не понятно что делать, если имеется несколько методов с одним названием. Выдается толи первый, толи последний попавшийся.


Кстати, переходы к коду проекта тоже работают не верно в случае если клас partial. Переход осуществляется к первой сканированной части, а это не верно. В таких случаях надо выдавать диалок со списком файлов в которых распологаются части класса.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: И ещё в догонку: isymwrapper.dll
От: IT Россия linq2db.com
Дата: 20.09.06 00:56
Оценка:
Здравствуйте, VladD2, Вы писали:

IT>>Лишних референсов плодить не желательно.


VD>От тут я не согласен. Ссылку на сборку из фрэймворка можно давать без каких либо проблем. Это лучше чем копипэст. Вот если это левая сборка или ради одного интерфейса, то другое дело.


Это я чего-то тормознул. Мне показалось, что это сборка из SDK, которая может быть, а может и не может.

VD>Кстати, переходы к коду проекта тоже работают не верно в случае если клас partial. Переход осуществляется к первой сканированной части, а это не верно. В таких случаях надо выдавать диалок со списком файлов в которых распологаются части класса.


Переход осуществляется без затей по location. Так что править надо именно location для partial классов.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: И ещё в догонку: isymwrapper.dll
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.09.06 01:37
Оценка:
Здравствуйте, IT, Вы писали:

IT>Переход осуществляется без затей по location. Так что править надо именно location для partial классов.


Ты не те локейшоны берешь. И править там ничего не надо. Я же правильно нахожу функцию?

Там (в классе TypeBuilder) есть список локейшонов (PartsLocation) для разных файлов. Вот из них и нужно делать список если их более одной штуки.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: И ещё в догонку: isymwrapper.dll
От: IT Россия linq2db.com
Дата: 20.09.06 01:43
Оценка:
Здравствуйте, VladD2, Вы писали:

IT>>Переход осуществляется без затей по location. Так что править надо именно location для partial классов.


VD>Ты не те локейшоны берешь. И править там ничего не надо. Я же правильно нахожу функцию?

VD>Там (в классе TypeBuilder) есть список локейшонов (PartsLocation) для разных файлов. Вот из них и нужно делать список если их более одной штуки.

Подожди. Каждый IMember имеет location в котором он определён. Что тут не правильно?
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[6]: И ещё в догонку: isymwrapper.dll
От: Блудов Павел Россия  
Дата: 20.09.06 02:32
Оценка:
Здравствуйте, IT, Вы писали:

IT>Подожди. Каждый IMember имеет location в котором он определён. Что тут не правильно?

Полагаю, Влад имеет ввиду, что если есть partial class MyClass, то при нажатии F12 вот в таком месте
MyClass a = new MyClass();
// ^= курсор тут.


Нужно уведомить пользователя, что MyClass состоит из n кусков и предложить выбрать. Интересная тема — исключить из списка генерируемые файлы типа MyClass.designer.cs
... << RSDN@Home 1.2.0 alpha rev. 642>>
Re[7]: И ещё в догонку: isymwrapper.dll
От: IT Россия linq2db.com
Дата: 20.09.06 03:16
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

IT>>Подожди. Каждый IMember имеет location в котором он определён. Что тут не правильно?

БП>Полагаю, Влад имеет ввиду, что если есть partial class MyClass, то при нажатии F12 вот в таком месте

А как студия поступает в данном случае?
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[8]: И ещё в догонку: isymwrapper.dll
От: Блудов Павел Россия  
Дата: 20.09.06 03:46
Оценка:
Здравствуйте, IT, Вы писали:

IT>А как студия поступает в данном случае?

ReSharper вываливает DropDown "Choose Declaration" с полным списком .cs файлов, в которых имеется этот класс.

Сама студия кажет окошко "Find Symbol Results". Тоже со всеми файлами включая .designer.cs
... << RSDN@Home 1.2.0 alpha rev. 642>>
Готов переход к исходнику при наличии pdb.
От: Блудов Павел Россия  
Дата: 10.10.06 05:56
Оценка: 106 (2)
Здравствуйте, IT!

Получите и распишитесь (LanguageService\NemerleAuthoringScope.cs):

        public override string Goto(
            VSConstants.VSStd97CmdID cmd, 
            IVsTextView              textView,
            int                      line,
            int                      col,
            out TextSpan             span)
        {
            span = new TextSpan();

            GotoInfo info = _project.GetGoto(_filePath, line, col, _sourceText);

            if (info == null)
                return null;

            if (info.HasLocation)
            {
                span.iStartLine  = info.LineStart;
                span.iEndLine    = info.LineEnd;
                span.iStartIndex = info.ColStart;
                span.iEndIndex   = info.ColEnd;

                return info.FilePath;
            }

            if (null != info.Member && !string.IsNullOrEmpty(info.FilePath))
            {
                Guid   mdiGuid = new Guid("7DAC8207-D3AE-4c75-9B67-92801A497D44");
                IntPtr mdiPtr  = IntPtr.Zero;
                object mdiUnk;

                if (VSConstants.S_OK == _project.SmartOpenScope.OpenScope(info.FilePath, 0, ref mdiGuid, out mdiUnk))
                {
                    try
                    {
                        mdiPtr                = Marshal.GetIUnknownForObject(mdiUnk);

                        SymbolToken    token  = new SymbolToken(info.Member.GetHandle().MetadataToken);
                        ISymbolBinder1 binder = new SymBinder();
                        ISymbolReader  reader = binder.GetReader(mdiPtr, info.FilePath, null);
                        ISymbolMethod  method = reader.GetMethod(token);

                        if (method.SequencePointCount > 0)
                        {
                            ISymbolDocument[] documents  = new ISymbolDocument[1];
                            int[]             lines      = new int[1];
                            int[]             columns    = new int[1];
                            int[]             endLines   = new int[1];
                            int[]             endColumns = new int[1];

                            method.GetSequencePoints(null, documents, lines, columns, endLines, endColumns);

                            span.iStartLine  = lines[0]      - 1;
                            span.iEndLine    = endLines[0]   - 1;
                            span.iStartIndex = columns[0]    - 1;
                            span.iEndIndex   = endColumns[0] - 1;

                            return documents[0].URL;
                        }
                    }
                    catch (COMException)
                    {
                        // The file was not found or line numbers were stripped from pdb.
                    }
                    finally
                    {
                        if (IntPtr.Zero != mdiPtr)
                            Marshal.Release(mdiPtr);
                    }
                }
            }

            return null;
        }


Полужирным выделено то, чего мне не хватало и я тупо добавил:

GotoInfo.cs:
namespace Nemerle.Completion2
{
  public class GotoInfo
  {
    [Accessor] mutable _filePath  : string;
    [Accessor] mutable _lineStart : int;
    [Accessor] mutable _lineEnd   : int;
    [Accessor] mutable _colStart  : int;
    [Accessor] mutable _colEnd    : int;
    [Accessor] mutable _member    : IMember;

    public this(member : IMember)
    {
      _member = member;
      SetLocation(member.Location);
    }
  }
}


ProjectInfo.cs:
        public  IVsSmartOpenScope SmartOpenScope
        {
             get { return (IVsSmartOpenScope) _site.GetService(typeof (SVsSmartOpenScope)); }
        }


Кроме того, нужно добавить reference на ISymWrapper.DLL из каталога FrameWork'а.

Known issues

Вот тут работает:
m() : Nemerle.TailRecursionTransparentAttribute
{
    def i = Nemerle.TailRecursionTransparentAttribute(true);
    i;
}

А тут нет:
Main() : void
{
    printf("Hi!");
}

потому что Nemerle.IO.printf почему-то распознаётся как System.Console.Write() Причём в QuickTip тоже имеем System.Console.Write. Кто виноват и что делать
... << RSDN@Home 1.2.0 alpha rev. 642>>
Поравочка
От: Блудов Павел Россия  
Дата: 10.10.06 06:10
Оценка:
Вместо
                            ISymbolDocument[] documents  = new ISymbolDocument[1];
                            int[]             lines      = new int[1];
                            int[]             columns    = new int[1];
                            int[]             endLines   = new int[1];
                            int[]             endColumns = new int[1];

                            method.GetSequencePoints(null, documents, lines, columns, endLines, endColumns);

следует читать
                            ISymbolDocument[] documents  = new ISymbolDocument[1];
                            int[]             offsets    = new int[1];
                            int[]             lines      = new int[1];
                            int[]             columns    = new int[1];
                            int[]             endLines   = new int[1];
                            int[]             endColumns = new int[1];

                            method.GetSequencePoints(offsets, documents, lines, columns, endLines, endColumns);


Иначе студия тупо стреляется.
... << RSDN@Home 1.2.0 alpha rev. 642>>
Re: Готов переход к исходнику при наличии pdb.
От: ie Россия http://ziez.blogspot.com/
Дата: 10.10.06 06:16
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

БП>А тут нет:

БП>
Main() : void
БП>{
БП>    printf("Hi!");
БП>}

БП>потому что Nemerle.IO.printf почему-то распознаётся как System.Console.Write() Причём в QuickTip тоже имеем System.Console.Write. Кто виноват и что делать

Дык, printf — макрос. Он в итоге раскрывается в System.Console.Write(). Так что тут надо как-то колдовать с тем, что мы имеем до расскрытия макроса, а не с финальным кодом.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Превратим окружающую нас среду в воскресенье.
Re: Поравочка
От: ie Россия http://ziez.blogspot.com/
Дата: 10.10.06 06:17
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

БП>Вместо

...
БП>Иначе студия тупо стреляется.

Прислал бы svn-овский патч и делов
... << RSDN@Home 1.2.0 alpha rev. 0>>
Превратим окружающую нас среду в воскресенье.
Re[2]: Поравочка
От: Блудов Павел Россия  
Дата: 10.10.06 07:12
Оценка:
Здравствуйте, ie, Вы писали:

ie>Прислал бы svn-овский патч и делов

Не, у меня куча LF поменялись на CR-LF, пока я разобрался что к чему. Так что лучше так. Потом сделаю Revert всего и заберу новую версию.
... << RSDN@Home 1.2.0 alpha rev. 642>>
Re: Готов переход к исходнику при наличии pdb.
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.10.06 17:24
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

БП>

Known issues

БП>Вот тут работает:
БП>
БП>m() : Nemerle.TailRecursionTransparentAttribute
БП>{
БП>    def i = Nemerle.TailRecursionTransparentAttribute(true);
БП>    i;
БП>}
БП>

БП>А тут нет:
БП>
Main() : void
БП>{
БП>    printf("Hi!");
БП>}

БП>потому что Nemerle.IO.printf почему-то распознаётся как System.Console.Write() Причём в QuickTip тоже имеем System.Console.Write. Кто виноват и что делать

Все верно. Nemerle.IO.printf — это макрос который на самом деле может раскрыть намного более сложным образом. Тут нужно более сложный анализ производить. Если удастся получить хотя бы ссылу на сборку где объявлен Nemerle.IO.printf, то дальше все что нужно можно будет вытащить из метаданных.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Поравочка
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.10.06 17:24
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

ie>>Прислал бы svn-овский патч и делов

БП>Не, у меня куча LF поменялись на CR-LF, пока я разобрался что к чему. Так что лучше так. Потом сделаю Revert всего и заберу новую версию.

А не проще ли просто подключиться к проекту?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Поравочка
От: IT Россия linq2db.com
Дата: 10.10.06 21:40
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>А не проще ли просто подключиться к проекту?


Он стеснятеся.
Если нам не помогут, то мы тоже никого не пощадим.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.