/// ------------------------------------------------------------------------------------ /// <summary> /// Do the actual import /// </summary> /// <param name="usingNamespaces">Additional imported namespaces</param> /// <param name="sFileName">Filename of the IDL file</param> /// <param name="sXmlFile">Name of the XML config file</param> /// <param name="sOutFile">Output</param> /// <param name="sNamespace">Namespace</param> /// <param name="idhFiles">Names of IDH file used to retrieve comments.</param> /// <param name="referencedFiles">Names of files used to resolve references to /// external types.</param> /// <param name="fCreateComments"><c>true</c> to create XML comments</param> /// <returns><c>true</c> if import successful, otherwise <c>false</c>.</returns> /// ------------------------------------------------------------------------------------ public bool Import(List <string> usingNamespaces, string sFileName, string sXmlFile, string sOutFile, string sNamespace, StringCollection idhFiles, StringCollection referencedFiles, bool fCreateComments) { var fOk = true; var codeNamespace = new CodeNamespace(); // Add additional using statements foreach (var ns in usingNamespaces) { codeNamespace.Imports.Add(new CodeNamespaceImport(ns)); } // Add types from referenced files so that we can resolve types that are not // defined in this IDL file. foreach (var refFile in referencedFiles) { var referencedNamespace = DeserializeData(refFile); if (referencedNamespace == null) { continue; } foreach (string key in referencedNamespace.UserData.Keys) { codeNamespace.UserData[key] = referencedNamespace.UserData[key]; } } // Load the IDL conversion rules if (sXmlFile == null) { var assembly = Assembly.GetExecutingAssembly(); sXmlFile = Path.ChangeExtension(assembly.Location, "xml"); } var conversions = IDLConversions.Deserialize(sXmlFile); conversions.Namespace = codeNamespace; #if SINGLE_THREADED ParseIdhFiles(idhFiles); #else _waitHandle = new EventWaitHandle(false, EventResetMode.AutoReset); ThreadPool.QueueUserWorkItem(ParseIdhFiles, idhFiles); #endif using (var stream = new FileStream(sFileName, FileMode.Open, FileAccess.Read)) { var lexer = new IDLLexer(stream); var parser = new IDLParser(lexer); parser.setFilename(sFileName); codeNamespace.Name = sNamespace; codeNamespace.Comments.AddRange(AddFileBanner(sFileName, sOutFile)); codeNamespace.Imports.Add(new CodeNamespaceImport("System")); codeNamespace.Imports.Add(new CodeNamespaceImport("System.Runtime.InteropServices")); codeNamespace.Imports.Add(new CodeNamespaceImport("System.Runtime.InteropServices.ComTypes")); codeNamespace.Imports.Add(new CodeNamespaceImport("System.Runtime.CompilerServices")); // And now parse the IDL file parser.specification(codeNamespace, conversions); // Merge properties fOk = MergeProperties(codeNamespace); IDLConversions.AdjustReferencesInEnums(); // Add XML comments if (fCreateComments) { _waitHandle?.WaitOne(); AddComments(codeNamespace.Types); } // Serialize what we have so that we can re-use later if necessary SerializeData(sFileName, codeNamespace); // Finally, create the source code GenerateCode(sOutFile, codeNamespace); } return(fOk); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Clean up the comments. /// </summary> /// ------------------------------------------------------------------------------------ public void CleanupComment() { if (!m_fClean) { m_commentBldr.Replace("&", "&"); m_commentBldr.Replace("<", "<"); m_commentBldr.Replace(">", ">"); } m_fClean = true; ConvertSurveyorTag(@"@null\{(?<content>[^}]*)\}", ""); // no output ConvertSurveyorTag(@"/\*:Ignore ([^/*:]|/|\*|:)+/\*:End Ignore\*/", ""); // no output ConvertSurveyorTag(@"//:>([^\n]+)\n", ""); // no output ConvertSurveyorTag(@"@h3\{Hungarian: (?<content>[^}]*)\}", "Hungarian: <c>{0}</c>"); ConvertSurveyorTag(@"@h3\{(?<content>[^}]*)\}", "<h3>{0}</h3>"); ConvertSurveyorTag(@"@b\{(?<content>[^}]*)\}", "<b>{0}</b>"); ConvertSurveyorTag(@"@i\{(?<content>[^}]*)\}", "<i>{0}</i>"); ConvertSurveyorTag(@"@code\{(?<content>[^}]*)\}", "<code>{0}</code>"); ConvertSurveyorTag(@"@return (?<content>[^\n]+\n)", "{0}"); //ConvertSurveyorTag(@"@HTTP\{(?<content>[^}]*)\}", @"<see href=""{0}"">{0}</see>"); // Remove //--- and /*********** lines Regex line = new Regex(@"(\r\n)?(/\*|//)?(-|\*)+(\r\n|/)?"); if (line.IsMatch(m_commentBldr.ToString())) { MatchCollection matches = line.Matches(m_commentBldr.ToString()); for (int i = matches.Count; i > 0; i--) { Match match = matches[i - 1]; m_commentBldr.Remove(match.Index, match.Length); } } Regex param = new Regex(@"@param (?<name>(\w|/)+) (?<comment>([^@]|@i|@b)*)"); if (param.IsMatch(m_commentBldr.ToString())) { MatchCollection matches = param.Matches(m_commentBldr.ToString()); for (int i = matches.Count; i > 0; i--) { Match match = matches[i - 1]; m_commentBldr.Remove(match.Index, match.Length); string paramName = IDLConversions.ConvertParamName(match.Groups["name"].Value); if (!Children.ContainsKey(paramName)) { Console.WriteLine("Parameter mentioned in @param doesn't exist: {0}", match.Groups["name"].Value); continue; } StringBuilder bldr = Children[paramName] .m_commentBldr; bldr.Length = 0; bldr.Append(match.Groups["comment"].Value); Children[paramName].m_fClean = true; } } Regex exception = new Regex(@"@exception (?<hresult>\w+) (?<comment>([^@]|@i|@b)*)"); if (exception.IsMatch(m_commentBldr.ToString())) { MatchCollection matches = exception.Matches(m_commentBldr.ToString()); for (int i = matches.Count; i > 0; i--) { Match match = matches[i - 1]; m_commentBldr.Remove(match.Index, match.Length); string exceptionType = TranslateHResultToException(match.Groups["hresult"].Value); if (Attributes.ContainsKey("exception")) { Attributes["exception"] = Attributes["exception"] + "," + exceptionType; } else { Attributes.Add("exception", exceptionType); } Attributes.Add(exceptionType, string.Format("{0} ({1})", match.Groups["comment"].Value.Replace("//", "").TrimEnd('\n', '\r', ' '), match.Groups["hresult"].Value)); } } Regex list = new Regex(@"@list\{(?<content>[^}]*)\}"); if (list.IsMatch(m_commentBldr.ToString())) { MatchCollection matches = list.Matches(m_commentBldr.ToString()); for (int i = matches.Count; i > 0; i--) { Match match = matches[i - 1]; m_commentBldr.Remove(match.Index, match.Length); if (i == matches.Count) { m_commentBldr.Insert(match.Index, string.Format(" {0}</list>", Environment.NewLine)); } m_commentBldr.Insert(match.Index, string.Format("<item><description>{0} {1}{0} </description></item>", Environment.NewLine, match.Groups["content"].Value)); if (i == 1) { m_commentBldr.Insert(match.Index, string.Format(@"<list type=""bullet"">{0} ", Environment.NewLine)); } } } if (m_commentBldr.Length > 0) { using (StringReader reader = new StringReader(m_commentBldr.ToString())) { StringBuilder bldr = new StringBuilder(); SurveyorLexer lexer = new SurveyorLexer(bldr, reader); lexer.setLine(LineNumber); SurveyorParser parser = new SurveyorParser(bldr, lexer); parser.surveyorTags(); m_commentBldr = bldr; } } // Do this at the end because we might need it above to determine the end of the other tags ConvertSurveyorTag(@"@end", ""); // no output }
/// ------------------------------------------------------------------------------------ /// <summary> /// Do the actual import /// </summary> /// <param name="usingNamespaces">Additional imported namespaces</param> /// <param name="sFileName">Filename of the IDL file</param> /// <param name="sXmlFile">Name of the XML config file</param> /// <param name="sOutFile">Output</param> /// <param name="sNamespace">Namespace</param> /// <param name="idhFiles">Names of IDH file used to retrieve comments.</param> /// <param name="referencedFiles">Names of files used to resolve references to /// external types.</param> /// <param name="fCreateComments"><c>true</c> to create XML comments</param> /// <returns><c>true</c> if import successful, otherwise <c>false</c>.</returns> /// ------------------------------------------------------------------------------------ public bool Import(List <string> usingNamespaces, string sFileName, string sXmlFile, string sOutFile, string sNamespace, StringCollection idhFiles, StringCollection referencedFiles, bool fCreateComments) { bool fOk = true; CodeNamespace codeNamespace = new CodeNamespace(); // Add additional using statements foreach (string ns in usingNamespaces) { codeNamespace.Imports.Add(new CodeNamespaceImport(ns)); } // Add types from referenced files so that we can resolve types that are not // defined in this IDL file. foreach (string refFile in referencedFiles) { AddReferences(codeNamespace, refFile); } // Load the IDL conversion rules if (sXmlFile == null) { Assembly assembly = Assembly.GetExecutingAssembly(); sXmlFile = Path.ChangeExtension(assembly.Location, "xml"); } IDLConversions conversions = IDLConversions.Deserialize(sXmlFile); conversions.Namespace = codeNamespace; string outPath = Path.GetFullPath(Path.GetDirectoryName(sOutFile)); conversions.ResolveBaseType += (s, e) => { string rFile = Path.Combine(outPath, e.TypeName + ".iip"); if (!AddReferences(e.NameSpace, rFile)) { e.IdhFileName = rFile; if (ResolveBaseType != null) { ResolveBaseType(this, e); } AddReferences(e.NameSpace, e.IdhFileName ?? rFile); } }; #if SINGLE_THREADED ParseIdhFile(idhFiles); #else m_waitHandle = new EventWaitHandle(false, EventResetMode.AutoReset); ThreadPool.QueueUserWorkItem(new WaitCallback(ParseIdhFiles), idhFiles); #endif using (FileStream stream = new FileStream(sFileName, FileMode.Open, FileAccess.Read)) { IDLLexer lexer = new IDLLexer(stream); IDLParser parser = new IDLParser(lexer); parser.setFilename(sFileName); codeNamespace.Name = sNamespace; codeNamespace.Comments.AddRange(AddFileBanner(sFileName, sOutFile)); codeNamespace.Imports.Add(new CodeNamespaceImport("System")); codeNamespace.Imports.Add(new CodeNamespaceImport("System.Runtime.InteropServices")); codeNamespace.Imports.Add(new CodeNamespaceImport("System.Runtime.InteropServices.ComTypes")); codeNamespace.Imports.Add(new CodeNamespaceImport("System.Runtime.CompilerServices")); // And now parse the IDL file parser.specification(codeNamespace, conversions); // Merge properties fOk = MergeProperties(codeNamespace); IDLConversions.AdjustReferencesInEnums(); // Add XML comments if (fCreateComments) { if (m_waitHandle != null) { m_waitHandle.WaitOne(); } AddComments(codeNamespace.Types); } // Serialize what we have so that we can re-use later if necessary SerializeData(sFileName, codeNamespace); // Finally, create the source code GenerateCode(sOutFile, codeNamespace); } return(fOk); }