/// <summary> /// Converts a Mono.CSharpPs syntax tree into an NRefactory syntax tree. /// </summary> public SyntaxTree Parse(CompilerCompilationUnit top, string fileName) { if (top == null) { return null; } PlayScriptParser.ConversionVisitor conversionVisitor = new ConversionVisitor (GenerateTypeSystemMode, top.LocationsBag); top.ModuleCompiled.Accept(conversionVisitor); conversionVisitor.Unit.FixOutOfOrderLocations(); // Reorder locations that are incorrect for PlayScript InsertComments(top, conversionVisitor); if (CompilationUnitCallback != null) { CompilationUnitCallback(top); } if (top.LastYYValue is Mono.CSharpPs.Expression) { conversionVisitor.Unit.TopExpression = ((Mono.CSharpPs.Expression)top.LastYYValue).Accept(conversionVisitor) as AstNode; } conversionVisitor.Unit.FileName = fileName; conversionVisitor.Unit.ConditionalSymbols = top.Conditionals.Concat (compilerSettings.ConditionalSymbols).ToArray (); 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); CompilerCompilationUnit top; if (String.IsNullOrEmpty(fileName) || fileName.EndsWith(".play") || fileName.EndsWith(".as")) { if (String.IsNullOrEmpty(fileName) || fileName.EndsWith(".play")) file.PsExtended = true; // Assume playscript unless we have an actual file ext. var parser = (Mono.PlayScript.PlayScriptParser)Driver.Parse(reader, file, module, session, report, initialLine - 1, initialColumn - 1); top = new CompilerCompilationUnit() { ModuleCompiled = module, LocationsBag = session.LocationsBag, SpecialsBag = parser.Lexer.sbag, Conditionals = parser.Lexer.SourceFile.Conditionals }; } else { var parser = (Mono.CSharpPs.CSharpParser)Driver.Parse(reader, file, module, session, report, initialLine - 1, initialColumn - 1); 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; } }
static 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 { var directive = special as SpecialsBag.PreProcessorDirective; if (directive != null) { newLeaf = new PreProcessorDirective ((ICSharpCode.NRefactory.PlayScript.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)); } else { newLeaf = new WindowsNewLine (new TextLocation (newLine.Line, newLine.Col)); } }*/ } } 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; } } }