Example #1
0
        /// <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;
        }
Example #3
0
        /// <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);
        }
Example #4
0
        /// <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);
        }