/// <summary>
        /// Extracts the body of the given preprocessor directive symbol, parses it, and returns the parsed expression.
        /// </summary>
        /// <param name="parser">
        /// The C# parser.
        /// </param>
        /// <param name="sourceCode">
        /// The source code containing the preprocessor directive symbol.
        /// </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(CsParser parser, SourceCode sourceCode, Symbol preprocessorSymbol, int startIndex)
        {
            Param.AssertNotNull(parser, "parser");
            Param.AssertNotNull(sourceCode, "sourceCode");
            Param.AssertNotNull(preprocessorSymbol, "preprocessorSymbol");
            Param.AssertGreaterThanOrEqualToZero(startIndex, "startIndex");
            Debug.Assert(preprocessorSymbol.SymbolType == SymbolType.PreprocessorDirective, "The symbol is not a preprocessor directive.");

            string text = preprocessorSymbol.Text.Substring(startIndex, preprocessorSymbol.Text.Length - startIndex).Trim();
            if (text.Length > 0)
            {
                using (StringReader reader = new StringReader(text))
                {
                    // Extract the symbols within this text.
                    CodeLexer lexer = new CodeLexer(parser, sourceCode, new CodeReader(reader));
                    List<Symbol> symbolList = lexer.GetSymbols(sourceCode, null);
                    SymbolManager directiveSymbols = new SymbolManager(symbolList);

                    CodeParser preprocessorBodyParser = new CodeParser(parser, directiveSymbols);

                    // Parse these symbols to create the body expression.
                    return preprocessorBodyParser.GetNextConditionalPreprocessorExpression(sourceCode);
                }
            }

            // The directive has no body.
            return null;
        }
Example #2
0
        /// <summary>
        /// Gets an attribute from the code.
        /// </summary>
        /// <param name="parentReference">
        /// The parent code unit.
        /// </param>
        /// <param name="unsafeCode">
        /// Indicates whether the attribute lies within an unsafe code block.
        /// </param>
        /// <returns>
        /// Returns the attribute.
        /// </returns>
        private Attribute GetAttribute(Reference<ICodePart> parentReference, bool unsafeCode)
        {
            Param.AssertNotNull(parentReference, "parentReference");
            Param.Ignore(unsafeCode);

            CodeParser attributeParser = new CodeParser(this.parser, this.symbols);
            return attributeParser.ParseAttribute(parentReference, unsafeCode, this.document);
        }
Example #3
0
        /// <summary>
        /// Initializes a new instance of the Method class.
        /// </summary>
        /// <param name="document">
        /// The document that contains the element.
        /// </param>
        /// <param name="parent">
        /// The parent of the element.
        /// </param>
        /// <param name="header">
        /// The Xml header for this element.
        /// </param>
        /// <param name="attributes">
        /// The list of attributes attached to this element.
        /// </param>
        /// <param name="declaration">
        /// The declaration code for this element.
        /// </param>
        /// <param name="returnType">
        /// The method's return type.
        /// </param>
        /// <param name="returnTypeIsRef">
        /// The method's return type is ref.
        /// </param>
        /// <param name="parameters">
        /// The parameters to the method.
        /// </param>
        /// <param name="typeConstraints">
        /// The list of type constraints on the element.
        /// </param>
        /// <param name="unsafeCode">
        /// Indicates whether the element resides within a block of unsafe code.
        /// </param>
        /// <param name="generated">
        /// Indicates whether the code element was generated or written by hand.
        /// </param>
        internal Method(
            CsDocument document,
            CsElement parent,
            XmlHeader header,
            ICollection <Attribute> attributes,
            Declaration declaration,
            TypeToken returnType,
            bool returnTypeIsRef,
            IList <Parameter> parameters,
            ICollection <TypeParameterConstraintClause> typeConstraints,
            bool unsafeCode,
            bool generated)
            : base(document, parent, ElementType.Method, "method " + declaration.Name, header, attributes, declaration, unsafeCode, generated)
        {
            Param.AssertNotNull(document, "document");
            Param.AssertNotNull(parent, "parent");
            Param.Ignore(header);
            Param.Ignore(attributes);
            Param.AssertNotNull(declaration, "declaration");
            Param.Ignore(returnType);
            Param.Ignore(returnTypeIsRef);
            Param.AssertNotNull(parameters, "parameters");
            Param.Ignore(typeConstraints);
            Param.Ignore(unsafeCode);
            Param.Ignore(generated);

            Debug.Assert(
                returnType != null || declaration.ContainsModifier(CsTokenType.Explicit, CsTokenType.Implicit),
                "A method's return type can only be null in an explicit or implicit operator overload method.");

            this.returnType      = returnType;
            this.returnTypeIsRef = returnTypeIsRef;
            this.parameters      = parameters;
            this.typeConstraints = typeConstraints;

            Debug.Assert(parameters.IsReadOnly, "The parameters collection should be read-only.");

            // Determine whether this is an extension method. The method must be static.
            if (this.parameters.Count > 0 && this.Declaration.ContainsModifier(CsTokenType.Static))
            {
                // Look at this first parameter. Since the parameters collection is not an indexable list, the
                // easiest way to do this is to foreach through the parameter list and break after the first one.
                foreach (Parameter parameter in this.parameters)
                {
                    if ((parameter.Modifiers & ParameterModifiers.This) != 0)
                    {
                        this.extensionMethod = true;
                    }

                    break;
                }
            }

            // Add the qualifications.
            this.QualifiedName = CodeParser.AddQualifications(this.parameters, this.QualifiedName);

            // If this is an explicit interface member implementation and our access modifier
            // is currently set to private because we don't have one, then it should be public instead.
            if (this.Declaration.Name.IndexOf(".", StringComparison.Ordinal) > -1 && !this.Declaration.Name.StartsWith("this.", StringComparison.Ordinal))
            {
                this.Declaration.AccessModifierType = AccessModifierType.Public;
            }

            // Set the parent of the type constraint clauses.
            if (typeConstraints != null)
            {
                foreach (TypeParameterConstraintClause constraint in typeConstraints)
                {
                    constraint.ParentElement = this;
                }
            }
        }
        public override bool ParseFile(SourceCode sourceCode, int passNumber, ref CodeDocument document)
        {
            Param.RequireNotNull(sourceCode, "sourceCode");
            Param.RequireGreaterThanOrEqualToZero(passNumber, "passNumber");
            Param.Ignore(document);

            StyleCopTrace.In(sourceCode, passNumber, document);

            // The document is parsed on the first pass. On any subsequent passes, we do not do anything.
            if (passNumber == 0)
            {
                if (this.SkipAnalysisForDocument(sourceCode))
                {
                    return false;
                }

                try
                {
                    using (TextReader reader = sourceCode.Read())
                    {
                        // Create the document.
                        if (reader == null)
                        {
                            this.AddViolation(sourceCode, 1, Rules.FileMustBeReadable);
                        }
                        else
                        {
                            // Create the lexer object for the code string.
                            CodeLexer lexer = new CodeLexer(this, sourceCode, new CodeReader(reader));

                            // Parse the document.
                            CodeParser parser = new CodeParser(this, lexer);
                            parser.ParseDocument();

                            document = parser.Document;
                        }
                    }
                }
                catch (SyntaxException syntaxex)
                {
                    this.AddViolation(syntaxex.SourceCode, syntaxex.LineNumber, Rules.SyntaxException, syntaxex.Message);
                    CsDocument csdocument = new CsDocument(sourceCode, this);
                    csdocument.FileHeader = new FileHeader(string.Empty, new CsTokenList(csdocument.Tokens), new Reference<ICodePart>(csdocument));
                    document = csdocument;
                }
            }

            return StyleCopTrace.Out(false);
        }
Example #5
0
        /// <summary>
        /// Sets the inherited items of the class.
        /// </summary>
        /// <param name="declaration">
        /// The class declaration.
        /// </param>
        protected void SetInheritedItems(Declaration declaration)
        {
            Param.RequireNotNull(declaration, "declaration");

            // Pull out the name of the base class and any implemented interfaces
            // from the declaration of this class.
            bool          colon      = false;
            bool          comma      = false;
            List <string> interfaces = new List <string>();

            foreach (CsToken token in declaration.Tokens)
            {
                if (colon)
                {
                    if (token.CsTokenType != CsTokenType.WhiteSpace && token.CsTokenType != CsTokenType.EndOfLine && token.CsTokenType != CsTokenType.SingleLineComment &&
                        token.CsTokenType != CsTokenType.MultiLineComment && token.CsTokenType != CsTokenType.PreprocessorDirective)
                    {
                        if (token.Text.Length >= 2 && token.Text[0] == 'I' && char.IsUpper(token.Text[1]))
                        {
                            interfaces.Add(CodeParser.TrimType(token.Text));
                        }
                        else
                        {
                            this.baseClass = CodeParser.TrimType(token.Text);
                        }

                        colon = false;
                    }
                }
                else if (comma)
                {
                    if (token.CsTokenType != CsTokenType.WhiteSpace && token.CsTokenType != CsTokenType.EndOfLine && token.CsTokenType != CsTokenType.SingleLineComment &&
                        token.CsTokenType != CsTokenType.MultiLineComment && token.CsTokenType != CsTokenType.PreprocessorDirective)
                    {
                        interfaces.Add(CodeParser.TrimType(token.Text));
                        comma = false;
                    }
                }
                else
                {
                    if (token.CsTokenType == CsTokenType.Where)
                    {
                        break;
                    }
                    else if (token.Text == ":")
                    {
                        if (this.baseClass.Length > 0)
                        {
                            break;
                        }
                        else
                        {
                            colon = true;
                        }
                    }
                    else if (token.CsTokenType == CsTokenType.Comma)
                    {
                        comma = true;
                    }
                }
            }

            if (interfaces.Count > 0)
            {
                this.implementedInterfaces = interfaces.ToArray();
            }
        }