void CheckAttribute(FileDiagnostics diagnostics, Token attribute, AttributeType type) { if (attribute == null) { return; } var newAttribute = new AttributeContext(attribute, type); // If the attribute already exists, syntax error. bool wasCopy = false; for (int c = 0; c < ObtainedAttributes.Count; c++) { if (ObtainedAttributes[c].Type == newAttribute.Type) { newAttribute.Copy(diagnostics); wasCopy = true; break; } } // Add the attribute. ObtainedAttributes.Add(newAttribute); // Additonal syntax errors. Only throw if the attribute is not a copy. if (!wasCopy && ApplyAttributes.Apply(diagnostics, newAttribute)) { ValidateAttribute(diagnostics, newAttribute); } }
private void ValidateAttribute(FileDiagnostics diagnostics, AttributeContext newAttribute) { // Virtual attribute on a static method (static attribute was first.) if (IsAttribute(AttributeType.Static) && newAttribute.Type == AttributeType.Virtual) { diagnostics.Error("Static methods cannot be virtual.", newAttribute.Range); } // Static attribute on a virtual method (virtual attribute was first.) if (IsAttribute(AttributeType.Virtual) && newAttribute.Type == AttributeType.Static) { diagnostics.Error("Virtual methods cannot be static.", newAttribute.Range); } }
public bool Apply(FileDiagnostics diagnostics, AttributeContext attribute) { if (_disallowedAttributes.Contains(attribute.Type)) { diagnostics.Error("The '" + attribute.Type.ToString().ToLower() + "' attribute is not allowed.", attribute.Range); return(false); } // Apply the attribute. switch (attribute.Type) { // Accessors case AttributeType.Public: Accessor = AccessLevel.Public; break; case AttributeType.Protected: Accessor = AccessLevel.Protected; break; case AttributeType.Private: Accessor = AccessLevel.Private; break; // Apply static case AttributeType.Static: IsStatic = true; break; // Apply virtual case AttributeType.Virtual: IsVirtual = true; break; // Apply override case AttributeType.Override: IsOverride = true; break; // Apply Recursive case AttributeType.Recursive: IsRecursive = true; break; // Apply Variables default: throw new NotImplementedException(); } return(true); }