PageRenderTime 63ms CodeModel.GetById 25ms app.highlight 31ms RepoModel.GetById 1ms app.codeStats 0ms

/client_v4_2_dev/Framework/CorDebug/ResXFileCodeGenerator.cs

#
C# | 396 lines | 322 code | 67 blank | 7 comment | 58 complexity | 74545c1da0e1564f9005828fb566473f MD5 | raw file
  1using System;
  2using System.IO;
  3using System.Reflection;
  4using System.Diagnostics;
  5using System.Collections;
  6using System.ComponentModel;
  7using System.Runtime.InteropServices;
  8using CorDebugInterop;
  9using Microsoft.Win32;
 10using Microsoft.VisualStudio.Debugger.Interop;
 11using Microsoft.VisualStudio.Shell.Interop;
 12using Microsoft.VisualStudio.Shell;
 13using Microsoft.VisualStudio.OLE.Interop;
 14using Microsoft.VisualStudio.Designer.Interfaces;
 15using System.CodeDom;
 16using System.CodeDom.Compiler;
 17
 18using IOleServiceProvider = Microsoft.VisualStudio.OLE.Interop.IServiceProvider;
 19using IServiceProvider = System.IServiceProvider;
 20
 21namespace Microsoft.SPOT.Debugger
 22{
 23    internal abstract class BaseCodeGenerator : IVsSingleFileGenerator
 24    {
 25        private string codeFileNameSpace = string.Empty;
 26        private string codeFilePath = string.Empty;
 27
 28        private IVsGeneratorProgress codeGeneratorProgress;
 29
 30        // **************************** PROPERTIES ****************************
 31        protected string FileNameSpace
 32        {
 33            get
 34            {
 35                return codeFileNameSpace;
 36            }
 37        }
 38
 39        protected string InputFilePath
 40        {
 41            get
 42            {
 43                return codeFilePath;
 44            }
 45        }
 46
 47        internal IVsGeneratorProgress CodeGeneratorProgress
 48        {
 49            get
 50            {
 51                return codeGeneratorProgress;
 52            }
 53        }
 54
 55        // **************************** METHODS **************************
 56        public abstract int DefaultExtension( out string ext );
 57
 58        // MUST implement this abstract method.
 59        protected abstract byte[] GenerateCode( string inputFileName, string inputFileContent );
 60
 61
 62        protected virtual void GeneratorErrorCallback( int warning, uint level, string message, uint line, uint column )
 63        {
 64            IVsGeneratorProgress progress = CodeGeneratorProgress;
 65            if(progress != null)
 66            {
 67                Utility.COM_HResults.ThrowOnFailure( progress.GeneratorError( warning, level, message, line, column ) );
 68                
 69            }
 70        }
 71
 72        public int Generate( string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace,
 73                             IntPtr[] pbstrOutputFileContents, out uint pbstrOutputFileContentSize, IVsGeneratorProgress pGenerateProgress )
 74        {
 75
 76            if(bstrInputFileContents == null)
 77            {
 78                throw new ArgumentNullException( bstrInputFileContents );
 79            }
 80            codeFilePath = wszInputFilePath;
 81            codeFileNameSpace = wszDefaultNamespace;
 82            codeGeneratorProgress = pGenerateProgress;
 83
 84            byte[] bytes = GenerateCode( wszInputFilePath, bstrInputFileContents );
 85            if(bytes == null)
 86            {
 87                pbstrOutputFileContents[0] = IntPtr.Zero;
 88                pbstrOutputFileContentSize = 0;
 89            }
 90            else
 91            {
 92                pbstrOutputFileContents[0] = Marshal.AllocCoTaskMem( bytes.Length );
 93                Marshal.Copy( bytes, 0, pbstrOutputFileContents[0], bytes.Length );
 94                pbstrOutputFileContentSize = (uint)bytes.Length;
 95            }
 96            return Utility.COM_HResults.S_OK;
 97        }
 98
 99        protected byte[] StreamToBytes( Stream stream )
100        {
101            if(stream.Length == 0)
102                return new byte[] { };
103
104            long position = stream.Position;
105            stream.Position = 0;
106            byte[] bytes = new byte[(int)stream.Length];
107            stream.Read( bytes, 0, bytes.Length );
108            stream.Position = position;
109
110            return bytes;
111        }
112    }
113
114    internal abstract class BaseCodeGeneratorWithSite : BaseCodeGenerator, IObjectWithSite
115    {
116
117        private Object site = null;
118        private CodeDomProvider codeDomProvider = null;
119        private static Guid CodeDomInterfaceGuid = new Guid( "{73E59688-C7C4-4a85-AF64-A538754784C5}" );
120        private static Guid CodeDomServiceGuid = CodeDomInterfaceGuid;
121        private ServiceProvider serviceProvider = null;
122
123        protected virtual CodeDomProvider CodeProvider
124        {
125            get
126            {
127                if(codeDomProvider == null)
128                {
129                    IVSMDCodeDomProvider vsmdCodeDomProvider = (IVSMDCodeDomProvider)GetService( CodeDomServiceGuid );
130                    if(vsmdCodeDomProvider != null)
131                    {
132                        codeDomProvider = (CodeDomProvider)vsmdCodeDomProvider.CodeDomProvider;
133                    }
134                    Debug.Assert( codeDomProvider != null, "Get CodeDomProvider Interface failed.  GetService(QueryService(CodeDomProvider) returned Null." );
135                }
136                return codeDomProvider;
137            }
138            set
139            {
140                if(value == null)
141                {
142                    throw new ArgumentNullException();
143                }
144
145                codeDomProvider = value;
146            }
147        }
148
149        private ServiceProvider SiteServiceProvider
150        {
151            get
152            {
153                if(serviceProvider == null)
154                {
155                    IOleServiceProvider oleServiceProvider = site as IOleServiceProvider;
156                    Debug.Assert( oleServiceProvider != null, "Unable to get IOleServiceProvider from site object." );
157
158                    serviceProvider = new ServiceProvider( oleServiceProvider );
159                }
160                return serviceProvider;
161            }
162        }
163
164        protected Object GetService( Guid serviceGuid )
165        {
166            return SiteServiceProvider.GetService( serviceGuid );
167        }
168
169        protected object GetService( Type serviceType )
170        {
171            return SiteServiceProvider.GetService( serviceType );
172        }
173
174
175        public override int DefaultExtension( out string ext )
176        {
177            CodeDomProvider codeDom = CodeProvider;
178            Debug.Assert( codeDom != null, "CodeDomProvider is NULL." );
179            string extension = codeDom.FileExtension;
180            if(extension != null && extension.Length > 0)
181            {
182                if(extension[0] != '.')
183                {
184                    extension = "." + extension;
185                }
186            }
187
188            ext = extension;
189            return Utility.COM_HResults.S_OK;
190        }
191
192        protected virtual ICodeGenerator GetCodeWriter()
193        {
194            CodeDomProvider codeDom = CodeProvider;
195            if(codeDom != null)
196            {
197#pragma warning disable 618 //backwards compat
198                return codeDom.CreateGenerator();
199#pragma warning restore 618
200            }
201
202            return null;
203        }
204
205        // ******************* Implement IObjectWithSite *****************
206        //
207        public virtual void SetSite( object pUnkSite )
208        {
209            site = pUnkSite;
210            codeDomProvider = null;
211            serviceProvider = null;
212        }
213
214        // Does anyone rely on this method?
215        public virtual void GetSite( ref Guid riid, out IntPtr ppvSite )
216        {
217            if(site == null)
218            {
219                Utility.COM_HResults.Throw( Utility.COM_HResults.E_FAIL );
220            }
221
222            IntPtr pUnknownPointer = Marshal.GetIUnknownForObject( site );
223            try
224            {
225                Marshal.QueryInterface( pUnknownPointer, ref riid, out ppvSite );
226
227                if(ppvSite == IntPtr.Zero)
228                {
229                    Utility.COM_HResults.Throw( Utility.COM_HResults.E_NOINTERFACE );
230                }
231            }
232            finally
233            {
234                if(pUnknownPointer != IntPtr.Zero)
235                {
236                    Marshal.Release( pUnknownPointer );
237                    pUnknownPointer = IntPtr.Zero;
238                }
239            }
240        }
241    }
242
243    internal class ResXFileCodeGenerator : BaseCodeGeneratorWithSite, IObjectWithSite
244    {
245        internal const string c_Name   = "ResXFileCodeGenerator";
246        private const string DesignerExtension = ".Designer";
247
248        internal bool m_fInternal = true;
249        internal bool m_fNestedEnums = true;
250        internal bool m_fMscorlib = false;
251        VsProject _project;
252
253        public ResXFileCodeGenerator(VsProject vsProject)
254        {
255            _project = vsProject;
256        }
257
258        protected string GetResourcesNamespace()
259        {
260            string resourcesNamespace = null;
261            try
262            {
263                IntPtr punkVsBrowseObject;
264                Guid vsBrowseObjectGuid = typeof( IVsBrowseObject ).GUID;
265
266                GetSite( ref vsBrowseObjectGuid, out punkVsBrowseObject );
267
268                if(punkVsBrowseObject != IntPtr.Zero)
269                {
270
271                    IVsBrowseObject vsBrowseObject = Marshal.GetObjectForIUnknown( punkVsBrowseObject ) as IVsBrowseObject;
272                    Debug.Assert( vsBrowseObject != null, "Generator invoked by Site that is not IVsBrowseObject?" );
273
274                    Marshal.Release( punkVsBrowseObject );
275
276                    if(vsBrowseObject != null)
277                    {
278                        IVsHierarchy vsHierarchy;
279                        uint vsitemid;
280
281                        vsBrowseObject.GetProjectItem( out vsHierarchy, out vsitemid );
282
283                        Debug.Assert( vsHierarchy != null, "GetProjectItem should have thrown or returned a valid IVsHierarchy" );
284                        Debug.Assert( vsitemid != 0, "GetProjectItem should have thrown or returned a valid VSITEMID" );
285
286
287                        if(vsHierarchy != null)
288                        {
289                            object obj;
290
291                            vsHierarchy.GetProperty( vsitemid, (int)__VSHPROPID.VSHPROPID_DefaultNamespace, out obj );
292                            string objStr = obj as string;
293                            if(objStr != null)
294                            {
295                                resourcesNamespace = objStr;
296                            }
297                        }
298                    }
299                }
300            }
301            catch(Exception e)
302            {
303                Debug.WriteLine( e.ToString() );
304                Debug.Fail( "These methods should succeed..." );
305            }
306
307            return resourcesNamespace;
308        }
309
310        public override int DefaultExtension( out string ext )
311        {
312            //copied from ResXFileCodeGenerator
313            string baseExtension;
314            ext = String.Empty;
315
316            int hResult = base.DefaultExtension( out baseExtension );
317
318            if(!Utility.COM_HResults.SUCCEEDED( hResult ))
319            {
320                Debug.Fail( "Invalid hresult returned by the base DefaultExtension" );
321                return hResult;
322            }
323
324            if(!String.IsNullOrEmpty( baseExtension ))
325            {
326                ext = DesignerExtension + baseExtension;
327            }
328
329            return Utility.COM_HResults.S_OK;
330        }
331
332        protected override byte[] GenerateCode( string inputFileName, string inputFileContent )
333        {
334            VSLangProj.Reference reference = _project.VSLangProj_References.Find("System.Drawing");
335            if (reference != null)
336            {
337                reference.Remove();
338            }
339
340            string spotGraphics = "Microsoft.SPOT.Graphics";
341            reference = _project.VSLangProj_References.Find(spotGraphics);
342            if (reference == null)
343            {
344                _project.VSLangProj_References.Add(spotGraphics);                
345            }
346
347            MemoryStream stream = new MemoryStream();
348            StreamWriter writer = new StreamWriter( stream );
349            string inputFileNameWithoutExtension = Path.GetFileNameWithoutExtension( inputFileName );            
350
351            Assembly tasks = null;
352
353            foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
354            {
355                if (string.Compare(asm.GetName().Name, "Microsoft.SPOT.Tasks", true) == 0)
356                {
357                    if(asm.GetName().Version.ToString(2) == new Version(_project.GetTargetFrameworkProperty().TrimStart('v')).ToString(2))
358                    {
359                        tasks = asm;
360                        break;
361                    }
362                }
363            }
364
365            if (tasks == null) throw new Exception("Microsoft.SPOT.Tasks.dll is not loaded!");
366
367            Type typ = tasks.GetType("Microsoft.SPOT.Tasks.ProcessResourceFiles");
368
369            if (typ != null)
370            {
371                object processResourceFiles = typ.GetConstructor(new Type[]{}).Invoke(null);
372
373                typ.GetProperty("StronglyTypedClassName").SetValue(processResourceFiles, inputFileNameWithoutExtension, null);
374                typ.GetProperty("StronglyTypedNamespace").SetValue(processResourceFiles, GetResourcesNamespace(), null);
375                typ.GetProperty("GenerateNestedEnums").SetValue(processResourceFiles, m_fNestedEnums, null);
376                typ.GetProperty("GenerateInternalClass").SetValue(processResourceFiles, m_fInternal, null);
377                typ.GetProperty("IsMscorlib").SetValue(processResourceFiles, m_fMscorlib, null);
378
379                string resourceName = (string)typ.GetProperty("StronglyTypedNamespace").GetValue(processResourceFiles, null);
380
381                if (string.IsNullOrEmpty(resourceName))
382                {
383                    resourceName = inputFileNameWithoutExtension;
384                }
385                else
386                {
387                    resourceName = string.Format("{0}.{1}", resourceName, inputFileNameWithoutExtension);
388                }
389
390                typ.GetMethod("CreateStronglyTypedResources").Invoke(processResourceFiles, new object[]{ inputFileName, this.CodeProvider, writer, resourceName });
391            }
392
393            return base.StreamToBytes( stream );
394        }
395    }
396}