/// <summary> /// Checks a word to see if it should start with this. or base. /// </summary> /// <param name="word">The word text to check.</param> /// <param name="item">The word being checked.</param> /// <param name="line">The line that the word appears on.</param> /// <param name="expression">The expression the word appears within.</param> /// <param name="parentElement">The element that contains the word.</param> /// <param name="parentClass">The parent class that this element belongs to.</param> /// <param name="members">The collection of members of the parent class.</param> private void CheckWordUsageAgainstClassMemberRules( string word, Token item, int line, Expression expression, Element parentElement, ClassBase parentClass, Dictionary <string, List <Element> > members) { Param.AssertValidString(word, "word"); Param.AssertNotNull(item, "item"); Param.AssertGreaterThanZero(line, "line"); Param.AssertNotNull(expression, "expression"); Param.AssertNotNull(parentElement, "parentElement"); Param.Ignore(parentClass); Param.Ignore(members); // If there is a local variable with the same name, or if the item we're checking is within the left-hand side // of an object initializer expression, then ignore it. if (!IsLocalMember(word, item, expression) && !IsObjectInitializerLeftHandSideExpression(expression)) { // Determine if this is a member of our class. Element foundMember = null; ICollection <Element> classMembers = ReadabilityRules.FindClassMember(word, parentClass, members, false); if (classMembers != null) { foreach (Element classMember in classMembers) { if (classMember.ContainsModifier(TokenType.Static) || (classMember.ElementType == ElementType.Field && ((Field)classMember).Const)) { // There is a member with a matching name that is static or is a const field. In this case, // ignore the issue and quit. foundMember = null; break; } else if (classMember.ElementType != ElementType.Class && classMember.ElementType != ElementType.Struct && classMember.ElementType != ElementType.Delegate && classMember.ElementType != ElementType.Enum) { // Found a matching member. if (foundMember == null) { foundMember = classMember; } } } if (foundMember != null) { if (foundMember.ElementType == ElementType.Property) { // If the property's name and type are the same, then this is not a violation. // In this case, the type is being accessed, not the property. Property property = (Property)foundMember; if (property.ReturnType.Text != property.Name) { this.Violation <Token>( Rules.PrefixLocalCallsWithThis, new ViolationContext(parentElement, line, word), this.FixPrefixLocalCallsWithThisViolation, item); } } else { this.Violation <Token>( Rules.PrefixLocalCallsWithThis, new ViolationContext(parentElement, line, word), this.FixPrefixLocalCallsWithThisViolation, item); } } } } }
/// <summary> /// Parses the given literal token. /// </summary> /// <param name="token">The literal token node.</param> /// <param name="expression">The expression that contains the token.</param> /// <param name="parentExpression">The parent of the expression that contains the token.</param> /// <param name="parentElement">The element that contains the expression.</param> /// <param name="parentClass">The class that the element belongs to.</param> /// <param name="members">The collection of members of the parent class.</param> private void CheckClassMemberRulesForLiteralToken( Token token, Expression expression, Expression parentExpression, Element parentElement, ClassBase parentClass, Dictionary <string, List <Element> > members) { Param.AssertNotNull(token, "token"); Param.AssertNotNull(expression, "expression"); Param.Ignore(parentExpression); Param.AssertNotNull(parentElement, "parentElement"); Param.Ignore(parentClass); Param.Ignore(members); // Skip types. We only care about named members. if (token.TokenType != TokenType.Type) { // If the name starts with a dot, ignore it. if (!token.Text.StartsWith(".", StringComparison.Ordinal)) { if (token.Text == "base" && parentExpression != null) { // An item is only allowed to start with base if there is an implementation of the // item in the local class and the caller is trying to explicitly call the base // class implementation instead of the local class implementation. Extract the name // of the item being accessed. Token name = ReadabilityRules.ExtractBaseClassMemberName(parentExpression, token); if (name != null) { ICollection <Element> matches = ReadabilityRules.FindClassMember(name.Text, parentClass, members, true); // Check to see if there is a non-static match. bool found = false; if (matches != null) { foreach (Element match in matches) { if (!match.ContainsModifier(TokenType.Static)) { found = true; break; } } } if (!found) { this.AddViolation(parentElement, name.LineNumber, Rules.DoNotPrefixCallsWithBaseUnlessLocalImplementationExists, name); } } } else if (token.Text != "this") { // Check whether this word should really start with this. this.CheckWordUsageAgainstClassMemberRules( token.Text, token, token.LineNumber, expression, parentElement, parentClass, members); } } } }