void VisitComment(ParsedDocument result, SpecialsBag.Comment comment, string[] tagComments) { var cmt = new MonoDevelop.Ide.TypeSystem.Comment(comment.Content); cmt.CommentStartsLine = comment.StartsLine; switch (comment.CommentType) { case SpecialsBag.CommentType.Multi: cmt.CommentType = MonoDevelop.Ide.TypeSystem.CommentType.Block; cmt.OpenTag = "/*"; cmt.ClosingTag = "*/"; break; case SpecialsBag.CommentType.Single: cmt.CommentType = MonoDevelop.Ide.TypeSystem.CommentType.SingleLine; cmt.OpenTag = "//"; break; case SpecialsBag.CommentType.Documentation: cmt.CommentType = MonoDevelop.Ide.TypeSystem.CommentType.Documentation; cmt.IsDocumentation = true; cmt.OpenTag = "///"; break; } cmt.Region = new DomRegion(comment.Line, comment.Col, comment.EndLine, comment.EndCol); result.Comments.Add(cmt); var trimmedContent = comment.Content.TrimStart(); foreach (string tag in tagComments) { if (!trimmedContent.StartsWith(tag)) { continue; } result.Add(new Tag(tag, comment.Content, cmt.Region)); } }
public ParsedDocument Parse(bool storeAst, string file, TextReader content, Project prj = null) { if (!storeAst) { return(null); } ProjectFile pf = null; var modName = ""; if (prj == null) { var sln = Ide.IdeApp.ProjectOperations.CurrentSelectedSolution; if (sln != null) { foreach (var proj in sln.GetAllProjects()) { if (proj.IsFileInProject(file)) { prj = proj; pf = proj.GetProjectFile(file); modName = BuildModuleName(pf); break; } } } } else if (prj.IsFileInProject(file)) { pf = prj.GetProjectFile(file); modName = BuildModuleName(pf); } // HACK(?) The folds are parsed before the document gets loaded // - so reuse the last parsed document to save time // -- What if multiple docs are opened? if (LastParsedMod is ParsedDModule && LastParsedMod.FileName == file) { var d = (ParsedDModule)LastParsedMod; // Build appropriate module name if (pf != null) { d.DDom.ModuleName = BuildModuleName(pf); } LastParsedMod = null; return(d); } else { LastParsedMod = null; } var dprj = prj as DProject; // Remove obsolete ast from cache IAbstractSyntaxTree ast = null; if (dprj != null) { ast = dprj.LocalFileCache[modName]; if (ast != null) { dprj.LocalFileCache.Remove(ast); dprj.LocalFileCache.UfcsCache.RemoveModuleItems(ast); ast = null; } } var doc = new ParsedDModule(file); var parser = DParser.Create(content); // Also put attention on non-ddoc comments; These will be used to generate foldable comment regions then parser.Lexer.OnlyEnlistDDocComments = false; // Parse the code ast = parser.Parse(); // Update project owner information / Build appropriate module name ast.ModuleName = modName; ast.FileName = file; // Assign new ast to the ParsedDDocument object doc.DDom = ast; // Add parser errors to the parser output foreach (var parserError in parser.ParseErrors) { doc.ErrorList.Add(new Error( ErrorType.Error, parserError.Message, parserError.Location.Line, parserError.Location.Column)); } #region Provide comment fold support by addin them to the IDE document object foreach (var cm in parser.TrackerVariables.Comments) { var c = new MonoDevelop.Ide.TypeSystem.Comment(cm.CommentText); c.CommentType = cm.CommentType.HasFlag(D_Parser.Parser.Comment.Type.Block) ? CommentType.Block : CommentType.SingleLine; c.IsDocumentation = cm.CommentType.HasFlag(D_Parser.Parser.Comment.Type.Documentation); if (c.CommentType == CommentType.SingleLine) { if (c.IsDocumentation) { c.OpenTag = "///"; } else { c.OpenTag = "//"; } } else { if (c.IsDocumentation) { c.OpenTag = "/**"; c.ClosingTag = "*/"; } else { c.OpenTag = "/*"; c.ClosingTag = "*/"; } } c.Region = new DomRegion(cm.StartPosition.Line, cm.StartPosition.Column - 2, cm.EndPosition.Line, cm.EndPosition.Column); doc.Comments.Add(c); // Enlist TODO/FIXME/HACK etc. stuff in the IDE's project task list foreach (var sct in CommentTag.SpecialCommentTags) { if (c.Text.StartsWith(sct.Tag)) { doc.Add(new Tag(sct.Tag, c.Text, c.Region)); break; } } } #endregion #region Serialize to NRefactory Dom structure /* * var cu = new CompilationUnit(file); * doc.CompilationUnit = cu; * * var global = new DomType(cu, ClassType.Class, * Modifiers.Public | Modifiers.Partial, * "(global)", * new DomLocation(), * ast.ModuleName, * new DomRegion()); * cu.Add(global); * * foreach (var n in ast) * { * var ch = ConvertDParserToDomNode(n, doc); * * if (ch is DomField || ch is DomMethod) * global.Add(ch as IMember); * else * cu.Add(ch as IType); * } */ #endregion return(doc); }
public override ParsedDocument Parse(bool storeAst, string file, TextReader content, Project prj = null) { if (!storeAst) return null; ProjectFile pf = null; if (prj == null) { var sln = Ide.IdeApp.ProjectOperations.CurrentSelectedSolution; if (sln != null) foreach (var proj in sln.GetAllProjects()) if (proj.IsFileInProject(file)) { prj = proj; pf = proj.GetProjectFile(file); break; } } else if(prj.IsFileInProject(file)) { pf = prj.GetProjectFile(file); } // HACK(?) The folds are parsed before the document gets loaded // - so reuse the last parsed document to save time // -- What if multiple docs are opened? if (LastParsedMod is ParsedDModule && LastParsedMod.FileName == file) { var d = LastParsedMod as ParsedDModule; LastParsedMod = null; return d; } else LastParsedMod = null; var dprj = prj as DProject; // Remove obsolete ast from cache DModule ast = null; if (dprj != null) { ast = dprj.LocalFileCache.GetModuleByFileName(file, prj.BaseDirectory) as DModule; if (ast != null) { dprj.LocalFileCache.Remove(ast); ast = null; } } var doc = new ParsedDModule(file); var parser = DParser.Create(content); // Also put attention on non-ddoc comments; These will be used to generate foldable comment regions then parser.Lexer.OnlyEnlistDDocComments = false; // Parse the code try { ast = parser.Parse(); } catch (TooManyErrorsException x) { ast = parser.Document; } // Update project owner information / Build appropriate module name if(string.IsNullOrEmpty(ast.ModuleName)) { if(pf == null) ast.ModuleName = Path.GetFileNameWithoutExtension(file); else ast.ModuleName = BuildModuleName(pf); } ast.FileName = file; // Assign new ast to the ParsedDDocument object doc.DDom = ast; // Add parser errors to the parser output foreach (var parserError in parser.ParseErrors) doc.ErrorList.Add(new Error( ErrorType.Error, parserError.Message, parserError.Location.Line, parserError.Location.Column)); #region Provide comment fold support by addin them to the IDE document object foreach (var cm in parser.TrackerVariables.Comments) { var c = new MonoDevelop.Ide.TypeSystem.Comment(cm.CommentText); c.CommentType = cm.CommentType.HasFlag(D_Parser.Parser.Comment.Type.Block) ? CommentType.Block : CommentType.SingleLine; c.IsDocumentation = cm.CommentType.HasFlag(D_Parser.Parser.Comment.Type.Documentation); if (c.CommentType == CommentType.SingleLine) { if (c.IsDocumentation) c.OpenTag = "///"; else c.OpenTag = "//"; } else { if (c.IsDocumentation) { c.OpenTag = "/**"; c.ClosingTag = "*/"; } else { c.OpenTag = "/*"; c.ClosingTag = "*/"; } } c.Region = new DomRegion(cm.StartPosition.Line, cm.StartPosition.Column, cm.EndPosition.Line, cm.EndPosition.Column); doc.Comments.Add(c); // Enlist TODO/FIXME/HACK etc. stuff in the IDE's project task list foreach (var sct in CommentTag.SpecialCommentTags) if (c.Text.StartsWith(sct.Tag)) { doc.Add(new Tag(sct.Tag, c.Text, c.Region)); break; } } // Workaround for tags not being displayed if (prj != null) { var ctnt = TypeSystemService.GetProjectContentWrapper(prj); if (ctnt != null) { var tags = ctnt.GetExtensionObject<ProjectCommentTags>(); if (tags != null) tags.UpdateTags(prj, file, doc.TagComments); } } else { // If the file is not associated with any project, // check if the file is located in an imported/included directory // and update the respective cache. // Note: ParseCache.Remove() also affects the Ufcs cache, // but when adding it again, the UfcsCache has to be updated manually var caches = new List<ParseCache>(); foreach(var p in Ide.IdeApp.Workspace.GetAllProjects()) if (p is DProject) { dprj = p as DProject; if (dprj.LocalIncludeCache.Remove(file)) caches.Add(dprj.LocalIncludeCache); if (dprj.LocalFileCache.Remove(file)) caches.Add(dprj.LocalFileCache); } foreach (var cmp in DCompilerService.Instance.Compilers) { if (cmp.ParseCache.Remove(file)) caches.Add(cmp.ParseCache); } if(caches.Count > 0) { var ctxt = Completion.DCodeCompletionSupport.CreateCurrentContext(); ctxt.CurrentContext.Set((IBlockNode)null); foreach (var cch in caches) { //FIXME: Adjust the target module name and/or copy the ast head cch.AddOrUpdate(ast); cch.UfcsCache.CacheModuleMethods(ast, ctxt); } } } #endregion #region Serialize to NRefactory Dom structure /* var cu = new CompilationUnit(file); doc.CompilationUnit = cu; var global = new DomType(cu, ClassType.Class, Modifiers.Public | Modifiers.Partial, "(global)", new DomLocation(), ast.ModuleName, new DomRegion()); cu.Add(global); foreach (var n in ast) { var ch = ConvertDParserToDomNode(n, doc); if (ch is DomField || ch is DomMethod) global.Add(ch as IMember); else cu.Add(ch as IType); } */ #endregion return doc; }
public override ParsedDocument Parse(bool storeAst, string file, TextReader content, Project prj = null) { if (!storeAst) return null; ProjectFile pf = null; if (prj == null) { var sln = Ide.IdeApp.ProjectOperations.CurrentSelectedSolution; if (sln != null) foreach (var proj in sln.GetAllProjects()) if (proj.IsFileInProject(file)) { prj = proj; pf = proj.GetProjectFile(file); break; } } else if(prj.IsFileInProject(file)) { pf = prj.GetProjectFile(file); } // HACK(?) The folds are parsed before the document gets loaded // - so reuse the last parsed document to save time // -- What if multiple docs are opened? var d = LastParsedMod as ParsedDModule; if (d != null && d.FileName == file) { LastParsedMod = null; return d; } else LastParsedMod = null; var dprj = prj as AbstractDProject; // Remove obsolete ast from cache if(file != null) GlobalParseCache.RemoveModule (file); DModule ast; var doc = new ParsedDModule(file); var parser = DParser.Create(content); // Also put attention on non-ddoc comments; These will be used to generate foldable comment regions then parser.Lexer.OnlyEnlistDDocComments = false; // Parse the code try { ast = parser.Parse(); } catch (TooManyErrorsException) { ast = parser.Document; } catch(System.Exception ex) { doc.ErrorList.Add(new Error(ErrorType.Error, ex.Message)); return doc; } if(ast == null) return doc; // Update project owner information / Build appropriate module name if(string.IsNullOrEmpty(ast.ModuleName)) { if(pf == null) ast.ModuleName = file != null ? Path.GetFileNameWithoutExtension(file) : string.Empty; else ast.ModuleName = BuildModuleName(pf); } ast.FileName = file; // Assign new ast to the ParsedDDocument object doc.DDom = ast; // Add parser errors to the parser output foreach (var parserError in parser.ParseErrors) doc.ErrorList.Add(new Error( ErrorType.Error, parserError.Message, parserError.Location.Line, parserError.Location.Column)); #region Provide comment fold support by addin them to the IDE document object foreach (var cm in parser.Comments) { var c = new MonoDevelop.Ide.TypeSystem.Comment(cm.CommentText){ CommentStartsLine = cm.CommentStartsLine, CommentType = (cm.CommentType & D_Parser.Parser.Comment.Type.Block) != 0 ? CommentType.Block : CommentType.SingleLine, IsDocumentation = cm.CommentType.HasFlag(D_Parser.Parser.Comment.Type.Documentation), }; if (c.CommentType == CommentType.SingleLine) { if (c.IsDocumentation) c.OpenTag = "///"; else c.OpenTag = "//"; } else { if (c.IsDocumentation) { c.OpenTag = "/**"; c.ClosingTag = "*/"; } else { c.OpenTag = "/*"; c.ClosingTag = "*/"; } } c.Region = new DomRegion(cm.StartPosition.Line, cm.StartPosition.Column, cm.EndPosition.Line, cm.EndPosition.Column); doc.Comments.Add(c); // Enlist TODO/FIXME/HACK etc. stuff in the IDE's project task list for (int i = CommentTag.SpecialCommentTags.Count-1; i >= 0 ; i--) if (c.Text.StartsWith(CommentTag.SpecialCommentTags[i].Tag)) { doc.Add(new Tag(CommentTag.SpecialCommentTags[i].Tag, c.Text, c.Region)); break; } } #endregion #region Serialize to NRefactory Dom structure /* var cu = new CompilationUnit(file); doc.CompilationUnit = cu; var global = new DomType(cu, ClassType.Class, Modifiers.Public | Modifiers.Partial, "(global)", new DomLocation(), ast.ModuleName, new DomRegion()); cu.Add(global); foreach (var n in ast) { var ch = ConvertDParserToDomNode(n, doc); if (ch is DomField || ch is DomMethod) global.Add(ch as IMember); else cu.Add(ch as IType); } */ #endregion if (prj != null) { // Workaround for tags not being displayed var ctnt = TypeSystemService.GetProjectContentWrapper(prj); if (ctnt != null) { var tags = ctnt.GetExtensionObject<ProjectCommentTags>(); if (tags != null) tags.UpdateTags(prj, file, doc.TagComments); } } return doc; }
public override ParsedDocument Parse(bool storeAst, string file, TextReader content, Project prj = null) { if (!storeAst) { return(null); } ProjectFile pf = null; if (prj == null) { var sln = Ide.IdeApp.ProjectOperations.CurrentSelectedSolution; if (sln != null) { foreach (var proj in sln.GetAllProjects()) { if (proj.IsFileInProject(file)) { prj = proj; pf = proj.GetProjectFile(file); break; } } } } else if (prj.IsFileInProject(file)) { pf = prj.GetProjectFile(file); } // HACK(?) The folds are parsed before the document gets loaded // - so reuse the last parsed document to save time // -- What if multiple docs are opened? var d = LastParsedMod as ParsedDModule; if (d != null && d.FileName == file) { LastParsedMod = null; return(d); } else { LastParsedMod = null; } var dprj = prj as AbstractDProject; // Remove obsolete ast from cache if (file != null) { GlobalParseCache.RemoveModule(file); } DModule ast; var doc = new ParsedDModule(file); var parser = DParser.Create(content); // Also put attention on non-ddoc comments; These will be used to generate foldable comment regions then parser.Lexer.OnlyEnlistDDocComments = false; // Parse the code try { ast = parser.Parse(); } catch (TooManyErrorsException) { ast = parser.Document; } // Update project owner information / Build appropriate module name if (string.IsNullOrEmpty(ast.ModuleName)) { if (pf == null) { ast.ModuleName = file != null?Path.GetFileNameWithoutExtension(file) : string.Empty; } else { ast.ModuleName = BuildModuleName(pf); } } ast.FileName = file; // Assign new ast to the ParsedDDocument object doc.DDom = ast; // Add parser errors to the parser output foreach (var parserError in parser.ParseErrors) { doc.ErrorList.Add(new Error( ErrorType.Error, parserError.Message, parserError.Location.Line, parserError.Location.Column)); } #region Provide comment fold support by addin them to the IDE document object foreach (var cm in parser.Comments) { var c = new MonoDevelop.Ide.TypeSystem.Comment(cm.CommentText) { CommentStartsLine = cm.CommentStartsLine, CommentType = (cm.CommentType & D_Parser.Parser.Comment.Type.Block) != 0 ? CommentType.Block : CommentType.SingleLine, IsDocumentation = cm.CommentType.HasFlag(D_Parser.Parser.Comment.Type.Documentation), }; if (c.CommentType == CommentType.SingleLine) { if (c.IsDocumentation) { c.OpenTag = "///"; } else { c.OpenTag = "//"; } } else { if (c.IsDocumentation) { c.OpenTag = "/**"; c.ClosingTag = "*/"; } else { c.OpenTag = "/*"; c.ClosingTag = "*/"; } } c.Region = new DomRegion(cm.StartPosition.Line, cm.StartPosition.Column, cm.EndPosition.Line, cm.EndPosition.Column); doc.Comments.Add(c); // Enlist TODO/FIXME/HACK etc. stuff in the IDE's project task list for (int i = CommentTag.SpecialCommentTags.Count - 1; i >= 0; i--) { if (c.Text.StartsWith(CommentTag.SpecialCommentTags[i].Tag)) { doc.Add(new Tag(CommentTag.SpecialCommentTags[i].Tag, c.Text, c.Region)); break; } } } #endregion #region Serialize to NRefactory Dom structure /* * var cu = new CompilationUnit(file); * doc.CompilationUnit = cu; * * var global = new DomType(cu, ClassType.Class, * Modifiers.Public | Modifiers.Partial, * "(global)", * new DomLocation(), * ast.ModuleName, * new DomRegion()); * cu.Add(global); * * foreach (var n in ast) * { * var ch = ConvertDParserToDomNode(n, doc); * * if (ch is DomField || ch is DomMethod) * global.Add(ch as IMember); * else * cu.Add(ch as IType); * } */ #endregion if (prj != null) { // Workaround for tags not being displayed var ctnt = TypeSystemService.GetProjectContentWrapper(prj); if (ctnt != null) { var tags = ctnt.GetExtensionObject <ProjectCommentTags>(); if (tags != null) { tags.UpdateTags(prj, file, doc.TagComments); } } } return(doc); }
void ParseHtmlDocument (List<Error> errors) { var sb = new StringBuilder (); var spanList = new List<Span> (); comments = new List<Comment> (); Action<Span> action = (Span span) => { if (span.Kind == SpanKind.Markup) { sb.Append (span.Content); spanList.Add (span); } else { for (int i = 0; i < span.Content.Length; i++) { char ch = span.Content[i]; if (ch != '\r' && ch != '\n') sb.Append (' '); else sb.Append (ch); } if (span.Kind == SpanKind.Comment) { var comment = new Comment (span.Content) { OpenTag = "@*", ClosingTag = "*@", CommentType = CommentType.Block, }; comment.Region = new DomRegion ( currentDocument.OffsetToLocation (span.Start.AbsoluteIndex - comment.OpenTag.Length), currentDocument.OffsetToLocation (span.Start.AbsoluteIndex + span.Length + comment.ClosingTag.Length)); comments.Add (comment); } } }; editorParser.CurrentParseTree.Accept (new CallbackVisitor (action)); var parser = new MonoDevelop.Xml.Parser.XmlParser (new WebFormsRootState (), true); try { parser.Parse (new StringReader (sb.ToString ())); } catch (Exception ex) { LoggingService.LogError ("Unhandled error parsing html in Razor document '" + (lastParsedFile ?? "") + "'", ex); } htmlParsedDocument = parser.Nodes.GetRoot (); errors.AddRange (parser.Errors); }
public override void VisitTrivia (SyntaxTrivia trivia) { base.VisitTrivia (trivia); switch (trivia.Kind ()) { case SyntaxKind.MultiLineCommentTrivia: case SyntaxKind.MultiLineDocumentationCommentTrivia: { var cmt = new Comment (CropStart (trivia.ToString (), "/*")); cmt.CommentStartsLine = StartsLine(trivia); cmt.CommentType = CommentType.Block; cmt.OpenTag = "/*"; cmt.ClosingTag = "*/"; cmt.Region = GetRegion (trivia); Comments.Add (cmt); break; } case SyntaxKind.SingleLineCommentTrivia: { var cmt = new Comment (CropStart (trivia.ToString (), "//")); cmt.CommentStartsLine = StartsLine(trivia); cmt.CommentType = CommentType.SingleLine; cmt.OpenTag = "//"; cmt.Region = GetRegion (trivia); Comments.Add (cmt); break; } case SyntaxKind.SingleLineDocumentationCommentTrivia: { var cmt = new Comment (CropStart (trivia.ToString (), "///")); cmt.CommentStartsLine = StartsLine(trivia); cmt.IsDocumentation = true; cmt.CommentType = CommentType.Documentation; cmt.OpenTag = "///"; cmt.ClosingTag = "*/"; cmt.Region = GetRegion (trivia); Comments.Add (cmt); break; } } }
public override ParsedDocument Parse(bool storeAst, string file, TextReader content, Project prj = null) { if (!storeAst) { return(null); } ProjectFile pf = null; if (prj == null) { var sln = Ide.IdeApp.ProjectOperations.CurrentSelectedSolution; if (sln != null) { foreach (var proj in sln.GetAllProjects()) { if (proj.IsFileInProject(file)) { prj = proj; pf = proj.GetProjectFile(file); break; } } } } else if (prj.IsFileInProject(file)) { pf = prj.GetProjectFile(file); } // HACK(?) The folds are parsed before the document gets loaded // - so reuse the last parsed document to save time // -- What if multiple docs are opened? if (LastParsedMod is ParsedDModule && LastParsedMod.FileName == file) { var d = LastParsedMod as ParsedDModule; LastParsedMod = null; return(d); } else { LastParsedMod = null; } var dprj = prj as AbstractDProject; // Remove obsolete ast from cache GlobalParseCache.RemoveModule(file); DModule ast; var doc = new ParsedDModule(file); var parser = DParser.Create(content); // Also put attention on non-ddoc comments; These will be used to generate foldable comment regions then parser.Lexer.OnlyEnlistDDocComments = false; // Parse the code try { ast = parser.Parse(); } catch (TooManyErrorsException x) { ast = parser.Document; } // Update project owner information / Build appropriate module name if (string.IsNullOrEmpty(ast.ModuleName)) { if (pf == null) { ast.ModuleName = Path.GetFileNameWithoutExtension(file); } else { ast.ModuleName = BuildModuleName(pf); } } ast.FileName = file; // Assign new ast to the ParsedDDocument object doc.DDom = ast; // Add parser errors to the parser output foreach (var parserError in parser.ParseErrors) { doc.ErrorList.Add(new Error( ErrorType.Error, parserError.Message, parserError.Location.Line, parserError.Location.Column)); } #region Provide comment fold support by addin them to the IDE document object foreach (var cm in parser.TrackerVariables.Comments) { var c = new MonoDevelop.Ide.TypeSystem.Comment(cm.CommentText) { CommentStartsLine = cm.CommentStartsLine, CommentType = (cm.CommentType & D_Parser.Parser.Comment.Type.Block) != 0 ? CommentType.Block : CommentType.SingleLine, IsDocumentation = cm.CommentType.HasFlag(D_Parser.Parser.Comment.Type.Documentation), }; if (c.CommentType == CommentType.SingleLine) { if (c.IsDocumentation) { c.OpenTag = "///"; } else { c.OpenTag = "//"; } } else { if (c.IsDocumentation) { c.OpenTag = "/**"; c.ClosingTag = "*/"; } else { c.OpenTag = "/*"; c.ClosingTag = "*/"; } } c.Region = new DomRegion(cm.StartPosition.Line, cm.StartPosition.Column, cm.EndPosition.Line, cm.EndPosition.Column); doc.Comments.Add(c); // Enlist TODO/FIXME/HACK etc. stuff in the IDE's project task list for (int i = CommentTag.SpecialCommentTags.Count - 1; i >= 0; i--) { if (c.Text.StartsWith(CommentTag.SpecialCommentTags[i].Tag)) { doc.Add(new Tag(CommentTag.SpecialCommentTags[i].Tag, c.Text, c.Region)); break; } } } #endregion #region Serialize to NRefactory Dom structure /* * var cu = new CompilationUnit(file); * doc.CompilationUnit = cu; * * var global = new DomType(cu, ClassType.Class, * Modifiers.Public | Modifiers.Partial, * "(global)", * new DomLocation(), * ast.ModuleName, * new DomRegion()); * cu.Add(global); * * foreach (var n in ast) * { * var ch = ConvertDParserToDomNode(n, doc); * * if (ch is DomField || ch is DomMethod) * global.Add(ch as IMember); * else * cu.Add(ch as IType); * } */ #endregion if (prj != null) { // Workaround for tags not being displayed var ctnt = TypeSystemService.GetProjectContentWrapper(prj); if (ctnt != null) { var tags = ctnt.GetExtensionObject <ProjectCommentTags>(); if (tags != null) { tags.UpdateTags(prj, file, doc.TagComments); } } } // Update UFCS ModulePackage pack; if ((pack = GlobalParseCache.GetPackage(ast, false)) != null && (pack = pack.Root) != null) { // If the file is not associated with any project, // check if the file is located in an imported/included directory // and update the respective cache. // Note: ParseCache.Remove() also affects the Ufcs cache, // but when adding it again, the UfcsCache has to be updated manually ParseCacheView pcw; bool containsPack = false; if (prj != null) { pcw = dprj.ParseCache; containsPack = true; } else { // Find out which compiler environment fits most pcw = null; foreach (var cmp in DCompilerService.Instance.Compilers) { pcw = cmp.GenParseCacheView(); foreach (var r in pack as IEnumerable <ModulePackage> ) { if (r == pack) { containsPack = true; break; } } if (containsPack) { break; } } } if (containsPack) { (pack as RootPackage).UfcsCache.CacheModuleMethods(ast, new ResolutionContext(pcw, null, ast)); } } return(doc); }
public ParsedDocument Parse(bool storeAst, string file, TextReader content, Project prj = null) { if (!storeAst) return null; // HACK(?) The folds are parsed before the document gets loaded // - so reuse the last parsed document to save time // -- What if multiple docs are opened? if (LastParsedMod is ParsedDModule && LastParsedMod.FileName == file) { var d = (ParsedDModule)LastParsedMod; if (prj!=null) { var pf = prj.GetProjectFile(file); // Build appropriate module name if (pf != null) d.DDom.ModuleName = BuildModuleName(pf); } LastParsedMod = null; return d; } else LastParsedMod = null; var doc = new ParsedDModule(file); var parser = DParser.Create(content); // Also put attention on non-ddoc comments; These will be used to generate foldable comment regions then parser.Lexer.OnlyEnlistDDocComments = false; // Parse the code var ast = parser.Parse(); // Update project owner information if (prj is DProject) { var pf = prj.GetProjectFile(file); // Build appropriate module name if (pf != null) ast.ModuleName = BuildModuleName(pf); } ast.FileName = file; doc.DDom = ast; // Add parser errors to the parser output foreach (var parserError in parser.ParseErrors) doc.ErrorList.Add(new Error( ErrorType.Error, parserError.Message, parserError.Location.Line, parserError.Location.Column)); #region Provide comment fold support by addin them to the IDE document object foreach (var cm in parser.TrackerVariables.Comments) { var c = new MonoDevelop.Ide.TypeSystem.Comment(cm.CommentText); c.CommentType = cm.CommentType.HasFlag(D_Parser.Parser.Comment.Type.Block) ? CommentType.Block : CommentType.SingleLine; c.IsDocumentation = cm.CommentType.HasFlag(D_Parser.Parser.Comment.Type.Documentation); if (c.CommentType == CommentType.SingleLine) { if (c.IsDocumentation) c.OpenTag = "///"; else c.OpenTag = "//"; } else { if (c.IsDocumentation) { c.OpenTag = "/**"; c.ClosingTag = "*/"; } else { c.OpenTag = "/*"; c.ClosingTag = "*/"; } } c.Region = new DomRegion(cm.StartPosition.Line, cm.StartPosition.Column - 2, cm.EndPosition.Line, cm.EndPosition.Column); doc.Comments.Add(c); // Enlist TODO/FIXME/HACK etc. stuff in the IDE's project task list foreach (var sct in CommentTag.SpecialCommentTags) if (c.Text.StartsWith(sct.Tag)) { doc.Add(new Tag(sct.Tag, c.Text, c.Region)); break; } } #endregion #region Serialize to NRefactory Dom structure /* var cu = new CompilationUnit(file); doc.CompilationUnit = cu; var global = new DomType(cu, ClassType.Class, Modifiers.Public | Modifiers.Partial, "(global)", new DomLocation(), ast.ModuleName, new DomRegion()); cu.Add(global); foreach (var n in ast) { var ch = ConvertDParserToDomNode(n, doc); if (ch is DomField || ch is DomMethod) global.Add(ch as IMember); else cu.Add(ch as IType); } */ #endregion return doc; }
public static IEnumerable <FoldingRegion> ToFolds(this IList <Comment> comments) { for (int i = 0; i < comments.Count; i++) { Comment comment = comments [i]; if (comment.CommentType == CommentType.Block) { int startOffset = 0; if (comment.Region.BeginLine == comment.Region.EndLine) { continue; } while (startOffset < comment.Text.Length) { char ch = comment.Text [startOffset]; if (!char.IsWhiteSpace(ch) && ch != '*') { break; } startOffset++; } int endOffset = startOffset; while (endOffset < comment.Text.Length) { char ch = comment.Text [endOffset]; if (ch == '\r' || ch == '\n' || ch == '*') { break; } endOffset++; } string txt; if (endOffset > startOffset) { txt = "/* " + SubstrEllipsize(comment.Text, startOffset, endOffset - startOffset) + " */"; } else { txt = "/* */"; } yield return(new FoldingRegion(txt, comment.Region, FoldType.Comment)); continue; } if (!comment.CommentStartsLine) { continue; } int j = i; int curLine = comment.Region.BeginLine - 1; var end = comment.Region.End; var commentText = new StringBuilder(); for (; j < comments.Count; j++) { Comment curComment = comments [j]; if (curComment == null || !curComment.CommentStartsLine || curComment.CommentType != comment.CommentType || curLine + 1 != curComment.Region.BeginLine) { break; } commentText.Append(curComment.Text); end = curComment.Region.End; curLine = curComment.Region.BeginLine; } if (j - i > 1) { string txt; if (comment.IsDocumentation) { txt = "/// ..."; string cmtText = commentText.ToString(); int idx = cmtText.IndexOf("<summary>"); if (idx >= 0) { int maxOffset = cmtText.IndexOf("</summary>"); while (maxOffset > 0 && cmtText[maxOffset - 1] == ' ') { maxOffset--; } if (maxOffset < 0) { maxOffset = cmtText.Length; } int startOffset = idx + "<summary>".Length; while (startOffset < maxOffset) { char ch = cmtText [startOffset]; if (!char.IsWhiteSpace(ch) && ch != '/') { break; } startOffset++; } int endOffset = startOffset; while (endOffset < maxOffset) { char ch = cmtText [endOffset]; if (ch == '\r' || ch == '\n') { break; } endOffset++; } if (endOffset > startOffset) { txt = "/// " + SubstrEllipsize(cmtText, startOffset, endOffset - startOffset); } } } else { txt = "// " + SubstrEllipsize(comment.Text, 0, comment.Text.Length); } yield return(new FoldingRegion(txt, new DomRegion(comment.Region.Begin, end), FoldType.Comment)); i = j - 1; } } }
public void Add(Comment comment) { comments.Add(comment); }