/// <summary> /// Converts an access modifier type to a human readable string. /// </summary> /// <param name="type"> /// The type to convert. /// </param> /// <returns> /// Returns the human readable string. /// </returns> private static string AccessModifierTypeString(AccessModifierType type) { Param.Ignore(type); switch (type) { case AccessModifierType.Public: return("public"); case AccessModifierType.Internal: return("internal"); case AccessModifierType.Protected: return("protected"); case AccessModifierType.Private: return("private"); case AccessModifierType.ProtectedInternal: return("protected internal"); default: Debug.Fail("Unexpected access modifier keyword"); throw new InvalidOperationException(); } }
private ModifierCollection(IList <Token> modifiers) { this.FirstToken = modifiers.Count == 0 ? null : modifiers[0]; foreach (Token token in modifiers) { int index = (int)LOOKUP[token.Value]; if (this.tokens[index] != null) { throw new ParserException(token, "Multiple declarations of '" + token.Value + "' have occurred."); } this.tokens[index] = token; } if (this.HasPrivate) { this.AccessModifierType = AccessModifierType.PRIVATE; } else if (this.HasInternal) { this.AccessModifierType = AccessModifierType.INTERNAL; } else if (this.HasProtected) { this.AccessModifierType = AccessModifierType.PROTECTED; } else { this.AccessModifierType = AccessModifierType.PUBLIC; } if (modifiers.Count > 1) { int accessModifierCount = (this.HasPublicExplicitly ? 1 : 0) + (this.HasPrivate ? 1 : 0) + (this.HasInternal ? 1 : 0) + (this.HasProtected ? 1 : 0); if (accessModifierCount > 1) { if (accessModifierCount != 2 || !this.HasProtected || !this.HasInternal) { throw new ParserException( this.PublicToken ?? this.PrivateToken ?? this.InternalToken, "Multiple access modifiers are not allowed (with the exception of internal + protected"); } else { this.AccessModifierType = AccessModifierType.INTERNAL_PROTECTED; } } } if (this.HasFinal && this.HasAbstract) { throw new ParserException(this.FinalToken, "Entity cannot be both final and abstract."); } }
/// <summary> /// Initializes a new instance of the Declaration class. /// </summary> /// <param name="tokens">The array of tokens that make up the declaration.</param> /// <param name="name">The name of the element.</param> /// <param name="elementType">The type of the element.</param> /// <param name="accessModifierType">The access type of the element.</param> internal Declaration( CsTokenList tokens, string name, ElementType elementType, AccessModifierType accessModifierType) : this(tokens, name, elementType, accessModifierType, new Dictionary<CsTokenType, CsToken>(0)) { Param.Ignore(tokens, name, elementType, accessModifierType); }
/// <summary> /// Checks whether specified element has private access modifier. /// </summary> public static bool IsPrivate(CsElement element) { AccessModifierType modifier = element.AccessModifier; if (modifier == AccessModifierType.Private) { return(true); } return(false); }
internal static bool IsAccessAllowed(Node callerLocation, TopLevelEntity referencedEntity) { AccessModifierType invokedAccessType = referencedEntity.Modifiers.AccessModifierType; if (invokedAccessType == AccessModifierType.PUBLIC) { return(true); } bool sameScope = referencedEntity.CompilationScope == callerLocation.CompilationScope; if (invokedAccessType == AccessModifierType.INTERNAL) { return(sameScope); } if (invokedAccessType == AccessModifierType.INTERNAL_PROTECTED) { if (!sameScope) { return(false); } } ClassDefinition memberClass = GetWrappingClassOfNodeIfNotAlreadyAClass(referencedEntity); ClassDefinition callerClass = GetWrappingClassOfNodeIfNotAlreadyAClass(callerLocation); bool sameClass = memberClass == callerClass; if (sameClass || invokedAccessType == AccessModifierType.PRIVATE) { return(sameClass); } // at this point, we are only left with PROTECTED and // INTERNAL_PROTECTED (where the INTERNAL part was already verified) and we // know that the calling site does not occur in the member's class. ClassDefinition classWalker = callerClass; while (classWalker != null) { classWalker = classWalker.BaseClass; if (classWalker == memberClass) { return(true); } } return(false); }
/// <summary> /// Checks whether specified element has internal access modifier. /// </summary> public static bool IsInternal(CsElement element) { AccessModifierType modifier = element.AccessModifier; if (modifier == AccessModifierType.Internal) { return(true); } if (modifier == AccessModifierType.ProtectedInternal) { return(true); } return(false); }
/// <summary> /// Initializes a new instance of the Declaration class. /// </summary> /// <param name="tokens"> /// The array of tokens that make up the declaration. /// </param> /// <param name="name"> /// The name of the element. /// </param> /// <param name="elementType"> /// The type of the element. /// </param> /// <param name="accessModifierType"> /// The access type of the element. /// </param> /// <param name="modifiers"> /// The list of modifier keywords in the declaration. /// </param> internal Declaration(CsTokenList tokens, string name, ElementType elementType, AccessModifierType accessModifierType, Dictionary <CsTokenType, CsToken> modifiers) { Param.AssertNotNull(tokens, "tokens"); Param.AssertNotNull(name, "name"); Param.Ignore(elementType); Param.Ignore(accessModifierType); Param.AssertNotNull(modifiers, "modifiers"); this.tokens = tokens; this.name = CodeLexer.DecodeEscapedText(name, true); this.elementType = elementType; this.accessModifierType = accessModifierType; this.modifiers = modifiers; this.tokens.Trim(); }
/// <summary> /// Initializes a new instance of the Declaration class. /// </summary> /// <param name="tokens">The array of tokens that make up the declaration.</param> /// <param name="name">The name of the element.</param> /// <param name="elementType">The type of the element.</param> /// <param name="accessModifierType">The access type of the element.</param> /// <param name="modifiers">The list of modifier keywords in the declaration.</param> internal Declaration( CsTokenList tokens, string name, ElementType elementType, AccessModifierType accessModifierType, Dictionary<CsTokenType, CsToken> modifiers) { Param.AssertNotNull(tokens, "tokens"); Param.AssertNotNull(name, "name"); Param.Ignore(elementType); Param.Ignore(accessModifierType); Param.AssertNotNull(modifiers, "modifiers"); this.tokens = tokens; this.name = name; this.elementType = elementType; this.accessModifierType = accessModifierType; this.modifiers = modifiers; this.tokens.Trim(); }
private static string AccessModifierTypeString(AccessModifierType type) { switch (type) { case AccessModifierType.Public: return "public"; case AccessModifierType.Internal: return "internal"; case AccessModifierType.ProtectedInternal: return "protected internal"; case AccessModifierType.Protected: return "protected"; case AccessModifierType.Private: return "private"; } throw new InvalidOperationException(); }
/// <summary> /// Initializes a new instance of the CsElement class. /// </summary> /// <param name="document"> /// The document that contains the element. /// </param> /// <param name="parent"> /// The parent of the element. /// </param> /// <param name="type"> /// The element type. /// </param> /// <param name="name"> /// The name of this 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="unsafeCode"> /// Indicates whether the element is unsafe. /// </param> /// <param name="generated"> /// Indicates whether the element was generated or written by hand. /// </param> internal CsElement( CsDocument document, CsElement parent, ElementType type, string name, XmlHeader header, ICollection <Attribute> attributes, Declaration declaration, bool unsafeCode, bool generated) : base(CodePartType.Element) { Param.AssertNotNull(document, "document"); Param.Ignore(parent); Param.Ignore(type); Param.AssertNotNull(name, "name"); Param.Ignore(header); Param.Ignore(attributes); Param.Ignore(declaration); Param.Ignore(unsafeCode); Param.Ignore(generated); this.document = document; if (this.document == null) { throw new ArgumentException(Strings.DocumentMustBeCsDocument, "document"); } if (parent != null && parent.Document != document) { throw new ArgumentException(Strings.ElementMustBeInParentsDocument, "parent"); } this.type = type; this.name = CodeLexer.DecodeEscapedText(name, true); this.header = header; this.attributes = attributes; this.declaration = declaration; this.unsafeCode = unsafeCode; this.generated = generated; if (!unsafeCode && this.declaration.ContainsModifier(CsTokenType.Unsafe)) { this.unsafeCode = true; } // Fill in the element reference in the header object. if (this.header != null) { Debug.Assert(this.header.Element == null, "The header element should not be empty."); this.header.Element = this; } // Fill in the element reference in the attributes list items. if (this.attributes != null) { Debug.Assert(this.attributes.IsReadOnly, "The attributes collection should be read-only."); foreach (Attribute attribute in this.attributes) { Debug.Assert(attribute.Element == null, "The attribute element should not be empty"); attribute.Element = this; } } // Set the fully qualified base name if (parent != null) { this.fullyQualifiedBase = parent.FullyQualifiedName; this.MergeAccess(parent.ActualAccess); } else { if (this.declaration != null) { this.actualAccess = this.declaration.AccessModifierType; } else { this.actualAccess = AccessModifierType.Public; } } // Set the fully qualified name this.fullyQualifiedName = this.fullyQualifiedBase; if (this.declaration != null && this.declaration.Name != null && this.declaration.Name.Length > 0) { if (this.fullyQualifiedBase != null && this.fullyQualifiedBase.Length > 0) { this.fullyQualifiedName += "."; } int index = this.declaration.Name.LastIndexOf("\\", StringComparison.Ordinal); if (index != -1) { this.fullyQualifiedName += this.declaration.Name.Substring(index + 1, this.declaration.Name.Length - index - 1); } else { this.fullyQualifiedName += this.declaration.Name; } index = this.fullyQualifiedName.IndexOf(".cs.", StringComparison.OrdinalIgnoreCase); if (-1 == index) { this.fullNamespaceName = this.fullyQualifiedName; } else { this.fullNamespaceName = this.fullyQualifiedName.Substring(index + 4, this.fullyQualifiedName.Length - index - 4); } } // There is only one type of element which is allowed to have a token // list consisting of nothing other than whitespace, newlines, etc., // which is the document root. This happens if you have a document which // contains nothing other than whitespace. Due to this we do not want to // trim down the token list for the root element, but we do want to for // all other types of elements. if (type == ElementType.Root) { this.TrimTokens = false; } }
/// <summary> /// Merges the access of this element with the access of its parent to determine /// the actual visibility of this item outside of the class. /// </summary> /// <returns>Returns the actual access level.</returns> private AccessModifierType ComputeActualAccess() { AccessModifierType localAccess = this.AccessModifierType; if (localAccess == AccessModifierType.Private) { return(localAccess); } Element parentElement = this.ParentCastedToElement; if (parentElement == null) { return(localAccess); } AccessModifierType parentActualAccess = parentElement.ActualAccessLevel; AccessModifierType actualAccess = localAccess; if (parentActualAccess == AccessModifierType.Public) { return(actualAccess); } else if (parentActualAccess == AccessModifierType.ProtectedInternal) { if (actualAccess == AccessModifierType.Public) { return(AccessModifierType.ProtectedInternal); } else { return(actualAccess); } } else if (parentActualAccess == AccessModifierType.Protected) { if (actualAccess == AccessModifierType.Public || actualAccess == AccessModifierType.ProtectedInternal) { return(AccessModifierType.Protected); } else if (actualAccess == AccessModifierType.Internal) { return(AccessModifierType.ProtectedAndInternal); } else { return(actualAccess); } } else if (parentActualAccess == AccessModifierType.Internal) { if (actualAccess == AccessModifierType.Public || actualAccess == AccessModifierType.ProtectedInternal) { return(AccessModifierType.Internal); } else if (actualAccess == AccessModifierType.Protected) { return(AccessModifierType.ProtectedAndInternal); } else { return(actualAccess); } } else if (parentActualAccess == AccessModifierType.ProtectedAndInternal) { if (actualAccess == AccessModifierType.Public || actualAccess == AccessModifierType.ProtectedInternal || actualAccess == AccessModifierType.Protected || actualAccess == AccessModifierType.Internal) { return(AccessModifierType.ProtectedAndInternal); } else { return(actualAccess); } } else { return(AccessModifierType.Private); } }
/// <summary> /// Initializes a new instance of the Declaration class. /// </summary> /// <param name="tokens"> /// The array of tokens that make up the declaration. /// </param> /// <param name="name"> /// The name of the element. /// </param> /// <param name="elementType"> /// The type of the element. /// </param> /// <param name="accessModifierType"> /// The access type of the element. /// </param> internal Declaration(CsTokenList tokens, string name, ElementType elementType, AccessModifierType accessModifierType) : this(tokens, name, elementType, accessModifierType, new Dictionary <CsTokenType, CsToken>(0)) { Param.Ignore(tokens, name, elementType, accessModifierType); }
/// <summary> /// Gets the modifiers from an element's declaration. /// </summary> /// <param name="elementReference">A reference to the element being created.</param> /// <param name="accessModifier">Returns the access modifier type for the element.</param> /// <param name="allowedModifiers">The list of keyword modifiers allowed on the element.</param> /// <returns>Returns the collection of modifiers.</returns> private Dictionary<CsTokenType, CsToken> GetElementModifiers( Reference<ICodePart> elementReference, ref AccessModifierType accessModifier, string[] allowedModifiers) { Param.AssertNotNull(elementReference, "elementReference"); Param.Ignore(accessModifier); Param.Ignore(allowedModifiers); Symbol accessModifierSeen = null; Dictionary<CsTokenType, CsToken> modifiers = new Dictionary<CsTokenType, CsToken>(); Symbol symbol = this.GetNextSymbol(elementReference); while (true) { if (symbol.SymbolType == SymbolType.Public) { // A public access modifier can only be specified if there have been no other access modifiers. if (accessModifierSeen != null) { throw this.CreateSyntaxException(); } accessModifier = AccessModifierType.Public; accessModifierSeen = symbol; CsToken token = this.GetToken(CsTokenType.Public, SymbolType.Public, elementReference); this.tokens.Add(token); modifiers.Add(CsTokenType.Public, token); } else if (symbol.SymbolType == SymbolType.Private) { // A private access modifier can only be specified if there have been no other access modifiers. if (accessModifierSeen != null) { throw this.CreateSyntaxException(); } accessModifier = AccessModifierType.Private; accessModifierSeen = symbol; CsToken token = this.GetToken(CsTokenType.Private, SymbolType.Private, elementReference); this.tokens.Add(token); modifiers.Add(CsTokenType.Private, token); } else if (symbol.SymbolType == SymbolType.Internal) { // The access is internal unless we have already seen a protected access // modifier, in which case it is protected internal. if (accessModifierSeen == null) { accessModifier = AccessModifierType.Internal; } else if (accessModifierSeen.SymbolType == SymbolType.Protected) { accessModifier = AccessModifierType.ProtectedInternal; } else { throw this.CreateSyntaxException(); } accessModifierSeen = symbol; CsToken token = this.GetToken(CsTokenType.Internal, SymbolType.Internal, elementReference); this.tokens.Add(token); modifiers.Add(CsTokenType.Internal, token); } else if (symbol.SymbolType == SymbolType.Protected) { // The access is protected unless we have already seen an internal access // modifier, in which case it is protected internal. if (accessModifierSeen == null) { accessModifier = AccessModifierType.Protected; } else if (accessModifierSeen.SymbolType == SymbolType.Internal) { accessModifier = AccessModifierType.ProtectedInternal; } else { throw this.CreateSyntaxException(); } accessModifierSeen = symbol; CsToken token = this.GetToken(CsTokenType.Protected, SymbolType.Protected, elementReference); this.tokens.Add(token); modifiers.Add(CsTokenType.Protected, token); } else { if (!this.GetOtherElementModifier(elementReference, allowedModifiers, modifiers, symbol)) { break; } } symbol = this.GetNextSymbol(elementReference); } return modifiers; }
/// <summary> /// The save. /// </summary> /// <param name="accessModifierType"> /// The access modifier type. /// </param> private void Save(AccessModifierType accessModifierType) { if (this.ClassContext.IsInterface) { return; } switch (accessModifierType) { case AccessModifierType.Internal: this.headerWriter.Write("internal"); break; case AccessModifierType.Private: this.headerWriter.Write("private"); break; case AccessModifierType.Protected: this.headerWriter.Write("protected"); break; case AccessModifierType.ProtectedAndInternal: this.headerWriter.Write("protected"); break; case AccessModifierType.ProtectedInternal: this.headerWriter.Write("protected"); break; case AccessModifierType.Public: this.headerWriter.Write("public"); break; default: this.headerWriter.Write("private"); break; } }
/// <summary> /// Merges the access of this element with the access of its parent to determine /// the actual visibility of this item outside of the class. /// </summary> /// <param name="parentAccess"> /// The parent's actual access type. /// </param> private void MergeAccess(AccessModifierType parentAccess) { Param.Ignore(parentAccess); AccessModifierType access = this.declaration.AccessModifierType; if (parentAccess == AccessModifierType.Public) { this.actualAccess = access; } else if (parentAccess == AccessModifierType.ProtectedInternal) { if (access == AccessModifierType.Public) { this.actualAccess = AccessModifierType.ProtectedInternal; } else { this.actualAccess = access; } } else if (parentAccess == AccessModifierType.Protected) { if (access == AccessModifierType.Public || access == AccessModifierType.ProtectedInternal) { this.actualAccess = AccessModifierType.Protected; } else if (access == AccessModifierType.Internal) { this.actualAccess = AccessModifierType.ProtectedAndInternal; } else { this.actualAccess = access; } } else if (parentAccess == AccessModifierType.Internal) { if (access == AccessModifierType.Public || access == AccessModifierType.ProtectedInternal) { this.actualAccess = AccessModifierType.Internal; } else if (access == AccessModifierType.Protected) { this.actualAccess = AccessModifierType.ProtectedAndInternal; } else { this.actualAccess = access; } } else if (parentAccess == AccessModifierType.ProtectedAndInternal) { if (access == AccessModifierType.Public || access == AccessModifierType.ProtectedInternal || access == AccessModifierType.Protected || access == AccessModifierType.Internal) { this.actualAccess = AccessModifierType.ProtectedAndInternal; } else { this.actualAccess = access; } } else { this.actualAccess = AccessModifierType.Private; } }
private Dictionary<CsTokenType, CsToken> GetElementModifiers(ref AccessModifierType accessModifier, string[] allowedModifiers) { Symbol symbol = null; Dictionary<CsTokenType, CsToken> modifiers = new Dictionary<CsTokenType, CsToken>(); Symbol nextSymbol = this.GetNextSymbol(); while (true) { if (nextSymbol.SymbolType == SymbolType.Public) { if (symbol != null) { throw this.CreateSyntaxException(); } accessModifier = AccessModifierType.Public; symbol = nextSymbol; CsToken item = this.GetToken(CsTokenType.Public, SymbolType.Public); this.tokens.Add(item); modifiers.Add(CsTokenType.Public, item); } else if (nextSymbol.SymbolType == SymbolType.Private) { if (symbol != null) { throw this.CreateSyntaxException(); } accessModifier = AccessModifierType.Private; symbol = nextSymbol; CsToken token = this.GetToken(CsTokenType.Private, SymbolType.Private); this.tokens.Add(token); modifiers.Add(CsTokenType.Private, token); } else if (nextSymbol.SymbolType == SymbolType.Internal) { if (symbol == null) { accessModifier = AccessModifierType.Internal; } else { if (symbol.SymbolType != SymbolType.Protected) { throw this.CreateSyntaxException(); } accessModifier = AccessModifierType.ProtectedInternal; } symbol = nextSymbol; CsToken token3 = this.GetToken(CsTokenType.Internal, SymbolType.Internal); this.tokens.Add(token3); modifiers.Add(CsTokenType.Internal, token3); } else if (nextSymbol.SymbolType == SymbolType.Protected) { if (symbol == null) { accessModifier = AccessModifierType.Protected; } else { if (symbol.SymbolType != SymbolType.Internal) { throw this.CreateSyntaxException(); } accessModifier = AccessModifierType.ProtectedInternal; } symbol = nextSymbol; CsToken token4 = this.GetToken(CsTokenType.Protected, SymbolType.Protected); this.tokens.Add(token4); modifiers.Add(CsTokenType.Protected, token4); } else if (!this.GetOtherElementModifier(allowedModifiers, modifiers, nextSymbol)) { return modifiers; } nextSymbol = this.GetNextSymbol(); } }
/// <summary> /// Converts an access modifier type to a human readable string. /// </summary> /// <param name="type">The type to convert.</param> /// <returns>Returns the human readable string.</returns> private static string AccessModifierTypeString(AccessModifierType type) { Param.Ignore(type); switch (type) { case AccessModifierType.Public: return "public"; case AccessModifierType.Internal: return "internal"; case AccessModifierType.Protected: return "protected"; case AccessModifierType.Private: return "private"; case AccessModifierType.ProtectedInternal: return "protected internal"; default: Debug.Fail("Unexpected access modifier keyword"); throw new InvalidOperationException(); } }