void InsertComments(CompilerCompilationUnit top, ConversionVisitor conversionVisitor) { AstNode insertionPoint = conversionVisitor.Unit.FirstChild; for (int i = 0; i < top.SpecialsBag.Specials.Count; i++) { var special = top.SpecialsBag.Specials [i]; AstNode newLeaf = null; Role role = null; bool isDocumentationComment = false; var comment = special as SpecialsBag.Comment; if (comment != null) { // HACK: multiline documentation comment detection; better move this logic into the mcs tokenizer bool isMultilineDocumentationComment = ( comment.CommentType == SpecialsBag.CommentType.Multi && comment.Content.StartsWith("*", StringComparison.Ordinal) && !comment.Content.StartsWith("**", StringComparison.Ordinal) ); isDocumentationComment = comment.CommentType == SpecialsBag.CommentType.Documentation || isMultilineDocumentationComment; if (conversionVisitor.convertTypeSystemMode && !isDocumentationComment) continue; var type = isMultilineDocumentationComment ? CommentType.MultiLineDocumentation : (CommentType)comment.CommentType; var start = new TextLocation (comment.Line, comment.Col); var end = new TextLocation (comment.EndLine, comment.EndCol); newLeaf = new Comment (type, start, end) { StartsLine = comment.StartsLine, Content = isMultilineDocumentationComment ? comment.Content.Substring(1) : comment.Content }; role = Roles.Comment; } else if (!GenerateTypeSystemMode) { var pragmaDirective = special as SpecialsBag.PragmaPreProcessorDirective; if (pragmaDirective != null) { var pragma = new PragmaWarningPreprocssorDirective(new TextLocation(pragmaDirective.Line, pragmaDirective.Col), new TextLocation(pragmaDirective.EndLine, pragmaDirective.EndCol)); pragma.Disable = pragmaDirective.Disalbe; pragma.AddWarnings(pragmaDirective.Codes); newLeaf = pragma; role = Roles.PreProcessorDirective; goto end; } var lineDirective = special as SpecialsBag.LineProcessorDirective; if (lineDirective != null) { var pragma = new LinePreprocssorDirective(new TextLocation(lineDirective.Line, lineDirective.Col), new TextLocation(lineDirective.EndLine, lineDirective.EndCol)); pragma.LineNumber = lineDirective.LineNumber; pragma.FileName = lineDirective.FileName; newLeaf = pragma; role = Roles.PreProcessorDirective; goto end; } var directive = special as SpecialsBag.PreProcessorDirective; if (directive != null) { newLeaf = new PreProcessorDirective ((ICSharpCode.NRefactory.CSharp.PreProcessorDirectiveType)((int)directive.Cmd & 0xF), new TextLocation (directive.Line, directive.Col), new TextLocation (directive.EndLine, directive.EndCol)) { Argument = directive.Arg, Take = directive.Take }; role = Roles.PreProcessorDirective; } end: ; } if (newLeaf != null) { InsertComment(ref insertionPoint, newLeaf, role, isDocumentationComment, conversionVisitor.Unit); } } if (!GenerateTypeSystemMode) { // We cannot insert newlines in the same loop as comments/preprocessor directives // because they are not correctly ordered in the specials bag insertionPoint = conversionVisitor.Unit.FirstChild; for (int i = 0; i < top.SpecialsBag.Specials.Count; i++) { var newLine = top.SpecialsBag.Specials[i] as SpecialsBag.NewLineToken; if (newLine != null) { AstNode newLeaf; if (newLine.NewLine == SpecialsBag.NewLine.Unix) { newLeaf = new UnixNewLine (new TextLocation (newLine.Line, newLine.Col + 1)); } else { newLeaf = new WindowsNewLine (new TextLocation (newLine.Line, newLine.Col + 1)); } InsertComment(ref insertionPoint, newLeaf, Roles.NewLine, false, conversionVisitor.Unit); } } } }
void InsertComments(CompilerCompilationUnit top, ConversionVisitor conversionVisitor) { var leaf = GetOuterLeft (conversionVisitor.Unit); for (int i = 0; i < top.SpecialsBag.Specials.Count; i++) { var special = top.SpecialsBag.Specials [i]; AstNode newLeaf = null; var comment = special as SpecialsBag.Comment; if (comment != null) { // HACK: multiline documentation comment detection; better move this logic into the mcs tokenizer bool isMultilineDocumentationComment = ( comment.CommentType == SpecialsBag.CommentType.Multi && comment.Content.StartsWith("*", StringComparison.Ordinal) && !comment.Content.StartsWith("**", StringComparison.Ordinal) ); if (conversionVisitor.convertTypeSystemMode && !(comment.CommentType == SpecialsBag.CommentType.Documentation || isMultilineDocumentationComment)) continue; var type = isMultilineDocumentationComment ? CommentType.MultiLineDocumentation : (CommentType)comment.CommentType; var start = new TextLocation (comment.Line, comment.Col); var end = new TextLocation (comment.EndLine, comment.EndCol); newLeaf = new Comment (type, start, end) { StartsLine = comment.StartsLine, Content = isMultilineDocumentationComment ? comment.Content.Substring(1) : comment.Content }; } else if (!GenerateTypeSystemMode) { var directive = special as SpecialsBag.PreProcessorDirective; if (directive != null) { newLeaf = new PreProcessorDirective ((ICSharpCode.NRefactory.CSharp.PreProcessorDirectiveType)((int)directive.Cmd & 0xF), new TextLocation (directive.Line, directive.Col), new TextLocation (directive.EndLine, directive.EndCol)) { Argument = directive.Arg, Take = directive.Take }; } else { var newLine = special as SpecialsBag.NewLineToken; if (newLine != null) { if (newLine.NewLine == SpecialsBag.NewLine.Unix) { newLeaf = new UnixNewLine (new TextLocation (newLine.Line, newLine.Col + 1)); } else { newLeaf = new WindowsNewLine (new TextLocation (newLine.Line, newLine.Col + 1)); } } } } if (newLeaf == null) continue; while (true) { var nextLeaf = NextLeaf (leaf); // insert comment at begin if (newLeaf.StartLocation < leaf.StartLocation) { var node = leaf.Parent ?? conversionVisitor.Unit; while (node.Parent != null && node.FirstChild == leaf) { leaf = node; node = node.Parent; } if (newLeaf is NewLineNode) { node.InsertChildBefore (leaf, (NewLineNode)newLeaf, Roles.NewLine); } else if (newLeaf is Comment) { node.InsertChildBefore (leaf, (Comment)newLeaf, Roles.Comment); } else { node.InsertChildBefore (leaf, (PreProcessorDirective)newLeaf, Roles.PreProcessorDirective); } leaf = newLeaf; break; } // insert comment at the end if (nextLeaf == null) { var node = leaf.Parent ?? conversionVisitor.Unit; if (newLeaf is NewLineNode) { node.AddChild ((NewLineNode)newLeaf, Roles.NewLine); } else if (newLeaf is Comment) { node.AddChild ((Comment)newLeaf, Roles.Comment); } else { node.AddChild ((PreProcessorDirective)newLeaf, Roles.PreProcessorDirective); } leaf = newLeaf; break; } // comment is between 2 nodes if (leaf.EndLocation <= newLeaf.StartLocation && newLeaf.StartLocation <= nextLeaf.StartLocation) { var node = leaf.Parent ?? conversionVisitor.Unit; if (newLeaf is NewLineNode) { node.InsertChildAfter (leaf, (NewLineNode)newLeaf, Roles.NewLine); } else if (newLeaf is Comment) { node.InsertChildAfter (leaf, (Comment)newLeaf, Roles.Comment); } else { node.InsertChildAfter (leaf, (PreProcessorDirective)newLeaf, Roles.PreProcessorDirective); } leaf = newLeaf; break; } leaf = nextLeaf; } } }