コード例 #1
0
        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);
            }
        }
コード例 #2
0
        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());
        }
コード例 #3
0
        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);
        }
コード例 #4
0
ファイル: ModelSharpTool.cs プロジェクト: pescuma/modelsharp
		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);
			}
		}
コード例 #5
0
ファイル: ModelSharpTool.cs プロジェクト: pescuma/modelsharp
		private void AddAssemblyDependency(GenerationEventArgs e, VSProject project, Assembly assembly)
		{
			AddAssemblyDependency(e, project, assembly.GetName().Name, assembly.Location, false);
		}
コード例 #6
0
ファイル: ModelSharpTool.cs プロジェクト: pescuma/modelsharp
		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);
			}
		}
コード例 #7
0
ファイル: ModelSharpTool.cs プロジェクト: pescuma/modelsharp
		private void DeleteFile(string filename, GenerationEventArgs e)
		{
			try
			{
				File.Delete(filename);
			}
			catch (Exception ex)
			{
				e.GenerateWarning(ex.Message);
			}
		}
コード例 #8
0
ファイル: ModelSharpTool.cs プロジェクト: pescuma/modelsharp
		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);
		}
コード例 #9
0
ファイル: ModelSharpTool.cs プロジェクト: pescuma/modelsharp
		private void DeleteDir(string dir, GenerationEventArgs e)
		{
			try
			{
				Directory.Delete(dir, true);
			}
			catch (Exception ex)
			{
				e.GenerateWarning(ex.Message);
			}
		}
コード例 #10
0
ファイル: ModelSharpTool.cs プロジェクト: pescuma/modelsharp
		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);
			}
		}
コード例 #11
0
ファイル: ModelSharpTool.cs プロジェクト: pescuma/modelsharp
		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));
			}
		}
コード例 #12
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,
                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);
            }
        }
コード例 #13
0
ファイル: CustomToolBase.cs プロジェクト: pescuma/modelsharp
        /// <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;
            }
        }