/// <summary> /// Initializes a new instance of the CodeParser class. /// </summary> /// <param name="languageService">The C# language service.</param> /// <param name="document">The document being parsed.</param> /// <param name="symbols">The symbols in the document to parse.</param> /// <param name="preprocessorDefinitions">The optional preprocessor flags.</param> public CodeParser(CsLanguageService languageService, CsDocument document, SymbolManager symbols, IDictionary<string, object> preprocessorDefinitions) { Param.AssertNotNull(languageService, "languageService"); Param.AssertNotNull(document, "document"); Param.AssertNotNull(symbols, "symbols"); Param.Ignore(preprocessorDefinitions); this.languageService = languageService; this.document = document; this.symbols = symbols; this.preprocessorDefinitions = preprocessorDefinitions; }
/// <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; }
/// <summary> /// Parses the contents of the document. /// </summary> internal void ParseCodeModel() { CsLanguageService.Debug.Assert(this.document == null, "This method is only designed to be called once."); // The parent reference to the document. var codeModelProxy = new CodeUnitProxy(null); // Create the document object. this.document = new CsDocument(codeModelProxy, this.lexer.SourceCode.Name, this.lexer.SourceCode.Path, this.languageService.PartialElementService); // Find the list of symbols in the document. List<Symbol> symbolList = this.lexer.GetSymbols( this.document, this.preprocessorDefinitions); // Create the symbol manager class. this.symbols = new SymbolManager(symbolList); // Get the file header if it exists. FileHeader fileHeader = this.GetFileHeader(codeModelProxy); // Let the symbol manager know if this document contains generated code. if (fileHeader.Generated) { this.symbols.IncrementGeneratedCodeBlocks(); } // Parse the contents of the document. this.ParseElementContainerBody(codeModelProxy, this.document, false); // Perform a debug check to ensure that all code unit references have been set. ValidateCodeUnitReferences(this.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); }