public bool IsOfType(IObjectSpecImmutable specification) { if (specification == this) { return(true); } if (Interfaces.Any(interfaceSpec => interfaceSpec.IsOfType(specification))) { return(true); } // match covariant generic types if (Type.IsGenericType && IsCollection) { Type otherType = specification.Type; if (otherType.IsGenericType && Type.GetGenericArguments().Count() == 1 && otherType.GetGenericArguments().Count() == 1) { if (Type.GetGenericTypeDefinition() == (typeof(IQueryable <>)) && Type.GetGenericTypeDefinition() == otherType.GetGenericTypeDefinition()) { Type genericArgument = Type.GetGenericArguments().Single(); Type otherGenericArgument = otherType.GetGenericArguments().Single(); Type otherGenericParameter = otherType.GetGenericTypeDefinition().GetGenericArguments().Single(); if ((otherGenericParameter.GenericParameterAttributes & GenericParameterAttributes.Covariant) != 0) { if (otherGenericArgument.IsAssignableFrom(genericArgument)) { return(true); } } } } } return(Superclass != null && Superclass.IsOfType(specification)); }
/// <summary> /// Filters <see cref="Type"/>s based on the interfaces they implement. /// </summary> /// <param name="type">The <see cref="Type"/> to filter.</param> /// <param name="mustBeRequired">This check will only be performed with this argument matches the value of the /// <see cref="RequireInterfaces"/> property.</param> /// <returns>True if the <paramref name="type"/> should be included; false if it was filtered out.</returns> /// <exception cref="TypeFilterException"><paramref name="mustBeRequired"/> is true, <see cref="RequireInterfaces"/> /// is true, and the <paramref name="type"/> does not implement the required <see cref="Interfaces"/>.</exception> bool FilterInterfaces(Type type, bool mustBeRequired) { if (mustBeRequired != RequireInterfaces) { return(true); } if (Interfaces == null || Interfaces.IsEmpty()) { return(true); } var i = type.GetInterfaces(); var isValid = (MatchAllInterfaces ? Interfaces.All(i.Contains) : Interfaces.Any(i.Contains)); if (!isValid) { if (RequireInterfaces) { const string errmsg = "Type `{0}` does not have the required interfaces: `{1}`."; var err = string.Format(errmsg, type, GetTypeString(Interfaces)); if (log.IsFatalEnabled) { log.Fatal(err); } throw new TypeFilterException(err); } else { return(false); } } return(true); }
public TypeHierarchyItem LoadInterfaceHierarchy() { var interfaceRoot = new TypeHierarchyItem(null); if (Interfaces.Any()) { var rootInterfaces = new List <TypeHierarchyItem>(); for (int i = Interfaces.Length - 1; i >= 0; i--) { if (IsRootInterface(Interfaces[i].Symbol)) { rootInterfaces.Add(Interfaces[i]); } } FillHierarchyItems(rootInterfaces, interfaceRoot, FillHierarchyItem); } return(interfaceRoot); bool IsRootInterface(INamedTypeSymbol interfaceSymbol) { foreach (INamedTypeSymbol interfaceSymbol2 in interfaceSymbol.Interfaces) { foreach (TypeHierarchyItem interfaceItem in Interfaces) { if (interfaceItem.Symbol == interfaceSymbol2) { return(false); } } } return(true); } TypeHierarchyItem FillHierarchyItem(TypeHierarchyItem item, TypeHierarchyItem parent) { INamedTypeSymbol symbol = item.Symbol; item = new TypeHierarchyItem(symbol) { Parent = parent }; TypeHierarchyItem[] derivedInterfaces = Interfaces .Where(f => f.Symbol.Interfaces.Any(i => MetadataNameEqualityComparer <INamedTypeSymbol> .Instance.Equals(i.OriginalDefinition, symbol.OriginalDefinition))) .ToArray(); if (derivedInterfaces.Length > 0) { Array.Reverse(derivedInterfaces); FillHierarchyItems(derivedInterfaces, item, FillHierarchyItem); } return(item); } }
public string ToFinalString() { //string result = String.Format("{0} {1} class {2}", AccessModifier, String.Join(" ", Keywords), Name); string result = AccessModifier; if (Keywords != null && Keywords.Any()) { result += " " + String.Join(" ", Keywords); } result += " " + Type + " " + Name + " "; if (Inheritance != null && Inheritance != "") { result += " : " + Inheritance; } if (Interfaces != null && Interfaces.Any()) { if (Inheritance == null || Inheritance == "") { result += " : "; } else { result += ", "; } result += String.Join(", ", Interfaces); } result += "\n{\n"; if (Properties != null && Properties.Any()) { foreach (var item in Properties) { result += "\t" + item.ToString() + " { get; set; }\n"; } result += "\n"; } if (Methods != null && Methods.Any()) { foreach (var item in Methods) { result += item.ToFinalString() + "\n"; } result += "\n"; } result += "}\n"; return(result); }
private void ReflectOutInterfaces() { //do interfaces if (ShowInterfaces) { Type[] tiArray = TypeInAssembly.GetInterfaces(); foreach (Type ii in tiArray) { Interfaces.Add(ii.Name.ToString()); } } HasInterfaces = Interfaces.Any(); }
/// <summary> /// 文字列取得 /// </summary> /// <param name="index">前スペース数</param> /// <returns>文字列</returns> public override string ToString(int index = 0) { var result = new StringBuilder(); var indexSpace = string.Concat(Enumerable.Repeat(" ", index)); foreach (var comment in Comments) { result.Append(indexSpace); result.AppendLine($"{comment}"); } foreach (var modifier in Modifiers) { result.Append(indexSpace); result.Append($"{modifier} "); } result.Append($"interface {Name}"); // インターフェイス if (Interfaces.Any()) { result.Append(" : "); Interfaces.ForEach(item => { if (Interfaces.IndexOf(item) > 0) { result.Append(", "); } item.ForEach(expression => { result.Append(expression.Name); }); }); } result.AppendLine(); result.Append(indexSpace); result.AppendLine("{"); Members.ForEach(member => result.AppendLine(member.ToString(index + 1))); result.Append(indexSpace); result.AppendLine("}"); return(result.ToString()); }
public bool Implements(Type interfaceType) { return(Interfaces.Any(i => i.Type == interfaceType.FullName)); }
/// <summary> /// Returns whether type implements the given interface or not. /// </summary> public bool HasInterface(Type type) => Interfaces.Any(x => x.IsCompiledType && x.CompiledType == type);
/// <summary> /// Returns whether type implements the given interface or not. /// </summary> public bool HasInterface(HybType type) => Interfaces.Any(x => x == type);
/// <summary> /// Matches all methods that can be overriden (non-static, public or protected, abstract or virtual) /// within this type sub-tree (this type, its base and interfaces) /// with its override. /// Methods without an override are either abstract or a ghost stup has to be synthesized. /// </summary> /// <param name="diagnostics"></param> internal OverrideInfo[] ResolveOverrides(DiagnosticBag diagnostics) { if (_lazyOverrides != null) { // already resolved return(_lazyOverrides); } // inherit abstracts from base type // ignoring System.Object (we don't override its methods from PHP) var overrides = new List <OverrideInfo>(); if (BaseType != null && BaseType.SpecialType != SpecialType.System_Object) { overrides.AddRange(BaseType.ResolveOverrides(diagnostics)); } // collect this type declared methods including synthesized methods var members = this.GetMembers(); // resolve overrides of inherited members for (int i = 0; i < overrides.Count; i++) { var m = overrides[i]; if (m.HasOverride == false) { // update override info of the inherited member overrides[i] = new OverrideInfo(m.Method, OverrideHelper.ResolveMethodImplementation(m.Method, members)); } else { // clear the interface flag of inherited override info m.ImplementsInterface = false; overrides[i] = m; } } // resolve overrides of interface methods foreach (var iface in Interfaces) { // skip interfaces implemented by base type or other interfaces, // we don't want to add redundant override entries: if ((BaseType != null && BaseType.ImplementsInterface(iface)) || Interfaces.Any(x => x != iface && x.ImplementsInterface(iface))) { // iface is already handled within overrides => skip // note: iface can be ignored in metadata at all actually continue; } var iface_abstracts = iface.ResolveOverrides(diagnostics); foreach (var m in iface_abstracts) { if (BaseType != null && m.Method.ContainingType != iface && BaseType.ImplementsInterface(m.Method.ContainingType)) { // iface {m.Method.ContainingType} already handled within overrides => skip continue; } // ignore interface method that is already implemented: if (overrides.Any(o => OverrideHelper.SignaturesMatch(o.Method, m.Method))) { continue; } // add interface member, // resolve its override overrides.Add(new OverrideInfo(m.Method, this.IsInterface ? null : OverrideHelper.ResolveMethodImplementation(m.Method, this)) { ImplementsInterface = true }); } } // add overrideable routines from this type foreach (var s in members) { if (s is MethodSymbol m && m.IsOverrideable()) { overrides.Add(new OverrideInfo(m)); } } // handle unresolved abstracts for (int i = 0; i < overrides.Count; i++) { var m = overrides[i]; if (m.IsUnresolvedAbstract && this is SourceTypeSymbol srct && !this.IsInterface) { if (!this.IsAbstract) { // Class '{0}' doesn't implement abstract method {1}::{2}() diagnostics.Add(DiagnosticBagExtensions.ParserDiagnostic(srct.ContainingFile.SyntaxTree, srct.Syntax.HeadingSpan, Devsense.PHP.Errors.Errors.AbstractMethodNotImplemented, srct.FullName.ToString(), ((IPhpTypeSymbol)m.Method.ContainingType).FullName.ToString(), m.RoutineName)); } else if (m.ImplementsInterface /*&& this.IsAbstract*/) { m.ImplementsInterface = false; var method = m.Method; Debug.Assert(!method.IsStatic); Debug.Assert(method.DeclaredAccessibility != Accessibility.Private); Debug.Assert(method.ContainingType.IsInterface); // Template: abstract function {name}({parameters}) var ghost = new SynthesizedMethodSymbol(this, method.RoutineName, isstatic: false, isvirtual: true, isabstract: true, isfinal: false, returnType: method.ReturnType, accessibility: method.DeclaredAccessibility); ghost.SetParameters(SynthesizedParameterSymbol.Create(ghost, method.Parameters)); //module.SynthesizedManager.AddMethod(this, ghost); // will be added to synthesized manager by FinalizeMethodTable m.Method = ghost; // replace the interface method with synthesized abstract method // update overrides overrides[i] = m; } } } // cache & return return(_lazyOverrides = overrides.ToArray()); }
/// <summary> /// Matches all methods that can be overriden (non-static, public or protected, abstract or virtual) /// within this type sub-tree (this type, its base and interfaces) /// with its override. /// Methods without an override are either abstract or a ghost stup has to be synthesized. /// </summary> /// <param name="diagnostics"></param> internal OverrideInfo[] ResolveOverrides(DiagnosticBag diagnostics) { if (_lazyOverrides != null) { // already resolved return(_lazyOverrides); } // TODO: ignore System.Object ? // inherit abstracts from base type var overrides = new List <OverrideInfo>(); if (BaseType != null) { overrides.AddRange(BaseType.ResolveOverrides(diagnostics)); } // collect this type declared methods including synthesized methods var methods = this.GetMembers().OfType <MethodSymbol>(); var methodslookup = methods.Where(OverrideHelper.CanOverride).ToLookup(m => m.RoutineName); // resolve overrides of inherited members for (int i = 0; i < overrides.Count; i++) { var m = overrides[i]; if (m.HasOverride == false) { // update override info of the inherited member overrides[i] = new OverrideInfo(m.Method, OverrideHelper.ResolveMethodImplementation(m.Method, methodslookup[m.RoutineName])); } else { // clear the interface flag of inherited override info m.ImplementsInterface = false; overrides[i] = m; } } // resolve overrides of interface methods foreach (var iface in Interfaces) { // skip interfaces implemented by base type or other interfaces, // we don't want to add redundant override entries: if ((BaseType != null && BaseType.ImplementsInterface(iface)) || Interfaces.Any(x => x != iface && x.ImplementsInterface(iface))) { // iface is already handled within overrides => skip // note: iface can be ignored in metadata at all actually continue; } var iface_abstracts = iface.ResolveOverrides(diagnostics); foreach (var m in iface_abstracts) { if (BaseType != null && m.Method.ContainingType != iface && BaseType.ImplementsInterface(m.Method.ContainingType)) { // iface {m.Method.ContainingType} already handled within overrides => skip continue; } // add interface member, // resolve its override overrides.Add(new OverrideInfo(m.Method, this.IsInterface ? null : OverrideHelper.ResolveMethodImplementation(m.Method, this)) { ImplementsInterface = true }); } } // add overrideable routines from this type foreach (var m in methods) { if (m.IsOverrideable()) { overrides.Add(new OverrideInfo(m)); } } // report unresolved abstracts if (!this.IsInterface && !this.IsAbstract) { foreach (var m in overrides) { if (m.IsUnresolvedAbstract) { // TODO: diagnostics.Add() } } } // cache & return return(_lazyOverrides = overrides.ToArray()); }
public bool Implements(Type interfaceType) { return(Interfaces.Any(i => i.TypeAsString == interfaceType.GetFullNameWithAssemblyName())); }
/// <summary> /// Matches all methods that can be overriden (non-static, public or protected, abstract or virtual) /// within this type sub-tree (this type, its base and interfaces) /// with its override. /// Methods without an override are either abstract or a ghost stup has to be synthesized. /// </summary> /// <param name="diagnostics"></param> internal OverrideInfo[] ResolveOverrides(DiagnosticBag diagnostics) { if (_lazyOverrides != null) { // already resolved return(_lazyOverrides); } // TODO: ignore System.Object ? // inherit abstracts from base type var overrides = new List <OverrideInfo>(); if (BaseType != null) { overrides.AddRange(BaseType.ResolveOverrides(diagnostics)); } // collect this type declared methods including synthesized methods var methods = this.GetMembers().OfType <MethodSymbol>(); var methodslookup = methods.Where(OverrideHelper.CanOverride).ToLookup(m => m.RoutineName, StringComparer.OrdinalIgnoreCase); // resolve overrides of inherited members for (int i = 0; i < overrides.Count; i++) { var m = overrides[i]; if (m.HasOverride == false) { // update override info of the inherited member overrides[i] = new OverrideInfo(m.Method, OverrideHelper.ResolveMethodImplementation(m.Method, methodslookup[m.RoutineName])); } else { // clear the interface flag of inherited override info m.ImplementsInterface = false; overrides[i] = m; } } // resolve overrides of interface methods foreach (var iface in Interfaces) { // skip interfaces implemented by base type or other interfaces, // we don't want to add redundant override entries: if ((BaseType != null && BaseType.ImplementsInterface(iface)) || Interfaces.Any(x => x != iface && x.ImplementsInterface(iface))) { // iface is already handled within overrides => skip // note: iface can be ignored in metadata at all actually continue; } var iface_abstracts = iface.ResolveOverrides(diagnostics); foreach (var m in iface_abstracts) { if (BaseType != null && m.Method.ContainingType != iface && BaseType.ImplementsInterface(m.Method.ContainingType)) { // iface {m.Method.ContainingType} already handled within overrides => skip continue; } // ignore interface method that is already implemented: if (overrides.Any(o => OverrideHelper.SignaturesMatch(o.Method, m.Method))) { continue; } // add interface member, // resolve its override overrides.Add(new OverrideInfo(m.Method, this.IsInterface ? null : OverrideHelper.ResolveMethodImplementation(m.Method, this)) { ImplementsInterface = true }); } } // add overrideable routines from this type foreach (var m in methods) { if (m.IsOverrideable()) { overrides.Add(new OverrideInfo(m)); } } // report unresolved abstracts if (!this.IsAbstract && !this.IsInterface && this is SourceTypeSymbol srct) { foreach (var m in overrides) { if (m.IsUnresolvedAbstract) { // Class '{0}' doesn't implement abstract method {1}::{2}() diagnostics.Add(DiagnosticBagExtensions.ParserDiagnostic(srct.ContainingFile.SyntaxTree, srct.Syntax.HeadingSpan, Devsense.PHP.Errors.Errors.AbstractMethodNotImplemented, srct.FullName.ToString(), ((IPhpTypeSymbol)m.Method.ContainingType).FullName.ToString(), m.RoutineName)); } } } // cache & return return(_lazyOverrides = overrides.ToArray()); }