static ITypeParameter ResolveBaseTypeParameter(IMethod parentMethod, int index) { IMethod baseMethod = null; if (parentMethod.IsOverride) { foreach (IMethod m in InheritanceHelper.GetBaseMembers(parentMethod, false).OfType <IMethod>()) { if (!m.IsOverride) { baseMethod = m; break; } } } else if (parentMethod.IsExplicitInterfaceImplementation && parentMethod.ImplementedInterfaceMembers.Count == 1) { baseMethod = parentMethod.ImplementedInterfaceMembers[0] as IMethod; } if (baseMethod != null && index < baseMethod.TypeParameters.Count) { return(baseMethod.TypeParameters[index]); } else { return(null); } }
Accessibility ComputeAccessibility() { if (IsOverride && (getter == null || setter == null)) { // Overrides may override only one of the accessors, hence calculating the accessibility from // the declared accessors is not sufficient. We need to "copy" accessibility from the baseMember. foreach (var baseMember in InheritanceHelper.GetBaseMembers(this, includeImplementedInterfaces: false)) { if (!baseMember.IsOverride) { // See https://github.com/icsharpcode/ILSpy/issues/2653 // "protected internal" (ProtectedOrInternal) accessibility is "reduced" // to "protected" accessibility across assembly boundaries. if (baseMember.Accessibility == Accessibility.ProtectedOrInternal && this.ParentModule?.PEFile != baseMember.ParentModule?.PEFile) { return(Accessibility.Protected); } else { return(baseMember.Accessibility); } } } } return(AccessibilityExtensions.Union( this.Getter?.Accessibility ?? Accessibility.None, this.Setter?.Accessibility ?? Accessibility.None)); }
IList <IMember> FindImplementedInterfaceMembers() { if (unresolved.IsExplicitInterfaceImplementation) { List <IMember> result = new List <IMember>(); foreach (var memberReference in unresolved.ExplicitInterfaceImplementations) { IMember member = memberReference.Resolve(context); if (member != null) { result.Add(member); } } return(result.ToArray()); } else if (unresolved.IsStatic) { return(EmptyList <IMember> .Instance); } else { // TODO: implement interface member mappings correctly return(InheritanceHelper.GetBaseMembers(this, true) .Where(m => m.DeclaringTypeDefinition != null && m.DeclaringTypeDefinition.Kind == TypeKind.Interface) .ToArray()); } }
static ObservableCollection <ContextActionViewModel> BuildBaseMemberListViewModel(IMember member) { var c = new ObservableCollection <ContextActionViewModel>(); ObservableCollection <ContextActionViewModel> lastBase = c; IMember thisMember = member; while (thisMember != null) { IMember baseMember = InheritanceHelper.GetBaseMembers(thisMember, true).FirstOrDefault(); if (baseMember != null) { // Only allow this base member, if overriding a virtual/abstract member of a class // or implementing a member of an interface. if ((baseMember.DeclaringTypeDefinition.Kind == TypeKind.Interface) || (baseMember.IsOverridable && thisMember.IsOverride)) { var newChild = new ObservableCollection <ContextActionViewModel>(); lastBase.Add(GoToEntityAction.MakeViewModel(baseMember, newChild)); lastBase = newChild; } else { thisMember = null; } } thisMember = baseMember; } return(c); }
/// <summary> /// Gets the XML documentation element for the specified entity. /// Returns null if no documentation is found. /// </summary> public static XmlDocumentationElement Get(IEntity entity, bool inheritDocIfMissing = true) { var documentationComment = entity.Documentation; if (documentationComment != null) { return(Create(documentationComment, entity)); } IMember member = entity as IMember; if (inheritDocIfMissing && member != null) { if (member.SymbolKind == SymbolKind.Constructor) { // For constructors, the documentation of the base class ctor // isn't really suitable as constructors are not inherited. // We'll use the type's documentation instead: return(Get(entity.DeclaringTypeDefinition, inheritDocIfMissing)); } foreach (IMember baseMember in InheritanceHelper.GetBaseMembers(member, includeImplementedInterfaces: true)) { documentationComment = baseMember.Documentation; if (documentationComment != null) { return(Create(documentationComment, baseMember)); } } } return(null); }
IEnumerable <IEntity> AnalyzeType(IProperty analyzedEntity, ITypeDefinition type) { var token = analyzedEntity.MetadataToken; var declaringTypeToken = analyzedEntity.DeclaringTypeDefinition.MetadataToken; var module = analyzedEntity.DeclaringTypeDefinition.ParentModule.PEFile; var allTypes = type.GetAllBaseTypeDefinitions(); if (!allTypes.Any(t => t.MetadataToken == declaringTypeToken && t.ParentModule.PEFile == module)) { yield break; } foreach (var property in type.Properties) { if (!property.IsOverride) { continue; } var baseMembers = InheritanceHelper.GetBaseMembers(property, false); if (baseMembers.Any(p => p.MetadataToken == token && p.ParentModule.PEFile == module)) { yield return(property); } } }
public HasMemberCriterion(IMember neededMember) { // this.neededMember = neededMember; if (neededMember.ImplementedInterfaceMembers.Any()) { acceptableMembers = neededMember.ImplementedInterfaceMembers.ToList(); } else if (neededMember.IsOverride) { acceptableMembers = new List <IMember>(); foreach (var member in InheritanceHelper.GetBaseMembers(neededMember, true)) { acceptableMembers.Add(member); if (member.IsShadowing) { break; } } acceptableMembers.Add(neededMember); } else { acceptableMembers = new List <IMember> { neededMember }; } }
bool IsAppropriateCallTarget(ExpectedTargetDetails expectedTargetDetails, IMember expectedTarget, IMember actualTarget) { if (expectedTarget.Equals(actualTarget)) { return(true); } if (expectedTargetDetails.CallOpCode == OpCode.CallVirt && actualTarget.IsOverride) { if (expectedTargetDetails.NeedsBoxingConversion && actualTarget.DeclaringType.IsReferenceType != true) { return(false); } foreach (var possibleTarget in InheritanceHelper.GetBaseMembers(actualTarget, false)) { if (expectedTarget.Equals(possibleTarget)) { return(true); } if (!possibleTarget.IsOverride) { break; } } } return(false); }
public IEnumerable <ISymbol> Analyze(ISymbol analyzedSymbol, AnalyzerContext context) { Debug.Assert(analyzedSymbol is IMember); var member = (IMember)analyzedSymbol; Debug.Assert(!member.IsStatic); var baseMembers = InheritanceHelper.GetBaseMembers(member, includeImplementedInterfaces: true); return(baseMembers.Where(m => m.DeclaringTypeDefinition.Kind == TypeKind.Interface)); }
bool IsInactiveConditionalMethod(IParameterizedMember member) { if (member.SymbolKind != SymbolKind.Method || member.ReturnType.Kind != TypeKind.Void) { return(false); } foreach (var baseMember in InheritanceHelper.GetBaseMembers(member, false)) { if (IsInactiveConditional(baseMember.Attributes)) { return(true); } } return(IsInactiveConditional(member.Attributes)); }
public IMember FindBaseMembers() { var result = InheritanceHelper.GetBaseMembers(this, false); //var result = bm // .Where(m => m.DeclaringTypeDefinition != null && m.DeclaringTypeDefinition.Kind == TypeKind.Class) // .ToArray(); ////IEnumerable<IMember> otherMembers = DeclaringTypeDefinition.Members; ////if (SymbolKind == SymbolKind.Accessor) //// otherMembers = DeclaringTypeDefinition.GetAccessors(options: GetMemberOptions.IgnoreInheritedMembers); ////result = result.Where(item => !otherMembers.Any(m => m.IsExplicitInterfaceImplementation && m.ImplementedInterfaceMembers.Contains(item))).ToArray(); return(result.FirstOrDefault()); }
Accessibility ComputeAccessibility() { var baseAcc = base.Accessibility; if (IsOverride && !(CanGet && CanSet)) { foreach (var baseMember in InheritanceHelper.GetBaseMembers(this, false)) { if (!baseMember.IsOverride) { return(baseMember.Accessibility); } } } return(baseAcc); }
Accessibility ComputeAccessibility() { if (IsOverride && (getter == null || setter == null)) { foreach (var baseMember in InheritanceHelper.GetBaseMembers(this, includeImplementedInterfaces: false)) { if (!baseMember.IsOverride) { return(baseMember.Accessibility); } } } return(AccessibilityExtensions.Union( this.Getter?.Accessibility ?? Accessibility.None, this.Setter?.Accessibility ?? Accessibility.None)); }
public override void VisitInvocationExpression(InvocationExpression invocationExpression) { base.VisitInvocationExpression(invocationExpression); var mr = invocationExpression.Target as MemberReferenceExpression; if (mr == null || !(mr.Target is BaseReferenceExpression)) { return; } var invocationRR = ctx.Resolve(invocationExpression) as InvocationResolveResult; if (invocationRR == null) { return; } var parentEntity = invocationExpression.GetParent <EntityDeclaration>(); if (parentEntity == null) { return; } var rr = ctx.Resolve(parentEntity) as MemberResolveResult; if (rr == null) { return; } if (invocationExpression.Arguments.Count >= invocationRR.Member.Parameters.Count || invocationRR.Member.Parameters.Count == 0 || !invocationRR.Member.Parameters.Last().IsOptional) { return; } if (!InheritanceHelper.GetBaseMembers(rr.Member, false).Any(m => m == invocationRR.Member)) { return; } AddIssue(new CodeIssue( invocationExpression.RParToken, ctx.TranslateString("Call to base member with implicit default parameters") )); }
public IEnumerable <IMember> GetOverridableMembers() { // Disallow trying to override in e.g. interfaces or enums if (this.CurrentType.Kind != TypeKind.Class && this.CurrentType.Kind != TypeKind.Struct) { return(new IMember[0]); } var candidates = this.CurrentType .GetMembers(m => (m.IsVirtual || m.IsAbstract) && m.IsOverridable).ToArray(); var overridden = this.CurrentType .GetMembers(m => m.IsOverride && m.DeclaringTypeDefinition == currentTypeDefinition) .SelectMany(m => InheritanceHelper.GetBaseMembers(m, true)); return(candidates.Except(overridden)); }
void VisitParameterizedEntityDeclaration(string memberType, EntityDeclaration entityDeclaration, AstNodeCollection <ParameterDeclaration> parameters) { // Ignore explicit interface implementations (those should have no optional parameters as there can't be any direct calls) if (!entityDeclaration.GetChildByRole(EntityDeclaration.PrivateImplementationTypeRole).IsNull) { return; } //Override is not strictly necessary because methodDeclaration //might still implement an interface member var memberResolveResult = ctx.Resolve(entityDeclaration) as MemberResolveResult; if (memberResolveResult == null) { return; } var member = (IParameterizedMember)memberResolveResult.Member; var baseMembers = InheritanceHelper.GetBaseMembers(member, true).ToList(); foreach (IParameterizedMember baseMember in baseMembers) { if (baseMember.IsOverride || baseMember.DeclaringType.Kind == TypeKind.Interface) { continue; } CompareMethods(memberType, parameters, member, baseMember); return; } // only check 1 interface method -> multiple interface implementations could lead to deault value conflicts // possible other solutions: Skip the interface check entirely var interfaceBaseMethods = baseMembers.Where(b => b.DeclaringType.Kind == TypeKind.Interface).ToList(); if (interfaceBaseMethods.Count == 1) { foreach (IParameterizedMember baseMember in interfaceBaseMethods) { if (baseMember.DeclaringType.Kind == TypeKind.Interface) { CompareMethods(memberType, parameters, member, baseMember); } } } }
IEnumerable <IEntity> AnalyzeType(IEvent analyzedEntity, ITypeDefinition type) { var token = analyzedEntity.DeclaringTypeDefinition.MetadataToken; var module = analyzedEntity.DeclaringTypeDefinition.ParentModule.PEFile; if (!type.GetAllBaseTypeDefinitions() .Any(t => t.MetadataToken == token && t.ParentModule.PEFile == module)) { yield break; } foreach (var @event in type.GetEvents(options: GetMemberOptions.ReturnMemberDefinitions)) { if (InheritanceHelper.GetBaseMembers(@event, true) .Any(m => m.DeclaringTypeDefinition.MetadataToken == token && m.ParentModule.PEFile == module)) { yield return(@event); } } }
IEnumerable <IEntity> AnalyzeType(IMethod analyzedEntity, ITypeDefinition type) { var token = analyzedEntity.MetadataToken; var declaringTypeToken = analyzedEntity.DeclaringTypeDefinition.MetadataToken; var module = analyzedEntity.DeclaringTypeDefinition.ParentModule.PEFile; var allTypes = type.GetAllBaseTypeDefinitions(); if (!allTypes.Any(t => t.MetadataToken == declaringTypeToken && t.ParentModule.PEFile == module)) { yield break; } foreach (var method in type.Methods) { var baseMembers = InheritanceHelper.GetBaseMembers(method, true); if (baseMembers.Any(m => m.MetadataToken == token && m.ParentModule.PEFile == module)) { yield return(method); } } }
IEnumerable <IEntity> AnalyzeType(IEvent analyzedEntity, ITypeDefinition type) { if (!analyzedEntity.DeclaringType.GetAllBaseTypeDefinitions() .Any(t => t.MetadataToken == analyzedEntity.DeclaringTypeDefinition.MetadataToken && t.ParentModule.PEFile == type.ParentModule.PEFile)) { yield break; } foreach (var @event in type.Events) { if ([email protected]) { continue; } if (InheritanceHelper.GetBaseMembers(@event, false) .Any(p => p.MetadataToken == analyzedEntity.MetadataToken && p.ParentModule.PEFile == analyzedEntity.ParentModule.PEFile)) { yield return(@event); } } }
bool IsAppropriateCallTarget(IMember expectedTarget, IMember actualTarget, bool isVirtCall) { if (expectedTarget.Equals(actualTarget)) { return(true); } if (isVirtCall && actualTarget.IsOverride) { foreach (var possibleTarget in InheritanceHelper.GetBaseMembers(actualTarget, false)) { if (expectedTarget.Equals(possibleTarget)) { return(true); } if (!possibleTarget.IsOverride) { break; } } } return(false); }
/// <summary> /// Gets the XML documentation element for the specified entity. /// Returns null if no documentation is found. /// </summary> public static XmlDocumentationElement Get(IEntity entity, bool inheritDocIfMissing = true) { var documentationComment = entity.Documentation; if (documentationComment != null) { return(Create(documentationComment, entity)); } IMember member = entity as IMember; if (inheritDocIfMissing && member != null) { foreach (IMember baseMember in InheritanceHelper.GetBaseMembers(member, includeImplementedInterfaces: true)) { documentationComment = baseMember.Documentation; if (documentationComment != null) { return(Create(documentationComment, baseMember)); } } } return(null); }
IList <IMember> FindImplementedInterfaceMembers() { if (unresolved.IsExplicitInterfaceImplementation) { List <IMember> result = new List <IMember>(); foreach (var memberReference in unresolved.ExplicitInterfaceImplementations) { IMember member = memberReference.Resolve(context); if (member != null) { result.Add(member); } } return(result.ToArray()); } else if (unresolved.IsStatic || !unresolved.IsPublic || DeclaringTypeDefinition == null || DeclaringTypeDefinition.Kind == TypeKind.Interface) { return(EmptyList <IMember> .Instance); } else { // TODO: implement interface member mappings correctly var result = InheritanceHelper.GetBaseMembers(this, true) .Where(m => m.DeclaringTypeDefinition != null && m.DeclaringTypeDefinition.Kind == TypeKind.Interface) .ToArray(); IEnumerable <IMember> otherMembers = DeclaringTypeDefinition.Members; if (SymbolKind == SymbolKind.Accessor) { otherMembers = DeclaringTypeDefinition.GetAccessors(options: GetMemberOptions.IgnoreInheritedMembers); } result = result.Where(item => !otherMembers.Any(m => m.IsExplicitInterfaceImplementation && m.ImplementedInterfaceMembers.Contains(item))).ToArray(); return(result); } }
static List <XmlDocumentationElement> CreateElements(IEnumerable <XObject?> childObjects, IEntity?declaringEntity, Func <string, IEntity?>?crefResolver, int nestingLevel) { List <XmlDocumentationElement> list = new List <XmlDocumentationElement>(); foreach (var child in childObjects) { var childText = child as XText; var childTag = child as XCData; var childElement = child as XElement; if (childText != null) { list.Add(new XmlDocumentationElement(childText.Value, declaringEntity)); } else if (childTag != null) { list.Add(new XmlDocumentationElement(childTag.Value, declaringEntity)); } else if (childElement != null) { if (nestingLevel < 5 && childElement.Name == "inheritdoc") { string? cref = childElement.Attribute("cref")?.Value; IEntity?inheritedFrom = null; string? inheritedDocumentation = null; if (cref != null && crefResolver != null) { inheritedFrom = crefResolver(cref); if (inheritedFrom != null) { inheritedDocumentation = "<doc>" + inheritedFrom.GetDocumentation() + "</doc>"; } } else { foreach (IMember baseMember in InheritanceHelper.GetBaseMembers((IMember?)declaringEntity, includeImplementedInterfaces: true)) { inheritedDocumentation = baseMember.GetDocumentation(); if (inheritedDocumentation != null) { inheritedFrom = baseMember; inheritedDocumentation = "<doc>" + inheritedDocumentation + "</doc>"; break; } } } if (inheritedDocumentation != null) { var doc = XDocument.Parse(inheritedDocumentation).Element("doc"); // XPath filter not yet implemented if (childElement.Parent?.Parent == null && childElement.Attribute("select")?.Value == null) { // Inheriting documentation at the root level List <string> doNotInherit = new List <string>(); doNotInherit.Add("overloads"); doNotInherit.AddRange(childObjects.OfType <XElement>().Select(e => e.Name.LocalName).Intersect( doNotInheritIfAlreadyPresent)); var inheritedChildren = doc.Nodes().Where( inheritedObject => { XElement?inheritedElement = inheritedObject as XElement; return(!(inheritedElement != null && doNotInherit.Contains(inheritedElement.Name.LocalName))); }); list.AddRange(CreateElements(inheritedChildren, inheritedFrom, crefResolver, nestingLevel + 1)); } } } else { list.Add(new XmlDocumentationElement(childElement, declaringEntity, crefResolver) { nestingLevel = nestingLevel }); } } } if (list.Count > 0 && list[0].IsTextNode) { if (string.IsNullOrWhiteSpace(list[0].textContent)) { list.RemoveAt(0); } else { list[0].textContent = list[0].textContent !.TrimStart(); } } if (list.Count > 0 && list[list.Count - 1].IsTextNode) { if (string.IsNullOrWhiteSpace(list[list.Count - 1].textContent)) { list.RemoveAt(list.Count - 1); } else { list[list.Count - 1].textContent = list[list.Count - 1].textContent !.TrimEnd(); } } return(list); }
static List <XmlDocumentationElement> CreateElements(IEnumerable <AXmlObject> childObjects, IEntity declaringEntity, Func <string, IEntity> crefResolver, int nestingLevel) { List <XmlDocumentationElement> list = new List <XmlDocumentationElement>(); foreach (var child in childObjects) { var childText = child as AXmlText; var childTag = child as AXmlTag; var childElement = child as AXmlElement; if (childText != null) { list.Add(new XmlDocumentationElement(childText.Value, declaringEntity)); } else if (childTag != null && childTag.IsCData) { foreach (var text in childTag.Children.OfType <AXmlText>()) { list.Add(new XmlDocumentationElement(text.Value, declaringEntity)); } } else if (childElement != null) { if (nestingLevel < 5 && childElement.Name == "inheritdoc") { string cref = childElement.GetAttributeValue("cref"); IEntity inheritedFrom = null; DocumentationComment inheritedDocumentation = null; if (cref != null) { inheritedFrom = crefResolver(cref); if (inheritedFrom != null) { inheritedDocumentation = inheritedFrom.Documentation; } } else { foreach (IMember baseMember in InheritanceHelper.GetBaseMembers((IMember)declaringEntity, includeImplementedInterfaces: true)) { inheritedDocumentation = baseMember.Documentation; if (inheritedDocumentation != null) { inheritedFrom = baseMember; break; } } } if (inheritedDocumentation != null) { var doc = new AXmlParser().Parse(inheritedDocumentation.Xml); // XPath filter not yet implemented if (childElement.Parent is AXmlDocument && childElement.GetAttributeValue("select") == null) { // Inheriting documentation at the root level List <string> doNotInherit = new List <string>(); doNotInherit.Add("overloads"); doNotInherit.AddRange(childObjects.OfType <AXmlElement>().Select(e => e.Name).Intersect( doNotInheritIfAlreadyPresent)); var inheritedChildren = doc.Children.Where( inheritedObject => { AXmlElement inheritedElement = inheritedObject as AXmlElement; return(!(inheritedElement != null && doNotInherit.Contains(inheritedElement.Name))); }); list.AddRange(CreateElements(inheritedChildren, inheritedFrom, inheritedDocumentation.ResolveCref, nestingLevel + 1)); } } } else { list.Add(new XmlDocumentationElement(childElement, declaringEntity, crefResolver) { nestingLevel = nestingLevel }); } } } if (list.Count > 0 && list[0].IsTextNode) { if (string.IsNullOrWhiteSpace(list[0].textContent)) { list.RemoveAt(0); } else { list[0].textContent = list[0].textContent.TrimStart(); } } if (list.Count > 0 && list[list.Count - 1].IsTextNode) { if (string.IsNullOrWhiteSpace(list[list.Count - 1].textContent)) { list.RemoveAt(list.Count - 1); } else { list[list.Count - 1].textContent = list[list.Count - 1].textContent.TrimEnd(); } } return(list); }