Example #1
0
        /// <summary>
        /// Generates the specified WSZ input file path.
        /// </summary>
        /// <param name="wszInputFilePath">The WSZ input file path.</param>
        /// <param name="bstrInputFileContents">The BSTR input file contents.</param>
        /// <param name="wszDefaultNamespace">The WSZ default namespace.</param>
        /// <param name="rgbOutputFileContents">The RGB output file contents.</param>
        /// <param name="pcbOutput">The PCB output.</param>
        /// <param name="pGenerateProgress">The p generate progress.</param>
        /// <returns></returns>
        public int Generate(string wszInputFilePath,
            string bstrInputFileContents,
            string wszDefaultNamespace,
            IntPtr[] rgbOutputFileContents,
            out uint pcbOutput,
            IVsGeneratorProgress pGenerateProgress)
        {
            if (wszInputFilePath == null)
                throw new ArgumentNullException(wszInputFilePath);

            var generatorParams = GeneratorParams.LoadFromFile(wszInputFilePath) ?? new GeneratorParams();

            generatorParams.InputFilePath = wszInputFilePath;
            generatorParams.NameSpace = wszDefaultNamespace;

            var xsdGen = new GeneratorFacade(this.provider, generatorParams);

            var result = xsdGen.GenerateBytes();
            var generatedStuff = result.Entity;

            if (generatedStuff == null)
            {
                rgbOutputFileContents[0] = IntPtr.Zero;
                pcbOutput = 0;
                return 0;
            }

            // Copie du flux en mémoire pour que Visual Studio puisse le récupérer
            rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(generatedStuff.Length);
            Marshal.Copy(generatedStuff, 0, rgbOutputFileContents[0], generatedStuff.Length);
            pcbOutput = (uint) generatedStuff.Length;

            return 0;
        }
Example #2
0
        public int Generate(string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace, IntPtr[] pbstrOutputFileContents, out uint pbstrOutputFileContentSize, IVsGeneratorProgress pGenerateProgress)
        {
            if (bstrInputFileContents == null)
            {
                throw new ArgumentNullException(bstrInputFileContents);
            }

            this.codeFilePath = wszInputFilePath;
            this.codeFileNameSpace = wszDefaultNamespace;
            this.codeGeneratorProgress = pGenerateProgress;

            byte[] generatedStuff = this.GenerateCode(wszInputFilePath, bstrInputFileContents);

            if (generatedStuff == null)
            {
                pbstrOutputFileContents[0] = IntPtr.Zero;
                pbstrOutputFileContentSize = 0;
            }
            else
            {
                pbstrOutputFileContents[0] = Marshal.AllocCoTaskMem(generatedStuff.Length);
                Marshal.Copy(generatedStuff, 0, pbstrOutputFileContents[0], generatedStuff.Length);
                pbstrOutputFileContentSize = (uint)generatedStuff.Length;
            }
            return 0;
        }
Example #3
0
        int IVsSingleFileGenerator.Generate(string wszInputFilePath, string bstrInputFileContents,
            string wszDefaultNamespace, IntPtr[] rgbOutputFileContents, out uint pcbOutput,
            IVsGeneratorProgress pGenerateProgress)
        {
            codeFilePath = wszInputFilePath;
            codeFileNameSpace = wszDefaultNamespace;
            codeGeneratorProgress = pGenerateProgress;

            string Output;
            try
            {
                Output = GenerateCode(bstrInputFileContents);
            }
            catch (Exception e)
            {
                Output = GenerateError(pGenerateProgress, e);
            }

            var OutputBytes = Encoding.UTF8.GetBytes(Output);
            var OutputLength = OutputBytes.Length;

            rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(OutputLength);
            Marshal.Copy(OutputBytes, 0, rgbOutputFileContents[0], OutputLength);
            pcbOutput = (uint) OutputLength;

            return VSConstants.S_OK;
        }
        public int Generate(string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace, IntPtr[] pbstrOutputFileContents,
            out uint pbstrOutputFileContentSize, IVsGeneratorProgress pGenerateProgress)
        {
            if (null == bstrInputFileContents)
                throw new ArgumentNullException(bstrInputFileContents);

            _codeFilePath = wszInputFilePath;
            _codeFileNameSpace = wszDefaultNamespace;
            _codeGeneratorProgress = pGenerateProgress;

            byte[] codeBuffer = this.GenerateCode(wszInputFilePath, bstrInputFileContents);
            if (null == codeBuffer)
            {
                pbstrOutputFileContents[0] = IntPtr.Zero;
                pbstrOutputFileContentSize = 0;
            }
            else
            {
                pbstrOutputFileContents[0] = Marshal.AllocCoTaskMem(codeBuffer.Length);
                Marshal.Copy(codeBuffer, 0, pbstrOutputFileContents[0], codeBuffer.Length);
                pbstrOutputFileContentSize = (uint)codeBuffer.Length;
            }

            return 0;
        }
Example #5
0
        int IVsSingleFileGenerator.Generate(string wszInputFilePath,
                                            string bstrInputFileContents,
                                            string wszDefaultNamespace,
                                            IntPtr[] rgbOutputFileContents,
                                            out uint pcbOutput,
                                            IVsGeneratorProgress pGenerateProgress)
        {
            codeFilePath = wszInputFilePath;
            codeFileNameSpace = wszDefaultNamespace;
            codeGeneratorProgress = pGenerateProgress;
            byte[] bytes = null;
            try
            {
                BeforeCodeGenerated();
                bytes = Encoding.UTF8.GetBytes(GenerateCode(bstrInputFileContents));
                AfterCodeGenerated(false);
            }
            catch(Exception ex)
            {
                string message = GenerateError(pGenerateProgress, ex);
                AfterCodeGenerated(true);
                bytes = Encoding.UTF8.GetBytes(message);
            }

            int outputLength = bytes.Length;
            rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(outputLength);
            Marshal.Copy(bytes, 0, rgbOutputFileContents[0], outputLength);
            pcbOutput = (uint)outputLength;

            RefreshMsTestWindow();

            return VSConstants.S_OK;
        }
        public virtual int Generate(string inputFilePath, string inputFileContents, string defaultNamespace, IntPtr[] outputFileContents, out uint outputSize, IVsGeneratorProgress progressCallback)
        {
            if (inputFileContents == null)
                throw new ArgumentException("inputFileContents");

            try
            {
                byte[] outputBytes = Generate(inputFilePath, inputFileContents, defaultNamespace, progressCallback);
                if (outputBytes != null)
                {
                    outputSize = (uint)outputBytes.Length;
                    outputFileContents[0] = Marshal.AllocCoTaskMem(outputBytes.Length);
                    Marshal.Copy(outputBytes, 0, outputFileContents[0], outputBytes.Length);
                }
                else
                {
                    outputFileContents[0] = IntPtr.Zero;
                    outputSize = 0;
                }
                return VSConstants.S_OK;
            }
            catch (Exception e)
            {
                // Error msg in Visual Studio only gives the exception message,
                // not the stack trace. Workaround:
                throw new COMException(string.Format("{0}: {1}\n{2}", e.GetType().Name, e.Message, e.StackTrace));
            }
        }
        /// <summary>
        /// main method that the VS shell calls to do the generation
        /// </summary>
        /// <param name="wszInputFilePath">path to the input file</param>
        /// <param name="bstrInputFileContents">contents of the input file as a string (shell handles UTF-8 to Unicode and those types of conversions)</param>
        /// <param name="wszDefaultNamespace">default namespace for the generated code file</param>
        /// <param name="rgbOutputFileContents">byte-array of output file contents</param>
        /// <param name="pcbOutput">count of bytes in the output byte-array</param>
        /// <param name="pGenerateProgress">interface to send progress updates to the shell</param>
        public void Generate(
            string wszInputFilePath,
            string bstrInputFileContents,
            string wszDefaultNamespace,
            out IntPtr rgbOutputFileContents,
            out int pcbOutput,
            IVsGeneratorProgress pGenerateProgress)
        {

            if (bstrInputFileContents == null)
            {
                throw new ArgumentNullException(bstrInputFileContents);
            }

            codeFilePath = wszInputFilePath;
            codeFileNameSpace = wszDefaultNamespace;
            codeGeneratorProgress = pGenerateProgress;

            byte[] bytes = GenerateCode(wszInputFilePath, bstrInputFileContents);

            if (bytes == null)
            {
                rgbOutputFileContents = IntPtr.Zero;
                pcbOutput = 0;
            }
            else
            {
                pcbOutput = bytes.Length;
                rgbOutputFileContents = Marshal.AllocCoTaskMem(pcbOutput);
                Marshal.Copy(bytes, 0, rgbOutputFileContents, pcbOutput);
            }
        }
Example #8
0
        // called by custom tool invocation in Visual Studio
        // inputFile is the fullpath and filename of the file the user right clicked on
        public int Generate(string inputFile, string InputFileContents, string defaultNamespace, IntPtr[] outputFileContents, out uint pcbOutput, IVsGeneratorProgress pGenerateProgress)
        {
            XMLParser myParser = new XMLParser(inputFile);

            String parsingResult = myParser.Parse();

            // append namespace if provided
            if (defaultNamespace.Length > 0)
            {
                String namespaceBegin = "namespace "+ defaultNamespace + " { "+Environment.NewLine;

                parsingResult = namespaceBegin + parsingResult + " }";
            }

            ASCIIEncoding enc = new ASCIIEncoding();
            byte[] forOutputFile = enc.GetBytes(parsingResult);

            if (forOutputFile == null)
            {
                outputFileContents[0] = IntPtr.Zero;

                pcbOutput = 0;
            }
            else
            {
                // allocate memory and copy byte array for output file
                outputFileContents[0] = Marshal.AllocCoTaskMem(forOutputFile.Length);

                Marshal.Copy(forOutputFile, 0, outputFileContents[0], forOutputFile.Length);

                pcbOutput = (uint)forOutputFile.Length; // as per docs, return length of byte stream
            }

            return VSConstants.S_OK;
        }
        /// <summary>
        /// main method that the VS shell calls to do the generation
        /// </summary>
        /// <param name="wszInputFilePath">path to the input file</param>
        /// <param name="bstrInputFileContents">contents of the input file as a string (shell handles UTF-8 to Unicode & those types of conversions)</param>
        /// <param name="wszDefaultNamespace">default namespace for the generated code file</param>
        /// <param name="rgbOutputFileContents">byte-array of output file contents</param>
        /// <param name="pcbOutput">count of bytes in the output byte-array</param>
        /// <param name="pGenerateProgress">interface to send progress updates to the shell</param>
        public int Generate( string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace,
            IntPtr[] rgbOutputFileContents, out uint pcbOutput,
            Microsoft.VisualStudio.Shell.Interop.IVsGeneratorProgress pGenerateProgress)
        {
            if (bstrInputFileContents == null) throw new ArgumentNullException( bstrInputFileContents );

            this.codeFilePath = wszInputFilePath;
            this.codeFileNameSpace = wszDefaultNamespace;
            this.codeGeneratorProgress = pGenerateProgress;

            var bytes = this.GenerateCode( wszInputFilePath, bstrInputFileContents );

            if (bytes == null)
            {
                rgbOutputFileContents[0] = IntPtr.Zero;
                pcbOutput = 0;
            }
            else
            {
                pcbOutput = (uint)bytes.Length;
                rgbOutputFileContents[0] = Marshal.AllocCoTaskMem( bytes.Length );
                Marshal.Copy( bytes, 0, rgbOutputFileContents[0], bytes.Length );
            }

            return 0;
        }
Example #10
0
        /// <summary>
        /// Executes the transformation and returns the newly generated output file, whenever a custom tool is loaded, or the input file is saved.
        /// </summary>
        /// <returns>
        /// If the method succeeds, it returns <see cref="F:Microsoft.VisualStudio.VSConstants.S_OK"/>. If it fails, it returns an error code.
        /// </returns>
        /// <param name="wszInputFilePath">[in] The full path of the input file. May be null in future releases of Visual Studio, so generators should not rely on this value.</param><param name="bstrInputFileContents">[in] The contents of the input file. This is either a UNICODE BSTR (if the input file is text) or a binary BSTR (if the input file is binary). If the input file is a text file, the project system automatically converts the BSTR to UNICODE.</param><param name="wszDefaultNamespace">[in] This parameter is meaningful only for custom tools that generate code. It represents the namespace into which the generated code will be placed. If the parameter is not null and not empty, the custom tool can use the following syntax to enclose the generated code.   ' Visual Basic Namespace [default namespace]... End Namespace// Visual C#namespace [default namespace] { ... }</param><param name="rgbOutputFileContents">[out] Returns an array of bytes to be written to the generated file. You must include UNICODE or UTF-8 signature bytes in the returned byte array, as this is a raw stream. The memory for <paramref name="rgbOutputFileContents"/> must be allocated using the .NET Framework call, System.Runtime.InteropServices.AllocCoTaskMem, or the equivalent Win32 system call, CoTaskMemAlloc. The project system is responsible for freeing this memory.</param><param name="pcbOutput">[out] Returns the count of bytes in the <paramref name="rgbOutputFileContent"/> array.</param><param name="pGenerateProgress">[in] A reference to the <see cref="T:Microsoft.VisualStudio.Shell.Interop.IVsGeneratorProgress"/> interface through which the generator can report its progress to the project system.</param>
        public int Generate(string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace, IntPtr[] rgbOutputFileContents, out uint pcbOutput, IVsGeneratorProgress pGenerateProgress)
        {
            var generator = new Generator();
            ICodeFileWriterContext generatedFile;
            if (bstrInputFileContents.StartsWith("{"))
            {
                generatedFile = generator.CreateFile(wszDefaultNamespace, bstrInputFileContents);
            }
            else
            {
                try
                {
                    ServicePointManager.ServerCertificateValidationCallback = CertificateValidation;
                    var reader = new WebClient();

                    reader.Credentials = new NetworkCredential(ConfigurationManager.AppSettings["stardust.configUser"], ConfigurationManager.AppSettings["stardust.configPassword"], ConfigurationManager.AppSettings["stardust.configDomain"]);
                    var content = reader.DownloadString(string.Format("{0}&updV={1}", bstrInputFileContents, DateTime.Now.Ticks));
                    generatedFile = generator.CreateFile(wszDefaultNamespace, content);
                }
                catch (Exception ex)
                {
                    
                    throw new Exception("Unable to download settings from: "+bstrInputFileContents);
                }
            }
            pcbOutput = (uint)generator.Save(generatedFile, rgbOutputFileContents);
            return VSConstants.S_OK;
        }
Example #11
0
      int IVsSingleFileGenerator.Generate(string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace, IntPtr[] rgbOutputFileContents, out uint pcbOutput, IVsGeneratorProgress pGenerateProgress)
      {
         ProgressReporter reporter = new ProgressReporter(pGenerateProgress);

         bool fail = false;
         string output;
         try
         {
            output = Generate(wszInputFilePath, bstrInputFileContents, wszDefaultNamespace, new ServiceProvider(Site as Microsoft.VisualStudio.OLE.Interop.IServiceProvider).GetService(typeof(ProjectItem)) as ProjectItem, reporter);
         }
         catch (Exception ex)
         {
            output = "An unhandled exception occurred during generation; " + ex.Message;
            reporter.GenerateError(ex.Message);
            fail = true;
         }


         byte[] bytes = Encoding.UTF8.GetBytes(output);

         int outputLength = bytes.Length;
         rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(outputLength);
         Marshal.Copy(bytes, 0, rgbOutputFileContents[0], outputLength);
         pcbOutput = (uint)outputLength;

         return fail ? VSConstants.E_FAIL : VSConstants.S_OK;
      }
        public int Generate( string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace,
                             IntPtr[] pbstrOutputFileContents, out uint pbstrOutputFileContentSize, IVsGeneratorProgress pGenerateProgress )
        {

            if(bstrInputFileContents == null)
            {
                throw new ArgumentNullException( bstrInputFileContents );
            }
            codeFilePath = wszInputFilePath;
            codeFileNameSpace = wszDefaultNamespace;
            codeGeneratorProgress = pGenerateProgress;

            byte[] bytes = GenerateCode( wszInputFilePath, bstrInputFileContents );
            if(bytes == null)
            {
                pbstrOutputFileContents[0] = IntPtr.Zero;
                pbstrOutputFileContentSize = 0;
            }
            else
            {
                pbstrOutputFileContents[0] = Marshal.AllocCoTaskMem( bytes.Length );
                Marshal.Copy( bytes, 0, pbstrOutputFileContents[0], bytes.Length );
                pbstrOutputFileContentSize = (uint)bytes.Length;
            }
            return Utility.COM_HResults.S_OK;
        }
        // wraps GenerateRaw in a message pump so that Visual Studio
        // will display the nice "waiting" modal window...
        private int GenerateWithPump(string wszInputFilePath,
                                     //string bstrInputFileContents,
                                     string wszDefaultNamespace,
                                     IntPtr[] rgbOutputFileContents,
                                     out uint pcbOutput,
                                     IVsGeneratorProgress pGenerateProgress)
        {
            uint pcbOutput2 = 0;
            var rc = 0;
            string errMsg = null;

            VisualStudioHelper.PumpAction("Generating models...", "Please wait while Umbraco.ModelsBuilder generates models.", () =>
            {
                rc = GenerateRaw(wszInputFilePath,
                //bstrInputFileContents,
                wszDefaultNamespace,
                rgbOutputFileContents,
                out pcbOutput2,
                //pGenerateProgress,
                out errMsg);
            });

            // get value back
            pcbOutput = pcbOutput2;

            // handle error here - cannot do it in PumpAction - ComObject exception
            if (errMsg != null)
                VisualStudioHelper.ReportError(pGenerateProgress, errMsg);

            return rc;
        }
Example #14
0
		/////////////////////////////////////////////////////////////////////////////

		public void Generate(string inputFilePath, string inputFileContents, string defaultNamespace, out IntPtr outputFileContents, out int output, IVsGeneratorProgress generateProgress)
		{
			if (inputFileContents == null)
			{
				throw new ArgumentNullException("inputFileContents");
			}
			try
			{
				this.codeFilePath = inputFilePath;
				this.codeFileNamespace = defaultNamespace;
				this.codeGeneratorProgress = generateProgress;
				byte[] source = this.GenerateCode(inputFilePath, inputFileContents);
				if (source == null)
				{
					outputFileContents = IntPtr.Zero;
					output = 0;
				}
				else
				{
					output = source.Length;
					outputFileContents = Marshal.AllocCoTaskMem(output);
					Marshal.Copy(source, 0, outputFileContents, output);
				}
			}
			//catch ( Exception ex ) {
			//	throw;
			//}
			finally
			{
				this.codeFilePath = null;
				this.codeFileNamespace = null;
				this.codeGeneratorProgress = null;
			}
		}
Example #15
0
        protected virtual string GenerateError(IVsGeneratorProgress pGenerateProgress, Exception ex)
        {
            var Message = ex.ToString();

            pGenerateProgress.GeneratorError(0, 4, Message, 0xFFFFFFFF, 0xFFFFFFFF);

            return Message;
        }
        /// <summary>
        ///     Releases unmanaged and - optionally - managed resources.
        /// </summary>
        /// <param name="disposing">
        ///     <c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.
        /// </param>
        protected virtual void Dispose(bool disposing)
        {
            // TODO: uncomment this assert when and if VSCore starts to dispose IVsSingleFileGenerator-s
            //Debug.Assert(disposing,            
            //    typeof(BaseCodeGenerator).Name + ".Dispose(): Finalizing BaseCodeGenerator without disposing it first!");

            _codeGeneratorProgress = null;
        }
Example #17
0
        /// <summary>
        /// Called by Visual Studio when it needs to generate or 
        /// regenerate the code file from your the custom tool
        /// input file.
        /// </summary>
        /// <param name="wszInputFilePath"></param>
        /// <param name="bstrInputFileContents"></param>
        /// <param name="wszDefaultNamespace"></param>
        /// <param name="rgbOutputFileContents"></param>
        /// <param name="pcbOutput"></param>
        /// <param name="pGenerateProgress"></param>
        /// <returns></returns>
        int IVsSingleFileGenerator.Generate(string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace, IntPtr[] rgbOutputFileContents, out uint pcbOutput, IVsGeneratorProgress pGenerateProgress)
        {
            GenerationEventArgs gea = new GenerationEventArgs(
                bstrInputFileContents,
                wszInputFilePath,
                wszDefaultNamespace,
                new ServiceProvider(Site as Microsoft.VisualStudio.OLE.Interop.IServiceProvider)
                    .GetService(typeof(ProjectItem)) as ProjectItem);

            if (OnGenerateCode != null)
            {
                OnGenerateCode(this, gea);
            }

            if (gea.OutputFileExtension.StartsWith("."))
            {
                this.FileExtension = gea.OutputFileExtension;
            }
            else
            {
                this.FileExtension = "." + gea.OutputFileExtension;
            }

            GenerationProgressFacade progressFacade =
                new GenerationProgressFacade(pGenerateProgress);

            foreach (GenerationWarning warning in gea.Warnings)
            {
                progressFacade.GenerateWarning(
                    warning.Message,
                    warning.LineNumber,
                    warning.ColumnNumber);
            }

            foreach (GenerationError error in gea.Errors)
            {
                progressFacade.GenerateError(
                    error.Message,
                    error.LineNumber,
                    error.ColumnNumber);
            }

            byte[] bytes = gea.GetOutputCodeBytes();

            int outputLength = bytes.Length;
            rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(outputLength);
            Marshal.Copy(bytes, 0, rgbOutputFileContents[0], outputLength);
            pcbOutput = (uint)outputLength;

            if (gea.FailOnError && gea.Errors.Count > 0)
            {
                return VSConstants.E_FAIL;
            }
            else
            {
                return VSConstants.S_OK;
            }
        }
        protected override byte[] Generate(string inputFilePath, string inputFileContents, string defaultNamespace, IVsGeneratorProgress progressCallback)
        {
            if (inputFileContents == null)
            {
                throw new ArgumentNullException(nameof(inputFileContents));
            }

            var gen = GeneratorAgent.Gen(inputFilePath, inputFileContents, defaultNamespace);
            return gen == null ? new byte[] { } : Encoding.UTF8.GetBytes(gen);
        }
Example #19
0
 public int Generate(string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace, IntPtr[] rgbOutputFileContents, out uint pcbOutput, IVsGeneratorProgress pGenerateProgress)
 {
     string contentsString = GetContents(wszInputFilePath, bstrInputFileContents, wszDefaultNamespace, pGenerateProgress);
     byte[] contents = Encoding.UTF8.GetBytes(contentsString);
     int contentsLength = contents.Length;
     pcbOutput = Convert.ToUInt32(contentsLength);
     rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(contentsLength);
     Marshal.Copy(contents, 0, rgbOutputFileContents[0], contentsLength);
     return VSConstants.S_OK;
 }
Example #20
0
        protected override byte[] Generate(string inputFilePath, string inputFileContents, string defaultNamespace, IVsGeneratorProgress progressCallback)
        {

            var viewGen = new DryHtml.ViewGen.ViewGenerator(inputFilePath);
            viewGen.GenerateAll();

            progressCallback.Progress(100, 100);

            return new byte[0];
        }
Example #21
0
        int IVsSingleFileGenerator.Generate(string wszInputFilePath,
                                            string bstrInputFileContents,
                                            string wszDefaultNamespace,
                                            IntPtr[] rgbOutputFileContents,
                                            out uint pcbOutput,
                                            IVsGeneratorProgress pGenerateProgress)
        {
            string trimmedInputFileContents = bstrInputFileContents.Trim();
            codeFilePath = wszInputFilePath;
            codeFileNameSpace = wszDefaultNamespace;
            codeGeneratorProgress = pGenerateProgress;
            byte[] bytes = null;
            try
            {
                BeforeCodeGenerated();
                string generatedCode = null;
                if (IsSharePointFeature(trimmedInputFileContents))
                {
                    StringBuilder sharePointFeatureComment = new StringBuilder();
                    sharePointFeatureComment.AppendFormat("/*SpecFlow tried to generate a test class file, but {0} appears to be a SharePoint feature.", wszInputFilePath);
                    sharePointFeatureComment.AppendLine("  The SpecFlow test class was not be generated in order to avoid errors in the SharePoint proejct*/");
                    generatedCode = sharePointFeatureComment.ToString();
                }
                else
                {
                    generatedCode = GenerateCode(bstrInputFileContents);
                }
                if (generatedCode == null)
                {
                    bytes = GetBytesForError(pGenerateProgress, null);
                }
                else
                {
                    bytes = Encoding.UTF8.GetBytes(generatedCode);
                    AfterCodeGenerated(false);
                }
            }
            catch(Exception ex)
            {
                bytes = GetBytesForError(pGenerateProgress, ex);
            }

            byte[] utf8BOM = new byte[] { 0xEF, 0xBB, 0xBF };
            int outputLength = utf8BOM.Length + bytes.Length;
            byte[] output = new byte[outputLength];
            Array.Copy(utf8BOM, 0, output, 0, utf8BOM.Length);
            Array.Copy(bytes, 0, output, utf8BOM.Length, bytes.Length);
            rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(outputLength);
            Marshal.Copy(output, 0, rgbOutputFileContents[0], outputLength);
            pcbOutput = (uint)outputLength;

            RefreshMsTestWindow();

            return VSConstants.S_OK;
        }
        public int Generate(string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace, IntPtr[] rgbOutputFileContents, out uint pcbOutput, IVsGeneratorProgress pGenerateProgress)
        {
            string result = Transform(Path.GetFileName(wszInputFilePath), bstrInputFileContents);

            byte[] buf = Encoding.UTF8.GetBytes(result);

            rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(buf.Length);
            Marshal.Copy(buf, 0, rgbOutputFileContents[0], buf.Length);
            pcbOutput = (uint)(buf.Length);

            return VSConstants.S_OK;
        }
        public int Generate(string inputFilePath, string inputFileContents, string defaultNamespace, IntPtr[] outputFileContents, out uint bytesWritten, IVsGeneratorProgress progress)
        {
            var generator = new FixtureGenerator();
            var code = generator.GenerateCode(inputFilePath, inputFileContents, defaultNamespace);

            var bytes = Encoding.UTF8.GetBytes(code);
            var length = bytes.Length;

            bytesWritten = (uint) length;

            outputFileContents[0] = Marshal.AllocCoTaskMem(length);
            Marshal.Copy(bytes, 0, outputFileContents[0], length);
            return VSConstants.S_OK;
        }
 protected override int Generate(string wszInputFilePath,
                             string bstrInputFileContents,
                             string wszDefaultNamespace,
                             IntPtr[] rgbOutputFileContents,
                             out uint pcbOutput,
                             IVsGeneratorProgress pGenerateProgress)
 {
     return GenerateWithPump(wszInputFilePath,
         //bstrInputFileContents,
         wszDefaultNamespace,
         rgbOutputFileContents,
         out pcbOutput,
         pGenerateProgress);
 }
        public int Generate(string inputFilePath, string inputFileContents, string defaultNamespace, IntPtr[] outputFileContents, out uint outputLength, IVsGeneratorProgress generatorProgress)
        {
            if (outputFileContents != null && outputFileContents.Length > 0)
            {
                // Do this first, before input validation, so that the
                // catch block doesn't try to free memory with an uninitialized pointer.
                outputFileContents[0] = IntPtr.Zero;
            }

            try
            {
                Requires.NotNullOrEmpty(inputFilePath, "inputFilePath");
                Requires.NotNull(outputFileContents, "outputFileContents");
                Requires.Argument(outputFileContents.Length > 0, "outputFileContents", "Non-empty array expected.");

                string generated = null;
                ThreadHelper.JoinableTaskFactory.Run(async delegate
                {
                    VisualStudioWorkspace workspace = GetRoslynWorkspace();
                    var inputDocumentId = workspace.CurrentSolution.GetDocumentIdsWithFilePath(inputFilePath).First();
                    var inputDocument = workspace.CurrentSolution.GetDocument(inputDocumentId);
                    var outputDocument = await DocumentTransform.TransformAsync(inputDocument, new ProgressShim(generatorProgress));

                    // Now render as a complete string, as necessary by our single file generator.
                    var reducedDocumentText = await outputDocument.GetTextAsync();
                    generated = reducedDocumentText.ToString();
                });

                // Translate the string we've built up into the bytes of COM memory required.
                var encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: true);
                byte[] bytes = encoding.GetBytes(generated);
                outputLength = (uint)bytes.Length;
                outputFileContents[0] = Marshal.AllocCoTaskMem(bytes.Length);
                Marshal.Copy(bytes, 0, outputFileContents[0], bytes.Length);

                return VSConstants.S_OK;
            }
            catch (Exception ex)
            {
                if (outputFileContents[0] != IntPtr.Zero)
                {
                    Marshal.FreeCoTaskMem(outputFileContents[0]);
                    outputFileContents[0] = IntPtr.Zero;
                }

                outputLength = 0;
                return Marshal.GetHRForException(ex);
            }
        }
        protected override string GenerateError(IVsGeneratorProgress pGenerateProgress, Exception ex)
        {
            if (ex == null)
            {
                VisualStudioTracer.Assert(generationResult != null, "no reneration result found");
                VisualStudioTracer.Assert(!generationResult.Success, "generation result is not a failure");

                foreach (var error in generationResult.Errors)
                {
                    pGenerateProgress.GeneratorError(0, 4, error.Message, (uint) error.Line, (uint) error.LinePosition);
                }

                return string.Join(Environment.NewLine, generationResult.Errors.Select(e => e.Message));
            }
            return base.GenerateError(pGenerateProgress, ex);
        }
        /// <summary>
        /// Implements the IVsSingleFileGenerator.Generate method.
        /// Executes the transformation and returns the newly generated output file, whenever a custom tool is loaded, or the input file is saved
        /// </summary>
        /// <param name="wszInputFilePath">The full path of the input file. May be a null reference (Nothing in Visual Basic) in future releases of Visual Studio, so generators should not rely on this value</param>
        /// <param name="bstrInputFileContents">The contents of the input file. This is either a UNICODE BSTR (if the input file is text) or a binary BSTR (if the input file is binary). If the input file is a text file, the project system automatically converts the BSTR to UNICODE</param>
        /// <param name="wszDefaultNamespace">This parameter is meaningful only for custom tools that generate code. It represents the namespace into which the generated code will be placed. If the parameter is not a null reference (Nothing in Visual Basic) and not empty, the custom tool can use the following syntax to enclose the generated code</param>
        /// <param name="rgbOutputFileContents">[out] Returns an array of bytes to be written to the generated file. You must include UNICODE or UTF-8 signature bytes in the returned byte array, as this is a raw stream. The memory for rgbOutputFileContents must be allocated using the .NET Framework call, System.Runtime.InteropServices.AllocCoTaskMem, or the equivalent Win32 system call, CoTaskMemAlloc. The project system is responsible for freeing this memory</param>
        /// <param name="pcbOutput">[out] Returns the count of bytes in the rgbOutputFileContent array</param>
        /// <param name="pGenerateProgress">A reference to the IVsGeneratorProgress interface through which the generator can report its progress to the project system</param>
        /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns E_FAIL</returns>
        public int Generate(string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace,
            IntPtr[] rgbOutputFileContents, out uint pcbOutput, IVsGeneratorProgress pGenerateProgress)
        {
            var generatedFileByes = Encoding.UTF8.GetBytes(string.Empty);

            // The contract between IVsSingleFileGenerator implementors and consumers is that
            // any output returned from IVsSingleFileGenerator.Generate() is returned through
            // memory allocated via CoTaskMemAlloc(). Therefore, we have to convert the
            // byte[] array returned from GenerateCode() into an unmanaged blob.

            int outputLength = generatedFileByes.Length;
            rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(outputLength);
            Marshal.Copy(generatedFileByes, 0, rgbOutputFileContents[0], outputLength);
            pcbOutput = (uint)outputLength;
            return VSConstants.S_OK;
        }
        public int Generate(string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace, IntPtr[] rgbOutputFileContents, out uint pcbOutput, IVsGeneratorProgress pGenerateProgress)
        {
            if (bstrInputFileContents == null)
                throw new ArgumentException(bstrInputFileContents);

            FileInfo fi = new FileInfo(wszInputFilePath);
            string className = fi.Name.Split('.').First();

            Dictionary<string, object> TemplateParameters = new Dictionary<string, object>();
            TemplateParameters.Add("JsonText", bstrInputFileContents);
            TemplateParameters.Add("JsonNamespace", wszDefaultNamespace);
            TemplateParameters.Add("JsonClass", className);

            JsonT4 t4 = new JsonT4();
            t4.Session = TemplateParameters;
            //t4.WriteLine("//------------------------------------------------------------------------------");
            //t4.WriteLine("// <auto-generated>");
            //t4.WriteLine("//     This code was generated by a tool.");
            //t4.WriteLine("//     Runtime Version:4.0.30319.239");
            //t4.WriteLine("//");
            //t4.WriteLine("//     Changes to this file may cause incorrect behavior and will be lost if");
            //t4.WriteLine("//     the code is regenerated.");
            //t4.WriteLine("// </auto-generated>");
            //t4.WriteLine("//------------------------------------------------------------------------------");
            t4.Initialize();
            string csCode = t4.TransformText();

            //csCode = Format(csCode);
           
            byte[] bytes = Encoding.UTF8.GetBytes(csCode);

            if (bytes == null)
            {
                rgbOutputFileContents[0] = IntPtr.Zero;
                pcbOutput = 0;
            }
            else
            {
                rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(bytes.Length);
                Marshal.Copy(bytes, 0, rgbOutputFileContents[0], bytes.Length);

                pcbOutput = (uint)bytes.Length;
            }

            return VSConstants.S_OK;
        }
Example #29
0
		public int Generate(string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace, IntPtr[] rgbOutputFileContents, out uint pcbOutput, IVsGeneratorProgress pGenerateProgress) {
			string className = Path.GetFileNameWithoutExtension(wszInputFilePath);
			
			string result;
			try {
				string configPath = ExecutablesCommon.FindConfigFilePath(wszInputFilePath);
                result = ExecutablesCommon.ProcessContentInSeparateAppDomain(configPath, bstrInputFileContents, className, wszDefaultNamespace);
			}
			catch (Exception ex) {
				result = ex.ToString();
			}

			byte[] bytes = Encoding.UTF8.GetBytes(result);
			rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(bytes.Length);
			Marshal.Copy(bytes, 0, rgbOutputFileContents[0], bytes.Length);
			pcbOutput = (uint)bytes.Length;
			return VSConstants.S_OK;
		}
    public int Generate(string aInputFilePath, string aInputFileContents, string aDefaultNamespace, IntPtr[] aOutputFileContents, out uint oPcbOutput, IVsGeneratorProgress aGenerateProgress) {
      string xResult;
      using (var xInput = new StringReader(aInputFileContents)) {
        using (var xOut = new StringWriter()) {
            try
            {
              new Assembler();
              try
              {
                var xGen = new XSharp.Compiler.AsmGenerator();
                xGen.Generate(xInput, xOut);
                xResult =
                  "; Generated at " + DateTime.Now.ToString() + "\r\n"
                  + "\r\n"
                  + xOut.ToString() + "\r\n";
              }
              finally
              {
                Assembler.ClearCurrentInstance();
              }
            } catch (Exception ex) {
              var xSB = new StringBuilder();
              xSB.Append(xOut);
              xSB.AppendLine();

              for (Exception e = ex; e != null; e = e.InnerException) {
                xSB.AppendLine(e.Message);
              }
              xResult = xSB.ToString();
            }
          }
      }

      aOutputFileContents[0] = IntPtr.Zero;
      oPcbOutput = 0;
      var xBytes = Encoding.UTF8.GetBytes(xResult);
      if (xBytes.Length > 0) {
        aOutputFileContents[0] = Marshal.AllocCoTaskMem(xBytes.Length);
        Marshal.Copy(xBytes, 0, aOutputFileContents[0], xBytes.Length);
        oPcbOutput = (uint)xBytes.Length;
      }

      return VSConstants.S_OK;
    }
Example #31
0
        int IVsSingleFileGenerator.Generate(string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace, IntPtr[] rgbOutputFileContents, out uint pcbOutput, IVsGeneratorProgress pGenerateProgress)
        {
            if (bstrInputFileContents == null)
            {
                throw new ArgumentException(nameof(bstrInputFileContents));
            }
            InputFilePath         = wszInputFilePath;
            FileNamespace         = wszDefaultNamespace;
            CodeGeneratorProgress = pGenerateProgress;

            byte[] bytes = GenerateCode(bstrInputFileContents);

            if (bytes == null)
            {
                rgbOutputFileContents = null;
                pcbOutput             = 0;
                return(VSConstants.E_FAIL);
            }

            int outputLength = bytes.Length;

            rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(outputLength);
            Marshal.Copy(bytes, 0, rgbOutputFileContents[0], outputLength);
            pcbOutput = (uint)outputLength;
            return(VSConstants.S_OK);
        }
Example #32
0
        /// <summary>
        /// Implements the IVsSingleFileGenerator.Generate method.
        /// Executes the transformation and returns the newly generated output file, whenever a custom tool is loaded, or the input file is saved
        /// </summary>
        /// <param name="wszInputFilePath">The full path of the input file. May be a null reference (Nothing in Visual Basic) in future releases of Visual Studio, so generators should not rely on this value</param>
        /// <param name="bstrInputFileContents">The contents of the input file. This is either a UNICODE BSTR (if the input file is text) or a binary BSTR (if the input file is binary). If the input file is a text file, the project system automatically converts the BSTR to UNICODE</param>
        /// <param name="wszDefaultNamespace">This parameter is meaningful only for custom tools that generate code. It represents the namespace into which the generated code will be placed. If the parameter is not a null reference (Nothing in Visual Basic) and not empty, the custom tool can use the following syntax to enclose the generated code</param>
        /// <param name="rgbOutputFileContents">[out] Returns an array of bytes to be written to the generated file. You must include UNICODE or UTF-8 signature bytes in the returned byte array, as this is a raw stream. The memory for rgbOutputFileContents must be allocated using the .NET Framework call, System.Runtime.InteropServices.AllocCoTaskMem, or the equivalent Win32 system call, CoTaskMemAlloc. The project system is responsible for freeing this memory</param>
        /// <param name="pcbOutput">[out] Returns the count of bytes in the rgbOutputFileContent array</param>
        /// <param name="pGenerateProgress">A reference to the IVsGeneratorProgress interface through which the generator can report its progress to the project system</param>
        /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns E_FAIL</returns>
        int IVsSingleFileGenerator.Generate(string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace, IntPtr[] rgbOutputFileContents, out uint pcbOutput, IVsGeneratorProgress pGenerateProgress)
        {
            if (bstrInputFileContents == null)
            {
                throw new ArgumentNullException(bstrInputFileContents);
            }

            codeFilePath          = wszInputFilePath;
            codeFileNameSpace     = wszDefaultNamespace;
            codeGeneratorProgress = pGenerateProgress;

            byte[] bytes = GenerateCode(bstrInputFileContents);

            if (bytes == null)
            {
                // This signals that GenerateCode() has failed. Tasklist items have been put up in GenerateCode()
                rgbOutputFileContents = null;
                pcbOutput             = 0;

                // Return E_FAIL to inform Visual Studio that the generator has failed (so that no file gets generated)
                return(VSConstants.E_FAIL);
            }
            else
            {
                // The contract between IVsSingleFileGenerator implementors and consumers is that
                // any output returned from IVsSingleFileGenerator.Generate() is returned through
                // memory allocated via CoTaskMemAlloc(). Therefore, we have to convert the
                // byte[] array returned from GenerateCode() into an unmanaged blob.

                int outputLength = bytes.Length;
                rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(outputLength);
                Marshal.Copy(bytes, 0, rgbOutputFileContents[0], outputLength);
                pcbOutput = (uint)outputLength;
                return(VSConstants.S_OK);
            }
        }
Example #33
0
        public int Generate(string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace, IntPtr[] rgbOutputFileContents, out uint pcbOutput, IVsGeneratorProgress pGenerateProgress)
        {
            try
            {
                XmlDocument source = new XmlDocument();
                source.LoadXml(bstrInputFileContents);

                string xsltFileName = source.DocumentElement.GetAttribute("generator");
                if (xsltFileName == null || xsltFileName == "")
                {
                    xsltFileName = "ModelGenerator.xslt";
                }
                string xsltFile =
                    wszInputFilePath.Split(new string[] { "Schema" }, StringSplitOptions.None)[0]
                    + @"Schema\XsltGenerator\" + xsltFileName;
                if (!File.Exists(xsltFile))
                {
                    throw new ApplicationException("Xslt file not exists: " + xsltFile);
                }


                XslCompiledTransform transformator = new XslCompiledTransform();
                transformator.Load(xsltFile);

                string rootPath = Path.GetFullPath(wszInputFilePath);
                rootPath = rootPath.Substring(0, rootPath.LastIndexOf('\\') + 1);
                XsltUtil         util = new XsltUtil(rootPath, "ConnectionString");
                XsltArgumentList args = new XsltArgumentList();
                args.AddParam("param_namespace", "", wszDefaultNamespace);
                args.AddExtensionObject("urn:util", util);
                using (MemoryStream stream = new MemoryStream())
                {
                    transformator.Transform(source, args, stream);
                    stream.Position = 0;
                    byte[] content = stream.ToArray();
                    pcbOutput = (uint)content.Length;
                    rgbOutputFileContents[0] = Marshal.AllocCoTaskMem((int)content.Length);
                    Marshal.Copy(content, 0, rgbOutputFileContents[0], (int)content.Length);
                }
            }
            catch (Exception ex)
            {
                byte[] content = Encoding.UTF8.GetBytes(ex.ToString());
                pcbOutput = (uint)content.Length;
                rgbOutputFileContents[0] = Marshal.AllocCoTaskMem((int)content.Length);
                Marshal.Copy(content, 0, rgbOutputFileContents[0], (int)content.Length);
            }

            return(VSConstants.S_OK);
        }
Example #34
0
        public int Generate(string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace, IntPtr[] rgbOutputFileContents, out uint pcbOutput, IVsGeneratorProgress pGenerateProgress)
        {
            string className = Path.GetFileNameWithoutExtension(wszInputFilePath);

            string result;

            try {
                string configPath = ExecutablesCommon.FindConfigFilePath(wszInputFilePath);
                result = ExecutablesCommon.ProcessContentInSeparateAppDomain(configPath, bstrInputFileContents, className, wszDefaultNamespace);
            }
            catch (Exception ex) {
                result = ex.ToString();
            }

            byte[] bytes = Encoding.UTF8.GetBytes(result);
            rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(bytes.Length);
            Marshal.Copy(bytes, 0, rgbOutputFileContents[0], bytes.Length);
            pcbOutput = (uint)bytes.Length;
            return(VSConstants.S_OK);
        }
Example #35
0
 public abstract string Translate(string inputText, string defaultNamespace, IVsGeneratorProgress generateProgress);
Example #36
0
        public int Generate(string aInputFilePath, string aInputFileContents, string aDefaultNamespace, IntPtr[] aOutputFileContents, out uint oPcbOutput, IVsGeneratorProgress aGenerateProgress)
        {
            string xResult;

            using (var xInput = new StringReader(aInputFileContents))
            {
                using (var xOut = new StringWriter())
                {
                    try
                    {
                        new Assembler.Assembler();
                        try
                        {
                            var xGen = new AsmGenerator();
                            xGen.Generate(xInput, xOut);
                            xResult = $"Generated at {DateTime.Now} {Environment.NewLine} {Environment.NewLine} {xOut} {Environment.NewLine}";
                        }
                        finally
                        {
                            Assembler.Assembler.ClearCurrentInstance();
                        }
                    }
                    catch (Exception ex)
                    {
                        var xSB = new StringBuilder();
                        xSB.Append(xOut);
                        xSB.AppendLine();

                        for (Exception e = ex; e != null; e = e.InnerException)
                        {
                            xSB.AppendLine(e.Message);
                        }
                        xResult = xSB.ToString();
                    }
                }
            }

            aOutputFileContents[0] = IntPtr.Zero;
            oPcbOutput             = 0;
            var xBytes = Encoding.UTF8.GetBytes(xResult);

            if (xBytes.Length > 0)
            {
                aOutputFileContents[0] = Marshal.AllocCoTaskMem(xBytes.Length);
                Marshal.Copy(xBytes, 0, aOutputFileContents[0], xBytes.Length);
                oPcbOutput = (uint)xBytes.Length;
            }

            return(VSConstants.S_OK);
        }
Example #37
0
        public int Generate(string aInputFilePath, string aInputFileContents, string aDefaultNamespace, IntPtr[] aOutputFileContents, out uint oPcbOutput, IVsGeneratorProgress aGenerateProgress)
        {
            string xResult;

            using (var xInput = new StringReader(aInputFileContents)) {
                using (var xOutData = new StringWriter()) {
                    using (var xOutCode = new StringWriter()) {
                        try {
                            var xGen = new XSharp.Compiler.AsmGenerator();
                            xGen.Generate(xInput, xOutData, xOutCode);
                            xResult =
                                "; Generated at " + DateTime.Now.ToString() + "\r\n"
                                + "\r\n"
                                + xOutData.ToString() + "\r\n"
                                + xOutCode.ToString() + "\r\n";
                        } catch (Exception ex) {
                            var xSB = new StringBuilder();
                            xSB.Append(xOutData);
                            xSB.AppendLine();
                            xSB.Append(xOutCode);
                            xSB.AppendLine();

                            for (Exception e = ex; e != null; e = e.InnerException)
                            {
                                xSB.AppendLine(e.Message);
                            }
                            xResult = xSB.ToString();
                        }
                    }
                }
            }

            aOutputFileContents[0] = IntPtr.Zero;
            oPcbOutput             = 0;
            var xBytes = Encoding.UTF8.GetBytes(xResult);

            if (xBytes.Length > 0)
            {
                aOutputFileContents[0] = Marshal.AllocCoTaskMem(xBytes.Length);
                Marshal.Copy(xBytes, 0, aOutputFileContents[0], xBytes.Length);
                oPcbOutput = (uint)xBytes.Length;
            }

            return(VSConstants.S_OK);
        }
        /// <summary>
        /// Implements the IVsSingleFileGenerator.Generate method.
        /// Executes the transformation and returns the newly generated output file, whenever a custom tool is loaded, or the input file is saved
        /// </summary>
        /// <remarks>
        /// When this is called, the current generator enumerator consists of a list of file extentions that we are going to generate.
        /// </remarks>
        /// <param name="wszInputFilePath">The full path of the input file. May be a null reference (Nothing in Visual Basic) in future releases of Visual Studio, so generators should not rely on this value</param>
        /// <param name="bstrInputFileContents">The contents of the input file. This is either a UNICODE BSTR (if the input file is text) or a binary BSTR (if the input file is binary). If the input file is a text file, the project system automatically converts the BSTR to UNICODE</param>
        /// <param name="wszDefaultNamespace">This parameter is meaningful only for custom tools that generate code. It represents the namespace into which the generated code will be placed. If the parameter is not a null reference (Nothing in Visual Basic) and not empty, the custom tool can use the following syntax to enclose the generated code</param>
        /// <param name="rgbOutputFileContents">[out] Returns an array of bytes to be written to the generated file. You must include UNICODE or UTF-8 signature bytes in the returned byte array, as this is a raw stream. The memory for rgbOutputFileContents must be allocated using the .NET Framework call, System.Runtime.InteropServices.AllocCoTaskMem, or the equivalent Win32 system call, CoTaskMemAlloc. The project system is responsible for freeing this memory</param>
        /// <param name="pcbOutput">[out] Returns the count of bytes in the rgbOutputFileContent array</param>
        /// <param name="pGenerateProgress">A reference to the IVsGeneratorProgress interface through which the generator can report its progress to the project system</param>
        /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns E_FAIL</returns>
        public int Generate(string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace, IntPtr[] rgbOutputFileContents, out uint pcbOutput,
                            IVsGeneratorProgress pGenerateProgress)
        {
            // TODO: There are a number of nested try catch blocks that should be cleaned up.
            // Make sure exception handling is properly laid out. This function has high
            // complexity (probably too high with cycl over 30), which makes error handling important. What
            // exceptions escape (ie. not handled)? What halts file generation? etc...
            try
            {
                // EnsureActiveProjectSet();

                VsOutputWindowPaneManager.OutputWindowWriteLine(vsOutputWindowPaneName, "");
                VsOutputWindowPaneManager.OutputWindowWriteLine(vsOutputWindowPaneName, string.Format("------ CSD file generation started: Configuration document: {0} ------", InputFilePath));

                Diagnostics.DebugWrite("VsMultipleFileGenerator => VSMFG.");

                ProjectItem configurationSectionModelFile = null;

                _bstrInputFileContents = bstrInputFileContents;
                _wszInputFilePath      = wszInputFilePath;
                _generatorProgress     = pGenerateProgress;
                _oldFileNames.Clear();
                _newFileNames.Clear();

                // Look through all the projects in the solution
                // The _project holds DTE reference, so not needed here.
                //DTE dte = (DTE)Package.GetGlobalService(typeof(DTE));
                //Diagnostics.DebugWrite("VSMFG.Generate >> dte.Solution.Projects.Count = {0}.", dte.Solution.Projects.Count);

                VsOutputWindowPaneManager.OutputWindowWrite(vsOutputWindowPaneName, "* Searching for configuration project handle... ");

                Project     project     = null;
                ProjectItem projectItem = null;
                if (!VsHelper.FindProjectContainingFile(InputFilePath, out projectItem, out project))
                {
                    // TODO: Will this fail if NEW diagram is created but not saved? Confirm. I THINK empty diagram is always saved to disk upon creation.
                    throw new ApplicationException("Could not retrieve Visual Studio ProjectItem and/or parent project containing this CSD diagram. Has this diagram been saved yet after being created?");
                }
                _project = project;

                // obtain a reference to the current project as an IVsProject type
                IVsProject vsProject = VsHelper.ToVsProject(_project); // ABM - Issue 10435: 2nd WindowsService project results in FAILURE here.
                Diagnostics.DebugWrite("VH.TFP >> IVsProject vsProject = VsHelper.ToVsProject( project='{0}' )", _project.Name);

                int  iFound = 0;
                uint itemId = 0;

                // this locates, and returns a handle to our source file, as a ProjectItem
                // TODO: 20140908: Might not be needed due to the new way I locate projectitem and project.
                VSDOCUMENTPRIORITY[] prio = new VSDOCUMENTPRIORITY[(int)VSDOCUMENTPRIORITY.DP_Standard];
                int result = vsProject.IsDocumentInProject(InputFilePath, out iFound, prio, out itemId); // ABM - Issue 10435: WindowsService project results in iFound=0!!!

                #region VSITEMID Documentation
                // itemid: Pointer to the item identifier of the document within the project.
                // NOTE: itemId is either a specific id pointing to the file, or is one of VSITEMID enumeration.
                // VSITEMID represents Special items inside a VsHierarchy:

                /*
                 * public enum VSITEMID
                 * {
                 * Selection = 4294967293, // all the currently selected items. // represents the currently selected item or items, which can include the root of the hierarchy.
                 * Root = 4294967294,      // the hierarchy itself. // represents the root of a project hierarchy and is used to identify the entire hierarchy, as opposed to a single item.
                 * Nil = 4294967295,       // no node.// represents the absence of a project item. This value is used when there is no current selection.
                 * }
                 */
                /*
                 * http://visual-studio.todaysummary.com/q_visual-studio_76086.html
                 *
                 * http://msdn.microsoft.com/en-us/subscriptions/downloads/microsoft.visualstudio.shell.interop.ivshierarchy(v=vs.100).aspx
                 * The IVsHierarchy interface is a generic interface to a hierarchy of nodes. Each node, including the root node, can have arbitrary
                 * properties associated with it. Each node on the hierarchy object is identified using a cookie (VSITEMID), which indicates a particular
                 * node. This cookie is invisible to the consumer of IVsHierarchy, and is typically a pointer to some private data maintained by the
                 * hierarchy's implementation.
                 *
                 * A VSITEMID is a DWORD uniquely identifying a node within a hierarchy. Itemids from one IVsHierarchy may not be passed to another hierarchy. Also, note that itemids have a limited lifetime, as indicated by events fired by the hierarchy, so holding on to itemids for long durations will require either the sinking of these events, or the conversion of the itemid into a canonical, persistable form.
                 *
                 * An item in a hierarchy can be a leaf node, a container of other items, or a link into some other hierarchy using GetNestedHierarchy.
                 *
                 * The IVsHierarchy interface is not used only for project hierarchies. For example, the Server Explorer window implements the IVsHierarchy interface to display its hierarchy, which is not a project hierarchy.
                 *
                 * There are times when it is useful to query a hierarchy about various virtual nodes, such as the hierarchy itself or the selected nodes within the hierarchy. Where such virtual nodes are potentially of interest, one of the predefined VSITEMID values may be passed.
                 *
                 * The environment views a project as a hierarchy, that is, a tree of nodes in which the nodes are project items. Each node also has a set of associated properties, and provides hierarchy management for VSPackages that implement project hierarchies.
                 *
                 * Notes to Implementers
                 * Implemented by VSPackages that create their own project hierarchy.
                 *
                 * Notes to Callers
                 * Called by the environment to get and set hierarchy properties.*/

                #endregion

                if (result != VSConstants.S_OK)
                {
                    throw new Exception("Unexpected error calling IVsProject.IsDocumentInProject.");
                }

                Diagnostics.DebugWrite("VH.TFP >> vsProject.IsDocumentInProject(inputFilePath, out iFound={0}, pdwPriority, out itemId={1}).", iFound, itemId);

                // if this source file is found in this project
                if (iFound != 0 && itemId != 0)
                {
                    Diagnostics.DebugWrite("VH.TFP >> (iFound != 0 && itemId != 0) == TRUE!!!");
                    Microsoft.VisualStudio.OLE.Interop.IServiceProvider oleSp = null;
                    vsProject.GetItemContext(itemId, out oleSp);
                    if (oleSp != null)
                    {
                        Diagnostics.DebugWrite("VH.TFP >> vsProject.GetItemContext( itemId, out oleSp ) >> oleSp != null! Getting ServiceProvider sp...");
                        ServiceProvider sp = new ServiceProvider(oleSp);
                        // convert our handle to a ProjectItem
                        configurationSectionModelFile = sp.GetService(typeof(ProjectItem)) as ProjectItem;

                        if (configurationSectionModelFile != null)
                        {
                            Diagnostics.DebugWrite("VH.TFP >>  configurationSectionModelFile = sp.GetService( typeof( ProjectItem ) ) as ProjectItem is NOT null! Setting this._project to the project we were working on...");
                            // We now have what we need. Stop looking.
                        }
                    }
                    else
                    {
                        throw new ApplicationException("Unable to retrieve Visual Studio ProjectItem");
                    }
                }
                else
                {
                    VsOutputWindowPaneManager.OutputWindowWriteLine(vsOutputWindowPaneName, "error: Unable to retrieve Visual Studio ProjectItem. File generation halted.");
                    throw new ApplicationException("Unable to retrieve Visual Studio ProjectItem. Try running the tool again.");
                }

                // ABM: Code below was the complex and error prone way to find project/items. Interface exists to easily
                // locate these items. This interface is used to set current project as local variable instead of here.
                /**/
                // [7296] FILE = ~\ConfigurationSectionDesigner\Debugging\Sample.csd.
                if (!VsHelper.TryFindProjectItemAndParentProject(InputFilePath, out _project, out configurationSectionModelFile) || _project == null)
                {
                    VsOutputWindowPaneManager.OutputWindowWriteLine(vsOutputWindowPaneName, "error: Unable to retrieve Visual Studio ProjectItem. File generation halted.");
                    throw new ApplicationException("Unable to retrieve Visual Studio ProjectItem. Try running the tool again.");
                }
                /**/
                VsOutputWindowPaneManager.OutputWindowWriteLine(vsOutputWindowPaneName, "found!");

                // Check out this CSD file. DISABLED: Too much can go wrong the way this generator is currently structured.

                /*if (_project.DTE.SourceControl.IsItemUnderSCC(InputFilePath) && !_project.DTE.SourceControl.IsItemCheckedOut(InputFilePath))
                 * { _project.DTE.SourceControl.CheckOutItem(InputFilePath); } */

                // Check for source control integration for the CSD item and check it out of needed.
                //if (VsHelper.IsItemUnderSourceControl(dte, configurationSectionModelFile))
                if (_project.DTE.SourceControl.IsItemUnderSCC(InputFilePath) &&
                    !_project.DTE.SourceControl.IsItemCheckedOut(InputFilePath))
                {
                    // ABM: For simplicity, we checkout the CSD file and all subitems. All file operations later down the chain will not have a SC issue.
                    // REASON: This generator has a unique design where null generated content means "don't write to file at this step". For cs files,
                    //         the write to file occurs outside of the iteration later on. For diagram, it never happens. All of these conditions
                    //         make selective SC checkout more complicated than the possible performance improvement is worth. Opinions?

                    VsHelper.CheckoutItem(_project.DTE, configurationSectionModelFile);
                }

                #region new

                // Get names of all of the existing files under CSD.
                foreach (ProjectItem childItem in configurationSectionModelFile.ProjectItems)
                {
                    _oldFileNames.Add(childItem.Name);
                }
                #endregion

                // now we can start our work, iterate across all the 'elements' in our source file.
                // Each of these items is a file extension.
                foreach (TIterativeElement item in this)
                {
                    // This try catch only exists for debugging purposes.
                    try
                    {
                        // obtain a name for this target file
                        string fileName = GetFileName(item);
                        Diagnostics.DebugWrite("VSMFG.Generate >> Filename for current element in loop is '{0}'", fileName);

                        // add it to the tracking cache
                        _newFileNames.Add(fileName);

                        // fully qualify the file on the filesystem
                        //string strFile = Path.Combine(wszInputFilePath.Substring(0, wszInputFilePath.LastIndexOf(Path.DirectorySeparatorChar)), fileName);
                        string strFile = Path.Combine(Path.GetDirectoryName(wszInputFilePath), fileName);

                        bool isNewAdded = !_oldFileNames.Contains(fileName);

                        /*
                         * if (!isNewAdded)
                         * {
                         *  if (_project.DTE.SourceControl.IsItemUnderSCC(strFile) && !_project.DTE.SourceControl.IsItemCheckedOut(strFile))
                         *  {
                         *      Diagnostics.DebugWrite("VSMFG.Generate >> Checking file out from source control '{0}'", fileName);
                         *      _project.DTE.SourceControl.CheckOutItem(strFile);
                         *  }
                         * }*/

                        // create the file
                        FileStream fs = null;

                        try
                        {
                            // generate our target file content
                            byte[] data = GenerateContent(item); // NOTE: For .diagram and .cs, this will be null, so those will not be written.

                            // if data is null, it means to ignore the contents of the generated file (no write to file).
                            if (data == null)
                            {
                                continue;
                            }

                            fs = File.Create(strFile);

                            #region Replaced code: Remove later.

                            /*if (!isNewAdded)
                             * {
                             *  // If the (xsd or config) file already exists, only save the data if the generated file is different than the existing file.
                             *  if (!Util.IsDataEqual(File.ReadAllBytes(strFile), data))
                             *  {
                             *      // Check out this file.
                             *      if (_project.DTE.SourceControl.IsItemUnderSCC(strFile) &&
                             *          !_project.DTE.SourceControl.IsItemCheckedOut(strFile))
                             *      {
                             *          Diagnostics.DebugWrite("VSMFG.Generate >> Checking file out from source control '{0}'", fileName);
                             *          _project.DTE.SourceControl.CheckOutItem(strFile);
                             *      }
                             *
                             *      Diagnostics.DebugWrite("VSMFG.Generate >> File data has changed for file '{0}'. Re-using existing file...", strFile);
                             *      fs = File.Open(strFile, FileMode.Truncate);
                             *  }
                             * }
                             * else
                             * {
                             *  // create the file
                             *  fs = File.Create(strFile);
                             * }*/

                            //if (fs != null) // We only write if file is modified or new.
                            //{

                            #endregion

                            VsOutputWindowPaneManager.OutputWindowWrite(vsOutputWindowPaneName, "* Generating the " + item + " file...");

                            // write it out to the stream
                            fs.Write(data, 0, data.Length);
                            fs.Close();
                            OnFileGenerated(strFile, isNewAdded);

                            // add the newly generated file to the solution, as a child of the source file
                            //if (!configurationSectionModelFile.ProjectItems.Cast<ProjectItem>().Any(pi => pi.Name == fileName))
                            if (isNewAdded)
                            {
                                ProjectItem itm = configurationSectionModelFile.ProjectItems.AddFromFile(strFile);

                                /*
                                 * Here you may wish to perform some addition logic such as, setting a custom tool for the target file if it
                                 * is intented to perform its own generation process.
                                 * Or, set the target file as an 'Embedded Resource' so that it is embedded into the final Assembly.
                                 *
                                 * EnvDTE.Property prop = itm.Properties.Item("CustomTool");
                                 * //// set to embedded resource
                                 * itm.Properties.Item("BuildAction").Value = 3;
                                 * if (String.IsNullOrEmpty((string)prop.Value) || !String.Equals((string)prop.Value, typeof(AnotherCustomTool).Name))
                                 * {
                                 *  prop.Value = typeof(AnotherCustomTool).Name;
                                 * }
                                 */
                            }
                            //}
                        }
                        catch (Exception e)
                        {
                            //GeneratorProgress.GeneratorError( false, 0, string.Format( "{0}\n{1}", e.Message, e.StackTrace ), -1, -1 );
                            //GeneratorProgress.GeneratorError(0, 0, string.Format("{0}\n{1}", e.Message, e.StackTrace), 0, 0);

                            if (File.Exists(strFile))
                            {
                                // TODO: ABM - Should we write this error to the file (breaking the build), or just show error and keep old file?
                                File.WriteAllText(strFile, "An exception occured while running the CsdFileGenerator on this file. See the Error List for details. E=" + e);
                            }
                            throw;
                        }
                        finally
                        {
                            if (fs != null)
                            {
                                fs.Close();
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        // This is here for debugging purposes, as setting a breakpoint here can be very helpful
                        Diagnostics.DebugWrite("VSMFG.Generate >> EXCEPTION: {0}", ex);
                        throw;
                    }
                }

                // perform some clean-up, making sure we delete any old (stale) target-files
                VsOutputWindowPaneManager.OutputWindowWrite(vsOutputWindowPaneName, "* Cleaning up existing files... ");
                foreach (ProjectItem childItem in configurationSectionModelFile.ProjectItems)
                {
                    string next;
                    DefaultExtension(out next);

                    if (!(childItem.Name.EndsWith(next) || _newFileNames.Contains(childItem.Name)))
                    {
                        // then delete it
                        childItem.Delete();
                    }
                }
                VsOutputWindowPaneManager.OutputWindowWriteLine(vsOutputWindowPaneName, "complete!");

                VsOutputWindowPaneManager.OutputWindowWrite(vsOutputWindowPaneName, "* Generating the class file... ");

                // generate our default content for our 'single' file
                byte[] defaultData = null;
                try
                {
                    // This will call GenerateAllContent(string.Format("{0}-gen", [cs or vb]));
                    defaultData = GenerateDefaultContent();
                }
                catch (Exception ex)
                {
                    Diagnostics.DebugWrite("VSMFG.Generate >> EXCEPTION: {0}", ex);
                    throw;
                    //GeneratorProgress.GeneratorError( false, 0, string.Format( "{0}\n{1}", ex.Message, ex.StackTrace ), -1, -1 );
                    //GeneratorProgress.GeneratorError(0, 0, string.Format("{0}\n{1}", ex.Message, ex.StackTrace), 0, 0);
                }
                VsOutputWindowPaneManager.OutputWindowWriteLine(vsOutputWindowPaneName, "complete!");

                if (defaultData == null)
                {
                    defaultData = new byte[0];
                }
                // return our default data (code behind file), so that Visual Studio may write it to disk.

                /*
                 * You need to write the bytes of the generated file into this variable. However, you cannot
                 * do it directly (hence the IntPtr[] type) – instead, you must use the System.Runtime.InteropServices.AllocCoTaskMem
                 * allocator to create the memory and write type bytes in there.
                 */
                rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(defaultData.Length);

                Marshal.Copy(defaultData, 0, rgbOutputFileContents[0], defaultData.Length);

                // must be set to the number of bytes that we wrote to rgbOutputFileContents.
                pcbOutput = (uint)defaultData.Length;

                //string codefileName = GetFileName(CodeFileExtension);
                //OnFileGenerated(codefileName, isNewAdded);

                VsOutputWindowPaneManager.OutputWindowWriteLine(vsOutputWindowPaneName, "========== CSD file generation: complete! ==========");
            }
            catch (Exception ex)
            {
                // Currently, all exceptions are rethrown to be caught here.
                OnError(ex);

                LogException(ex);

                rgbOutputFileContents[0] = IntPtr.Zero;
                pcbOutput = 0;
            }

            return(0);
        }
Example #39
0
        public int Generate(string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace, IntPtr[] rgbOutputFileContents, out uint pcbOutput, IVsGeneratorProgress pGenerateProgress)
        {
            try
            {
                var csc = Directory.GetFiles(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "Microsoft.NET\\Framework"), "csc.exe", SearchOption.AllDirectories)
                          .Select(x => new { Path = x, Version = new Version(Path.GetFileName(Path.GetDirectoryName(x)).Substring(1)) })
                          .MaxVersion(x => x.Version);

                if (csc == null)
                {
                    pcbOutput = 0;
                    return(VSConstants.S_FALSE);
                }

                var code =
                    "using Cauldron.Interception.Cecilator;          " +
                    "using Cauldron.Interception.Fody;               " +
                    "using Cauldron.Interception.Fody.HelperTypes;   " +
                    "using System.Collections;                       " +
                    "using System.Collections.Generic;               " +
                    "using System.ComponentModel;                    " +
                    "using System.Diagnostics;                       " +
                    "using System.Collections.Concurrent;            " +
                    "using System;                                   " +
                    "using System.IO                                 " +
                    "using System.Threading.Tasks;                   " +
                    "using System.Linq;                              " +
                    "using Reflection = System.Reflection;           " +
                    "using System.Runtime.CompilerServices;          " +
                    "using System.Runtime.InteropServices;           " +
                    "using Mono.Cecil;                               " +
                    "public sealed class Interceptor { " +
                    bstrInputFileContents +
                    "}";

                var tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
                var tempCode      = Path.Combine(tempDirectory, Path.GetFileNameWithoutExtension(wszInputFilePath) + ".cs");
                var output        = Path.Combine(tempDirectory, Path.GetFileNameWithoutExtension(wszInputFilePath) + ".dll");
                Directory.CreateDirectory(tempDirectory);
                File.WriteAllText(tempCode, code);

                var references = new List <string>();
                var toolsPath  = Path.Combine(this.solutionPath, "Tools\\Cauldron.Interception.Fody.99.9.9");

                if (Directory.Exists(toolsPath))
                {
                    references.Add(Path.Combine(toolsPath, "Mono.Cecil.dll"));
                    references.Add(Path.Combine(toolsPath, "Cauldron.Interception.Fody.dll"));
                    references.Add(Path.Combine(toolsPath, "Cauldron.Interception.Cecilator.dll"));
                }
                else
                {
                    var packages             = Path.Combine(this.solutionPath, "packages");
                    var cauldronInterception = GetFolderWithHighestVersion(packages, "Cauldron.Interception.Fody");

                    references.Add(Path.Combine(cauldronInterception, "Mono.Cecil.dll"));
                    references.Add(Path.Combine(cauldronInterception, "Cauldron.Interception.Fody.dll"));
                    references.Add(Path.Combine(cauldronInterception, "Cauldron.Interception.Cecilator.dll"));
                }

                var processStartInfo = new ProcessStartInfo
                {
                    FileName               = csc.Path,
                    Arguments              = $"/t:library /out:\"{output}\" /optimize+  \"{tempCode}\" /r:{string.Join(",", references.Select(x => "\"" + x + "\""))}",
                    CreateNoWindow         = true,
                    UseShellExecute        = false,
                    WindowStyle            = ProcessWindowStyle.Hidden,
                    WorkingDirectory       = tempDirectory,
                    RedirectStandardOutput = true,
                    RedirectStandardError  = true
                };

                var process = new System.Diagnostics.Process
                {
                    StartInfo = processStartInfo
                };

                this.windowPane.OutputString(processStartInfo.FileName + "\r\n");
                this.windowPane.OutputString(processStartInfo.Arguments + "\r\n\r\n");

                process.OutputDataReceived += (s, e) => { this.windowPane.OutputString("\r\n" + e.Data); };
                process.ErrorDataReceived  += (s, e) => { this.windowPane.OutputString("\r\n" + e.Data); };

                process.Start();
                process.BeginOutputReadLine();
                process.BeginErrorReadLine();
                process.WaitForExit();

                var content = File.ReadAllBytes(output);
                pcbOutput = (uint)content.Length;
                rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(content.Length);
                Marshal.Copy(content, 0, rgbOutputFileContents[0], content.Length);

                Directory.Delete(tempDirectory, true);

                return(VSConstants.S_OK);
            }
            catch (Exception)
            {
                pcbOutput = 0;
                return(VSConstants.S_FALSE);
            }
        }
Example #40
0
 protected override byte[] Generate(string inputFilePath, string inputFileContents, string defaultNamespace, IVsGeneratorProgress progressCallback)
 {
     using (LNode.SetPrinter(EcsLanguageService.WithPlainCSharpPrinter))
         return(base.Generate(inputFilePath, inputFileContents, defaultNamespace, progressCallback));
 }
        /// <summary>
        /// Implements the IVsSingleFileGenerator.Generate method.
        /// Executes the transformation and returns the newly generated output file, whenever a custom tool is loaded, or the input file is saved
        /// </summary>
        /// <param name="wszInputFilePath">The full path of the input file. May be a null reference (Nothing in Visual Basic) in future releases of Visual Studio, so generators should not rely on this value</param>
        /// <param name="bstrInputFileContents">The contents of the input file. This is either a UNICODE BSTR (if the input file is text) or a binary BSTR (if the input file is binary). If the input file is a text file, the project system automatically converts the BSTR to UNICODE</param>
        /// <param name="wszDefaultNamespace">This parameter is meaningful only for custom tools that generate code. It represents the namespace into which the generated code will be placed. If the parameter is not a null reference (Nothing in Visual Basic) and not empty, the custom tool can use the following syntax to enclose the generated code</param>
        /// <param name="rgbOutputFileContents">[out] Returns an array of bytes to be written to the generated file. You must include UNICODE or UTF-8 signature bytes in the returned byte array, as this is a raw stream. The memory for rgbOutputFileContents must be allocated using the .NET Framework call, System.Runtime.InteropServices.AllocCoTaskMem, or the equivalent Win32 system call, CoTaskMemAlloc. The project system is responsible for freeing this memory</param>
        /// <param name="pcbOutput">[out] Returns the count of bytes in the rgbOutputFileContent array</param>
        /// <param name="pGenerateProgress">A reference to the IVsGeneratorProgress interface through which the generator can report its progress to the project system</param>
        /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns E_FAIL</returns>
        int IVsSingleFileGenerator.Generate(string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace, IntPtr[] rgbOutputFileContents, out uint pcbOutput, IVsGeneratorProgress pGenerateProgress)
        {
            if (bstrInputFileContents == null)
            {
                throw new ArgumentNullException(bstrInputFileContents);
            }

            if (wszInputFilePath == null)
            {
                throw new ArgumentNullException(bstrInputFileContents);
            }

            string InputFilePath = wszInputFilePath;
            string FileNameSpace = wszDefaultNamespace;

            try
            {
                var inputPath = Path.GetDirectoryName(InputFilePath);

                var resultCodeProcessor = new ResultCodeProcessor();
                resultCodeProcessor.LoadFacility(Path.Combine(inputPath, "ResultFacility.xml"));

                //var exporterXml = new ResultCodeExporterXml();
                using (var inputStream = new MemoryStream(Encoding.UTF8.GetBytes(bstrInputFileContents)))
                {
                    resultCodeProcessor.LoadCodes(inputStream);
                }

                resultCodeProcessor.UpdateResultCode();

                var memoryStream = new MemoryStream();
                resultCodeProcessor.GenerateSharp(memoryStream);
                if (memoryStream.Length == 0)
                {
                    rgbOutputFileContents = null;
                    pcbOutput             = 0;

                    return(VSConstants.E_FAIL);
                }
                else
                {
                    int outputLength = (int)memoryStream.Length;
                    rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(outputLength);
                    Marshal.Copy(memoryStream.GetBuffer(), 0, rgbOutputFileContents[0], outputLength);
                    pcbOutput = (uint)outputLength;
                    return(VSConstants.S_OK);
                }
            }
            catch (Exception)
            {
                rgbOutputFileContents = null;
                pcbOutput             = 0;
                return(VSConstants.E_FAIL);
            }
        }
Example #42
0
        protected override byte[] Generate(string inputFilePath, string inputFileContents, string defaultNamespace, IVsGeneratorProgress progressCallback)
        {
            string oldCurDir = Environment.CurrentDirectory;

            try {
                string inputFolder = Path.GetDirectoryName(inputFilePath);
                Environment.CurrentDirectory = inputFolder;                 // --macros should be relative to file being processed

                // Originally I wrote a conversion from IVsGeneratorProgress to
                // IMessageSink so that errors could be reported immediately and
                // directly to Visual Studio. This broke in a bizarre way when I
                // added processing on a separate thread (in order to be able to
                // abort the thread if it runs too long); I got the following
                // InvalidCastException: "Unable to cast COM object of type 'System.__ComObject'
                // to interface type 'Microsoft.VisualStudio.Shell.Interop.IVsGeneratorProgress'.
                // This operation failed because the QueryInterface call on the COM component for
                // the interface with IID '{BED89B98-6EC9-43CB-B0A8-41D6E2D6669D}' failed due to
                // the following error: No such interface supported (Exception from HRESULT:
                // 0x80004002 (E_NOINTERFACE))."
                //
                // A simple solution is to store the messages rather than reporting
                // them immediately. I'll report the errors at the very end.
                MessageHolder sink = new MessageHolder();

                var sourceFile = new InputOutput((UString)inputFileContents, inputFilePath);

                Compiler.KnownOptions["no-out-header"] = Pair.Create("", "Remove explanatory comment from output file");
                Compiler.KnownOptions.Remove("parallel");                   // not applicable to single file
                Compiler.KnownOptions.Remove("noparallel");                 // not applicable to single file

                var c = new Compiler(sink, sourceFile)
                {
                    AbortTimeout = TimeSpan.FromSeconds(10),
                    Parallel     = false                 // only one file, parallel doesn't help
                };

                var argList = G.SplitCommandLineArguments(defaultNamespace);
                var options = c.ProcessArguments(argList, true, false);
                // Note: if default namespace is left blank, VS uses the namespace
                // from project settings. Don't show an error in that case.
                if (argList.Count > 1 || (argList.Count == 1 && options.Count > 0))
                {
                    sink.Write(Severity.Error, "Command line", "'{0}': expected options only (try --help).", argList[0]);
                }

                string _;
                if (options.TryGetValue("help", out _) || options.TryGetValue("?", out _))
                {
                    var ms = new MemoryStream();
                    LeMP.Compiler.ShowHelp(LeMP.Compiler.KnownOptions, new StreamWriter(ms), false);
                    return(ms.GetBuffer());
                }

                LeMP.Compiler.WarnAboutUnknownOptions(options, sink, LeMP.Compiler.KnownOptions);

                if (options.ContainsKey("no-out-header"))
                {
                    c.NoOutHeader = true;
                }

                if (c.InLang == LesLanguageService.Value || inputFilePath.EndsWith(".les", StringComparison.OrdinalIgnoreCase))
                {
                    c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP.Prelude.Les"));
                }

                Configure(c);
                _requestedExtension = c.OutExt;

                // Help user code send messages to error list via MessageSink.Default.
                // `compileTime` already uses `using` to change the default sink to the
                // macro context, but this doesn't work in macros or events because they
                // execute after the `compileTime` or `macro` block has ended.
                using (MessageSink.SetDefault(sink))
                    c.Run();

                // Report errors
                foreach (var msg in sink.List)
                {
                    ReportErrorToVS(progressCallback, msg.Severity, msg.Context, msg.Format, msg.Args);
                }

                return(Encoding.UTF8.GetBytes(c.Output.ToString()));
            } finally {
                Environment.CurrentDirectory = oldCurDir;
            }
        }
 int IVsSingleFileGenerator.Generate(string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace, IntPtr[] rgbOutputFileContents, out uint pcbOutput, IVsGeneratorProgress pGenerateProgress)
 {
     if (bstrInputFileContents == null)
     {
         throw new ArgumentNullException("bstrInputFileContents");
     }
     return(Generate(wszInputFilePath, bstrInputFileContents, wszDefaultNamespace, rgbOutputFileContents, out pcbOutput, pGenerateProgress));
 }
 protected abstract int Generate(string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace, IntPtr[] rgbOutputFileContents, out uint pcbOutput, IVsGeneratorProgress pGenerateProgress);