/// <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; }
/// <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); }
/// <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); }
/// <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(); } }