private void GenerateOutput(object sender, GenerationEventArgs e) { string jar = GetInstallPath(@"smc\Smc.jar"); if (!File.Exists(jar)) { e.GenerateError("Missing intalled file: " + jar); return; } string tempFile = Path.GetTempFileName(); string tempDir = null; try { tempDir = Directory.CreateDirectory(tempFile + "_dir").FullName; GenerateSourceCode(jar, e, tempDir); DeleteAllFiles(e, tempDir); GenerateGraphFile(jar, e, tempDir); DeleteAllFiles(e, tempDir); //AddProjectItems(e, inputDir, names); EnsureDllIsInProject(e); } finally { if (tempDir != null) { DeleteAllFiles(e, tempDir); DeleteDir(tempDir, e); } DeleteFile(tempFile, e); } }
private List <string> CreateArgs(GenerationEventArgs e, Regex regex, params string[] defaults) { var lines = e.InputText.Split('\n'); for (var i = 0; i < lines.Length; i++) { var line = lines[i].Trim(); if (line.Length == 0) { continue; } if (!line.StartsWith("//")) { break; } var comment = line.Substring(2); var match = regex.Match(comment); if (!match.Success) { continue; } var args = new List <string>(); foreach (var capture in match.Groups["arg"].Captures) { args.Add(capture.ToString().Trim()); } return(args); } return(defaults.ToList()); }
private void GenerateGraphFile(string jar, GenerationEventArgs e, string tempDir) { const string graphvizCommandLine = "dot"; if (!ExistsOnPath(graphvizCommandLine)) { return; } string inputDir = new FileInfo(e.InputFilePath).DirectoryName; // Generate dot file List <string> args = CreateArgs(e, GraphCommandLineRe, "-graph", "-glevel", "0"); args.Insert(0, "-jar"); args.Insert(1, jar); args.Add("-d"); args.Add(tempDir); args.Add(e.InputFilePath); ProcessResult proc = Execute(tempDir, "java", args.ToArray()); if (ProcessErrors(e, proc, e.InputFilePath)) { return; } string dotFilename = GetGeneratedFileName(e, tempDir, "*.dot"); if (dotFilename == null) { return; } // Generate image using dot args = CreateArgs(e, DotCommandLineRe, "-Tsvg"); string imageExtension = (from a in args where a.StartsWith("-T") select a.Substring(2)).FirstOrDefault(); if (imageExtension == null) { e.GenerateError("Missing -T argument for dot"); return; } string imageFilename = Path.GetFileNameWithoutExtension(dotFilename) + "." + imageExtension; string imageFullPath = Path.Combine(inputDir, imageFilename); DeleteFile(imageFullPath, e); args.Add(Path.Combine(tempDir, dotFilename)); args.Add("-o"); args.Add(imageFullPath); Execute(tempDir, graphvizCommandLine, args.ToArray()); // Copy dot to input dir File.WriteAllText(Path.Combine(inputDir, dotFilename), File.ReadAllText(Path.Combine(tempDir, dotFilename))); // Add files to solution var toAdd = new HashSet <string>(); toAdd.Add(dotFilename); if (File.Exists(imageFullPath)) { toAdd.Add(imageFilename); } AddProjectItems(e, inputDir, toAdd); }
private void GenerateCode(object sender, GenerationEventArgs e) { e.OutputFileExtension = ".dot"; string templatesDir = GetInstallPath("templates"); if (!Directory.Exists(templatesDir)) { e.GenerateError("Missing templates from install: " + templatesDir); return; } string libDll = GetInstallPath(GetInstallPath(@"lib\ModelSharp.Lib.dll")); if (!Directory.Exists(templatesDir)) { e.GenerateError("Missing dll from install: " + libDll); return; } string tempFile = Path.GetTempFileName(); string tempDir = null; try { tempDir = Directory.CreateDirectory(tempFile + "_dir").FullName; var modelProcessor = new ModelProcessor(templatesDir, e.InputFilePath, true); modelProcessor.BaseOutputPath = tempDir; modelProcessor.GlobalConfig.ProjectNamespace = e.Namespace; var result = modelProcessor.Process(); // Output to console // foreach (var msg in result.Messages) // { // string txt; // if (msg.Line > 0) // txt = String.Format("[{0}] [{1:0000} : {2:000}] {3}", // msg.Error ? "ERROR" : "INFO ", msg.Line, msg.Column, // msg.Description); // else // txt = String.Format("[{0}] {1}", msg.Error ? "ERROR" : "INFO ", msg.Description); // // Console.WriteLine(txt); // } if (!result.Success) { e.GenerateError("Error generating model"); foreach (var msg in result.Messages) { if (msg.Error) { if (msg.Line > 0) e.GenerateError(msg.Description, msg.Line - 1, msg.Column); else e.GenerateError(msg.Description); } } return; } //string filename = Path.Combine(tempDir, names.First()); //foreach (var line in File.ReadLines(filename)) //{ // e.OutputCode.AppendLine(line); //} string inputDir = new FileInfo(e.InputFilePath).DirectoryName; MergeFiles(result.NotToChangeFilenames, tempDir, inputDir, false); MergeFiles(result.EditableFilenames, tempDir, inputDir, true); SetSubItems(e, inputDir, result.NotToChangeFilenames); AddToProject(e, inputDir, result.EditableFilenames); EnsureDllIsInProject(e, libDll); } finally { if (tempDir != null) { foreach (var file in Directory.GetFiles(tempDir)) { if (file == "." || file == "..") continue; DeleteFile(Path.Combine(tempDir, file), e); } DeleteDir(tempDir, e); } DeleteFile(tempFile, e); } }
private void AddAssemblyDependency(GenerationEventArgs e, VSProject project, Assembly assembly) { AddAssemblyDependency(e, project, assembly.GetName().Name, assembly.Location, false); }
private void AddAssemblyDependency(GenerationEventArgs e, VSProject project, string assemblyName, string assemblyLocation, bool copyLocal) { try { bool hasRef = project.References.Cast<Reference>().Any( r => r != null && string.Equals(r.Name, assemblyName, StringComparison.InvariantCultureIgnoreCase)); if (!hasRef) { Reference dllRef = project.References.Add(assemblyLocation); dllRef.CopyLocal = copyLocal; } } catch (Exception ex) { e.GenerateWarning("Failed to add reference to " + assemblyName + ":" + ex.Message); } }
private void DeleteFile(string filename, GenerationEventArgs e) { try { File.Delete(filename); } catch (Exception ex) { e.GenerateWarning(ex.Message); } }
private void EnsureDllIsInProject(GenerationEventArgs e, string libDll) { var project = (VSProject) e.ProjectItem.ContainingProject.Object; AddAssemblyDependency(e, project, Assembly.GetAssembly(typeof (DataContractAttribute))); AddAssemblyDependency(e, project, Assembly.GetAssembly(typeof (INotifyCollectionChanged))); AddAssemblyDependency(e, project, "ModelSharp.Lib", libDll, true); }
private void DeleteDir(string dir, GenerationEventArgs e) { try { Directory.Delete(dir, true); } catch (Exception ex) { e.GenerateWarning(ex.Message); } }
private void AddToProject(GenerationEventArgs e, string dir, List<string> names) { var proj = e.ProjectItem.ContainingProject; foreach (var name in names) { AddFromFileWithFolders(proj.ProjectItems, name, dir); } }
private void SetSubItems(GenerationEventArgs e, string dir, IEnumerable<string> relativeNames) { HashSet<string> filenames = new HashSet<string>(); foreach (var name in relativeNames) filenames.Add(name.Split('\\').Last()); HashSet<string> existingNames = new HashSet<string>(); foreach (ProjectItem item in e.ProjectItem.ProjectItems) { if (!filenames.Contains(item.Name) && !item.Name.EndsWith(".dot")) item.Delete(); else existingNames.Add(item.FileNames[0]); } foreach (var name in filenames) { if (existingNames.Contains(name)) continue; e.ProjectItem.ProjectItems.AddFromFile(Path.Combine(dir, name)); } }
/// <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, ProjectItemProvider(Site as Microsoft.VisualStudio.OLE.Interop.IServiceProvider)); if (OnGenerateCode != null) { OnGenerateCode(this, gea); } if (gea.OutputFileExtension.StartsWith(".")) { this.FileExtension = gea.OutputFileExtension; } else { this.FileExtension = "." + gea.OutputFileExtension; } GenerationProgressFacade progressFacade = ProgressFacadeProvider(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 (OnCompletedGeneration != null) { OnCompletedGeneration(this, new CompletedGenerationEventArgs( gea.OutputCode.ToString(), gea.ProjectItem)); } if (gea.FailOnError && gea.Errors.Count > 0) { return(VSConstants.E_FAIL); } else { return(VSConstants.S_OK); } }
/// <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, ProjectItemProvider(Site as Microsoft.VisualStudio.OLE.Interop.IServiceProvider)); if (OnGenerateCode != null) { OnGenerateCode(this, gea); } if (gea.OutputFileExtension.StartsWith(".")) { this.FileExtension = gea.OutputFileExtension; } else { this.FileExtension = "." + gea.OutputFileExtension; } GenerationProgressFacade progressFacade = ProgressFacadeProvider(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 (OnCompletedGeneration != null) { OnCompletedGeneration(this, new CompletedGenerationEventArgs( gea.OutputCode.ToString(), gea.ProjectItem)); } if (gea.FailOnError && gea.Errors.Count > 0) { return VSConstants.E_FAIL; } else { return VSConstants.S_OK; } }