/// <summary> /// Initializes a new instance of the CodeParser class. /// </summary> /// <param name="languageService">The C# language service.</param> /// <param name="lexer">The lexer to use for parsing the code.</param> /// <param name="preprocessorDefinitions">The optional preprocessor flags.</param> public CodeParser(CsLanguageService languageService, CodeLexer lexer, Dictionary<string, object> preprocessorDefinitions) { Param.AssertNotNull(languageService, "languageService"); Param.AssertNotNull(lexer, "lexer"); Param.Ignore(preprocessorDefinitions); this.languageService = languageService; this.lexer = lexer; this.preprocessorDefinitions = preprocessorDefinitions; }
/// <summary> /// Creates a document for the given source code. /// </summary> /// <param name="sourceCode">The source code to parse.</param> /// <returns>Returns the document.</returns> /// <exception cref="SyntaxException">Throw a syntax exception if the code cannot be parsed according to the C# specification.</exception> internal CsDocument CreateCodeModelInternal(Code sourceCode) { Param.AssertNotNull(sourceCode, "sourceCode"); // Create the lexer object for the code string. var lexer = new CodeLexer(this, sourceCode, new CodeReader(sourceCode)); // Parse the document. var parser = new CodeParser(this, lexer, this.preprocessorDefinitions); parser.ParseCodeModel(); return parser.Document; }
/// <summary> /// Extracts the body of the given preprocessor directive symbol, parses it, and returns the parsed expression. /// </summary> /// <param name="document">The parent document.</param> /// <param name="code">The source code.</param> /// <param name="parentProxy">Represents the parent item.</param> /// <param name="languageService">The C# language service.</param> /// <param name="preprocessorDefinitions">Optional preprocessor definitions.</param> /// <param name="preprocessorSymbol">The preprocessor directive symbol.</param> /// <param name="startIndex">The index of the start of the expression body within the text string.</param> /// <returns>Returns the expression.</returns> internal static Expression GetConditionalPreprocessorBodyExpression( CsDocument document, Code code, CodeUnitProxy parentProxy, CsLanguageService languageService, IDictionary<string, object> preprocessorDefinitions, Symbol preprocessorSymbol, int startIndex) { Param.AssertNotNull(document, "document"); Param.AssertNotNull(code, "code"); Param.AssertNotNull(parentProxy, "parentProxy"); Param.AssertNotNull(languageService, "languageService"); Param.Ignore(preprocessorDefinitions); Param.AssertNotNull(preprocessorSymbol, "preprocessorSymbol"); Param.AssertGreaterThanOrEqualToZero(startIndex, "startIndex"); CsLanguageService.Debug.Assert(preprocessorSymbol.SymbolType == SymbolType.PreprocessorDirective, "The symbol is not a preprocessor directive."); string text = preprocessorSymbol.Text.Substring(startIndex, preprocessorSymbol.Text.Length - startIndex).TrimEnd(null); if (text.Length > 0) { // Trim off the whitespace at the beginning and advance the start index. int trimIndex = 0; for (int i = 0; i < text.Length; ++i) { if (char.IsWhiteSpace(text[i])) { ++trimIndex; } else { break; } } if (trimIndex > 0) { text = text.Substring(trimIndex, text.Length - trimIndex); startIndex += trimIndex; } if (text.Length > 0) { // Extract the symbols within this text. Code preprocessorCode = new Code(text, "Preprocessor", "Preprocessor"); var lexer = new CodeLexer( languageService, preprocessorCode, new CodeReader(preprocessorCode), preprocessorSymbol.Location.StartPoint.Index + startIndex, preprocessorSymbol.Location.StartPoint.IndexOnLine + startIndex, preprocessorSymbol.Location.StartPoint.LineNumber); List<Symbol> symbolList = lexer.GetSymbols(document, null); var directiveSymbols = new SymbolManager(symbolList); var preprocessorBodyParser = new CodeParser(languageService, document, directiveSymbols, preprocessorDefinitions); // Parse these symbols to create the body expression. return preprocessorBodyParser.GetNextConditionalPreprocessorExpression(document, parentProxy); } } // The directive has no body. return null; }