/// <summary> /// Converts a ICSharpCode.NRefactory.MonoCSharp syntax tree into an NRefactory syntax tree. /// </summary> public SyntaxTree Parse(CompilerCompilationUnit top, string fileName) { if (top == null) { return null; } CSharpParser.ConversionVisitor conversionVisitor = new ConversionVisitor(GenerateTypeSystemMode, top.LocationsBag); top.ModuleCompiled.Accept(conversionVisitor); InsertComments(top, conversionVisitor); if (CompilationUnitCallback != null) { CompilationUnitCallback(top); } var expr = top.LastYYValue as ICSharpCode.NRefactory.MonoCSharp.Expression; if (expr != null) conversionVisitor.Unit.TopExpression = expr.Accept(conversionVisitor) as AstNode; conversionVisitor.Unit.FileName = fileName; var conditionals = new List<string>(); foreach (var settings in compilerSettings.ConditionalSymbols) { if (top.Conditionals.ContainsKey(settings) && !top.Conditionals [settings]) continue; conditionals.Add(settings); } foreach (var kv in top.Conditionals) { if (!kv.Value || compilerSettings.ConditionalSymbols.Contains(kv.Key)) continue; conditionals.Add(kv.Key); } conversionVisitor.Unit.ConditionalSymbols = conditionals; return conversionVisitor.Unit; }
SyntaxTree Parse(ITextSource program, string fileName, int initialLine, int initialColumn) { lock (parseLock) { errorReportPrinter = new ErrorReportPrinter(""); var ctx = new CompilerContext(compilerSettings.ToMono(), errorReportPrinter); ctx.Settings.TabSize = 1; var reader = new SeekableStreamReader(program); var file = new SourceFile(fileName, fileName, 0); Location.Initialize(new List<SourceFile>(new [] { file })); var module = new ModuleContainer(ctx); var session = new ParserSession(); session.LocationsBag = new LocationsBag(); var report = new Report(ctx, errorReportPrinter); var parser = Driver.Parse(reader, file, module, session, report, initialLine - 1, initialColumn - 1); var top = new CompilerCompilationUnit { ModuleCompiled = module, LocationsBag = session.LocationsBag, SpecialsBag = parser.Lexer.sbag, Conditionals = parser.Lexer.SourceFile.Conditionals }; var unit = Parse(top, fileName); unit.Errors.AddRange(errorReportPrinter.Errors); CompilerCallableEntryPoint.Reset(); return unit; } }
void InsertComments(CompilerCompilationUnit top, ConversionVisitor conversionVisitor) { AstNode insertionPoint = conversionVisitor.Unit.FirstChild; foreach (var special in top.SpecialsBag.Specials) { 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 PragmaWarningPreprocessorDirective(new TextLocation(pragmaDirective.Line, pragmaDirective.Col), new TextLocation(pragmaDirective.EndLine, pragmaDirective.EndCol)); pragma.AddChild(new CSharpTokenNode(new TextLocation(pragmaDirective.Line, pragmaDirective.Col), PragmaWarningPreprocessorDirective.PragmaKeywordRole), PragmaWarningPreprocessorDirective.PragmaKeywordRole); pragma.AddChild(new CSharpTokenNode(new TextLocation(pragmaDirective.Line, pragmaDirective.WarningColumn), PragmaWarningPreprocessorDirective.WarningKeywordRole), PragmaWarningPreprocessorDirective.WarningKeywordRole); var pragmaRole = pragmaDirective.Disalbe ? PragmaWarningPreprocessorDirective.DisableKeywordRole : PragmaWarningPreprocessorDirective.RestoreKeywordRole; pragma.AddChild(new CSharpTokenNode(new TextLocation(pragmaDirective.Line, pragmaDirective.DisableRestoreColumn), pragmaRole), pragmaRole); foreach (var code in pragmaDirective.Codes) { pragma.AddChild((PrimitiveExpression)conversionVisitor.Visit(code), PragmaWarningPreprocessorDirective.WarningRole); } newLeaf = pragma; role = Roles.PreProcessorDirective; goto end; } var lineDirective = special as SpecialsBag.LineProcessorDirective; if (lineDirective != null) { var pragma = new LinePreprocessorDirective(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((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) { var newLeaf = new NewLineNode(new TextLocation(newLine.Line, newLine.Col + 1)); newLeaf.NewLineType = newLine.NewLine == SpecialsBag.NewLine.Unix ? UnicodeNewline.LF : UnicodeNewline.CRLF; InsertComment(ref insertionPoint, newLeaf, Roles.NewLine, false, conversionVisitor.Unit); } } } }