/// <summary> /// Parses and returns a field. /// </summary> /// <param name="parent"> /// The parent of the element. /// </param> /// <param name="elementReference"> /// A reference to the element being created. /// </param> /// <param name="unsafeCode"> /// Indicates whether the code is marked as unsafe. /// </param> /// <param name="generated"> /// Indicates whether the code is marked as generated code. /// </param> /// <param name="xmlHeader"> /// The element's documentation header. /// </param> /// <param name="attributes"> /// The attributes on the element. /// </param> /// <returns> /// Returns the element. /// </returns> private Field ParseField( CsElement parent, Reference<ICodePart> elementReference, bool unsafeCode, bool generated, XmlHeader xmlHeader, ICollection<Attribute> attributes) { Param.AssertNotNull(parent, "parent"); Param.AssertNotNull(elementReference, "elementReference"); Param.Ignore(unsafeCode); Param.Ignore(generated); Param.Ignore(xmlHeader); Param.Ignore(attributes); Node<CsToken> previousTokenNode = this.tokens.Last; // Get the modifiers and access. AccessModifierType accessModifier = AccessModifierType.Private; Dictionary<CsTokenType, CsToken> modifiers = this.GetElementModifiers(elementReference, ref accessModifier, FieldModifiers); unsafeCode |= modifiers.ContainsKey(CsTokenType.Unsafe); // Get the field type. TypeToken fieldType = this.GetTypeToken(elementReference, unsafeCode, true); Node<CsToken> fieldTypeNode = this.tokens.InsertLast(fieldType); // Get all of the variable declarators. IList<VariableDeclaratorExpression> declarators = this.ParseFieldDeclarators(elementReference, unsafeCode, fieldType); if (declarators.Count == 0) { throw this.CreateSyntaxException(); } VariableDeclarationExpression declarationExpression = new VariableDeclarationExpression( new CsTokenList(this.tokens, declarators[0].Tokens.First, this.tokens.Last), new LiteralExpression(this.tokens, fieldTypeNode), declarators); // Create the field. Node<CsToken> firstTokenNode = previousTokenNode == null ? this.tokens.First : previousTokenNode.Next; CsTokenList declarationTokens = new CsTokenList(this.tokens, firstTokenNode, this.tokens.Last); Declaration declaration = new Declaration(declarationTokens, declarators[0].Identifier.Text, ElementType.Field, accessModifier, modifiers); Field field = new Field(this.document, parent, xmlHeader, attributes, declaration, fieldType, unsafeCode, generated); elementReference.Target = field; // Get the trailing semicolon. this.tokens.Add(this.GetToken(CsTokenType.Semicolon, SymbolType.Semicolon, elementReference)); // Create the variable declaration statement and add it to the field. field.VariableDeclarationStatement = new VariableDeclarationStatement( new CsTokenList(this.tokens, declarators[0].Tokens.First, this.tokens.Last), field.Const, declarationExpression); return field; }
/// <summary> /// Checks a field for compliance with naming prefix rules. /// </summary> /// <param name="field"> /// The field element. /// </param> /// <param name="validPrefixes"> /// A list of valid prefixes that should not be considered hungarian. /// </param> private void CheckFieldPrefix(Field field, Dictionary<string, string> validPrefixes) { Param.AssertNotNull(field, "field"); Param.Ignore(validPrefixes); // Skip past any prefixes in the name. int index = NamingRules.MovePastPrefix(field.Declaration.Name); // Check whether the name starts with a lower-case letter. if (char.IsLower(field.Declaration.Name, index)) { // Check for hungarian notation. this.CheckHungarian(field.Declaration.Name, index, field.LineNumber, field, validPrefixes); // Check casing on the field. if (field.Const) { // Const fields must start with an upper-case letter. this.AddViolation(field, field.LineNumber, Rules.ConstFieldNamesMustBeginWithUpperCaseLetter, field.Declaration.Name); } else if (field.AccessModifier == AccessModifierType.Public || field.AccessModifier == AccessModifierType.Internal || field.AccessModifier == AccessModifierType.ProtectedInternal) { // Public or internal fields must start with an upper-case letter. this.AddViolation(field, field.LineNumber, Rules.AccessibleFieldsMustBeginWithUpperCaseLetter, field.Declaration.Name); } // Readonly fields non-private must start with an upper-case letter. if (field.Readonly && field.AccessModifier != AccessModifierType.Private) { this.AddViolation(field, field.LineNumber, Rules.NonPrivateReadonlyFieldsMustBeginWithUpperCaseLetter, field.Declaration.Name); } // Readonly static fields must start with an upper-case letter. if (field.Readonly && field.Static) { this.AddViolation(field, field.LineNumber, Rules.StaticReadonlyFieldsMustBeginWithUpperCaseLetter, field.Declaration.Name); } } else if (char.IsUpper(field.Declaration.Name, index)) { // We check for IsUpper here as some languages don't have Upper/Lower case liek Chinese. // Constants must always start with an upper-case letter. if (field.Const) { return; } // Readonly non-private fields must start with an upper-case letter. if (field.Readonly && field.AccessModifier != AccessModifierType.Private) { return; } // Readonly static fields must start with an upper-case letter. if (field.Readonly && field.Static) { return; } // Public, internal or protected-internal fields also must always start with an upper-case letter. if (field.AccessModifier == AccessModifierType.Public) { return; } if (field.AccessModifier == AccessModifierType.Internal) { return; } if (field.AccessModifier == AccessModifierType.ProtectedInternal) { return; } this.AddViolation(field, field.LineNumber, Rules.FieldNamesMustBeginWithLowerCaseLetter, field.Declaration.Name); } }
/// <summary> /// The save. /// </summary> /// <param name="fieldDeclaration"> /// The field declaration. /// </param> private void Save(Field fieldDeclaration) { var isStatic = fieldDeclaration.Declaration.ContainsModifier(CsTokenType.Static); this.Save(fieldDeclaration.AccessModifier); this.headerWriter.Write(": "); if (isStatic) { this.headerWriter.Write("static "); } this.SwitchStreams(); this.saveVariablesMode = SaveVariablesMode.DoNotSaveInitializers; this.Save(fieldDeclaration.VariableDeclarationStatement); this.saveVariablesMode = SaveVariablesMode.Default; this.SwitchStreams(); this.headerWriter.WriteLine(';'); if (isStatic || fieldDeclaration.VariableDeclarationStatement.Constant) { this.saveVariablesMode = SaveVariablesMode.DefaultSourceInitializers; this.Save(fieldDeclaration.VariableDeclarationStatement); this.saveVariablesMode = SaveVariablesMode.Default; this.cppWriter.WriteLine(';'); this.cppWriter.WriteLine(); } }