From 42639407a0f19b82ca0b62cb7abb510768b284c4 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Thu, 7 Oct 2010 20:02:06 +0200 Subject: [PATCH] Simplify ITypeReference interface; added missing implementations in DefaultTypeDefinition (GetNestedTypes, GetMethod, etc.). --- .../TypeSystem/ConstructedType.cs | 18 +++- .../TypeSystem/EntityType.cs | 1 + ICSharpCode.NRefactory/TypeSystem/IField.cs | 4 +- .../TypeSystem/IParameter.cs | 5 +- ICSharpCode.NRefactory/TypeSystem/IType.cs | 81 +++++++++++++++++ .../TypeSystem/ITypeDefinition.cs | 60 +++++-------- .../TypeSystem/ITypeParameter.cs | 8 ++ .../TypeSystem/ITypeReference.cs | 90 +++---------------- .../TypeSystem/ITypeResolveContext.cs | 10 +-- .../Implementation/AbstractFreezable.cs | 8 ++ .../Implementation/AbstractTypeReference.cs | 32 +------ .../Implementation/DefaultAttribute.cs | 1 - .../Implementation/DefaultParameter.cs | 1 - .../Implementation/DefaultTypeDefinition.cs | 66 ++++++++++++-- .../Implementation/SpecializedMethod.cs | 2 +- .../Implementation/SpecializedProperty.cs | 2 +- 16 files changed, 220 insertions(+), 169 deletions(-) diff --git a/ICSharpCode.NRefactory/TypeSystem/ConstructedType.cs b/ICSharpCode.NRefactory/TypeSystem/ConstructedType.cs index 140a1eae1f..c512224815 100644 --- a/ICSharpCode.NRefactory/TypeSystem/ConstructedType.cs +++ b/ICSharpCode.NRefactory/TypeSystem/ConstructedType.cs @@ -147,7 +147,23 @@ namespace ICSharpCode.NRefactory.TypeSystem public IList GetNestedTypes(ITypeResolveContext context) { - throw new NotImplementedException(); + /* + class Base { + class Nested {} + } + class Derived : Base {} + + Derived.GetNestedTypes() = { Base`1+Nested } + Derived.GetNestedTypes() = { Base`1+Nested } + Base.GetNestedTypes() = { Base`1+Nested } + Base.GetNestedTypes() = { Base`1+Nested } where T2 = copy of T in Base`1+Nested + */ + Substitution substitution = new Substitution(typeArguments); + IList types = genericType.GetNestedTypes(context); + for (int i = 0; i < types.Count; i++) { + types[i] = types[i].AcceptVisitor(substitution); + } + return types; } public IList GetMethods(ITypeResolveContext context) diff --git a/ICSharpCode.NRefactory/TypeSystem/EntityType.cs b/ICSharpCode.NRefactory/TypeSystem/EntityType.cs index d9a4891434..86cb046167 100644 --- a/ICSharpCode.NRefactory/TypeSystem/EntityType.cs +++ b/ICSharpCode.NRefactory/TypeSystem/EntityType.cs @@ -7,6 +7,7 @@ namespace ICSharpCode.NRefactory.TypeSystem { public enum EntityType : byte { + None, TypeDefinition, Field, Property, diff --git a/ICSharpCode.NRefactory/TypeSystem/IField.cs b/ICSharpCode.NRefactory/TypeSystem/IField.cs index 6256461484..bdc87694e9 100644 --- a/ICSharpCode.NRefactory/TypeSystem/IField.cs +++ b/ICSharpCode.NRefactory/TypeSystem/IField.cs @@ -69,11 +69,11 @@ namespace ICSharpCode.NRefactory.TypeSystem } string IVariable.Name { - get { throw new NotImplementedException(); } + get { return null; } } ITypeReference IVariable.Type { - get { throw new NotImplementedException(); } + get { return null; } } } } diff --git a/ICSharpCode.NRefactory/TypeSystem/IParameter.cs b/ICSharpCode.NRefactory/TypeSystem/IParameter.cs index 854901546c..0333a45a94 100644 --- a/ICSharpCode.NRefactory/TypeSystem/IParameter.cs +++ b/ICSharpCode.NRefactory/TypeSystem/IParameter.cs @@ -85,14 +85,11 @@ namespace ICSharpCode.NRefactory.TypeSystem } bool IFreezable.IsFrozen { - get { - throw new NotImplementedException(); - } + get { return false; } } void IFreezable.Freeze() { - throw new NotImplementedException(); } } } diff --git a/ICSharpCode.NRefactory/TypeSystem/IType.cs b/ICSharpCode.NRefactory/TypeSystem/IType.cs index 627cd11fb4..66d07fd915 100644 --- a/ICSharpCode.NRefactory/TypeSystem/IType.cs +++ b/ICSharpCode.NRefactory/TypeSystem/IType.cs @@ -55,6 +55,45 @@ namespace ICSharpCode.NRefactory.TypeSystem /// by the return values of the visit calls. /// IType VisitChildren(TypeVisitor visitor); + + /// + /// Gets the direct base types. + /// + IEnumerable GetBaseTypes(ITypeResolveContext context); + + /// + /// Gets inner classes (including inherited inner classes). + /// + /// + /// If the inner class is generic, this method produces s that + /// parameterize each nested class with its own type parameters. + /// + /// A new mutable list + IList GetNestedTypes(ITypeResolveContext context); + + /// + /// Gets all methods that can be called on this return type. + /// + /// A new mutable list + IList GetMethods(ITypeResolveContext context); + + /// + /// Gets all properties that can be called on this return type. + /// + /// A new mutable list + IList GetProperties(ITypeResolveContext context); + + /// + /// Gets all fields that can be called on this return type. + /// + /// A new mutable list + IList GetFields(ITypeResolveContext context); + + /// + /// Gets all events that can be called on this return type. + /// + /// A new mutable list + IList GetEvents(ITypeResolveContext context); } [ContractClassFor(typeof(IType))] @@ -75,6 +114,48 @@ namespace ICSharpCode.NRefactory.TypeSystem get { return null; } } + IEnumerable IType.GetBaseTypes(ITypeResolveContext context) + { + Contract.Requires(context != null); + Contract.Ensures(Contract.Result>() != null); + return null; + } + + IList IType.GetNestedTypes(ITypeResolveContext context) + { + Contract.Requires(context != null); + Contract.Ensures(Contract.Result>() != null); + return null; + } + + IList IType.GetMethods(ITypeResolveContext context) + { + Contract.Requires(context != null); + Contract.Ensures(Contract.Result>() != null); + return null; + } + + IList IType.GetProperties(ITypeResolveContext context) + { + Contract.Requires(context != null); + Contract.Ensures(Contract.Result>() != null); + return null; + } + + IList IType.GetFields(ITypeResolveContext context) + { + Contract.Requires(context != null); + Contract.Ensures(Contract.Result>() != null); + return null; + } + + IList IType.GetEvents(ITypeResolveContext context) + { + Contract.Requires(context != null); + Contract.Ensures(Contract.Result>() != null); + return null; + } + string INamedElement.FullName { get { Contract.Ensures(Contract.Result() != null); diff --git a/ICSharpCode.NRefactory/TypeSystem/ITypeDefinition.cs b/ICSharpCode.NRefactory/TypeSystem/ITypeDefinition.cs index a70c876fc6..dc8576d8f3 100644 --- a/ICSharpCode.NRefactory/TypeSystem/ITypeDefinition.cs +++ b/ICSharpCode.NRefactory/TypeSystem/ITypeDefinition.cs @@ -121,81 +121,63 @@ namespace ICSharpCode.NRefactory.TypeSystem #region IEntity EntityType IEntity.EntityType { - get { - throw new NotImplementedException(); - } + get { return EntityType.None; } } DomRegion IEntity.Region { - get { - throw new NotImplementedException(); - } + get { return DomRegion.Empty; } } DomRegion IEntity.BodyRegion { - get { - throw new NotImplementedException(); - } + get { return DomRegion.Empty; } } ITypeDefinition IEntity.DeclaringTypeDefinition { - get { - throw new NotImplementedException(); - } + get { return null; } } IList IEntity.Attributes { - get { - throw new NotImplementedException(); - } + get { return null; } } string IEntity.Documentation { - get { - throw new NotImplementedException(); - } + get { return null; } } bool IEntity.IsStatic { - get { - throw new NotImplementedException(); - } + get { return false; } } Accessibility IEntity.Accessibility { - get { - throw new NotImplementedException(); - } + get { return Accessibility.None; } } bool IEntity.IsAbstract { - get { - throw new NotImplementedException(); - } + get { return false; } } bool IEntity.IsSealed { - get { - throw new NotImplementedException(); - } + get { return false; } } bool IEntity.IsShadowing { - get { - throw new NotImplementedException(); - } + get { return false; } } bool IEntity.IsSynthetic { - get { - throw new NotImplementedException(); - } + get { return false; } } IProjectContent IEntity.ProjectContent { - get { - throw new NotImplementedException(); - } + get { return null; } + } + + bool IFreezable.IsFrozen { + get { return false; } + } + + void IFreezable.Freeze() + { } #endregion } diff --git a/ICSharpCode.NRefactory/TypeSystem/ITypeParameter.cs b/ICSharpCode.NRefactory/TypeSystem/ITypeParameter.cs index 39c92581a4..ee7f43dfc6 100644 --- a/ICSharpCode.NRefactory/TypeSystem/ITypeParameter.cs +++ b/ICSharpCode.NRefactory/TypeSystem/ITypeParameter.cs @@ -169,5 +169,13 @@ namespace ICSharpCode.NRefactory.TypeSystem VarianceModifier ITypeParameter.Variance { get { return VarianceModifier.Invariant; } } + + bool IFreezable.IsFrozen { + get { return false; } + } + + void IFreezable.Freeze() + { + } } } diff --git a/ICSharpCode.NRefactory/TypeSystem/ITypeReference.cs b/ICSharpCode.NRefactory/TypeSystem/ITypeReference.cs index 3faff4ae0a..70f105b3a8 100644 --- a/ICSharpCode.NRefactory/TypeSystem/ITypeReference.cs +++ b/ICSharpCode.NRefactory/TypeSystem/ITypeReference.cs @@ -7,51 +7,27 @@ using System.Diagnostics.Contracts; namespace ICSharpCode.NRefactory.TypeSystem { + /// + /// Represents a reference to a type. + /// Must be resolved before it can be used as type. + /// [ContractClass(typeof(ITypeReferenceContract))] - public interface ITypeReference : IFreezable + public interface ITypeReference { - /// - /// Resolves this type reference. - /// - IType Resolve(ITypeResolveContext context); + // Keep this interface simple: I decided against having GetMethods/GetEvents etc. here, + // so that the Resolve step is never hidden from the consumer. - /// - /// Gets the direct base types. - /// - IEnumerable GetBaseTypes(ITypeResolveContext context); + // I decided against implementing IFreezable here: ITypeDefinition can be used as ITypeReference, + // but when freezing the reference, one wouldn't expect the definition to freeze. /// - /// Gets inner classes (including inherited inner classes). - /// - IList GetNestedTypes(ITypeResolveContext context); - - /// - /// Gets all methods that can be called on this return type. - /// - /// A new mutable list - IList GetMethods(ITypeResolveContext context); - - /// - /// Gets all properties that can be called on this return type. - /// - /// A new mutable list - IList GetProperties(ITypeResolveContext context); - - /// - /// Gets all fields that can be called on this return type. - /// - /// A new mutable list - IList GetFields(ITypeResolveContext context); - - /// - /// Gets all events that can be called on this return type. + /// Resolves this type reference. /// - /// A new mutable list - IList GetEvents(ITypeResolveContext context); + IType Resolve(ITypeResolveContext context); } [ContractClassFor(typeof(ITypeReference))] - abstract class ITypeReferenceContract : IFreezableContract, ITypeReference + abstract class ITypeReferenceContract : ITypeReference { IType ITypeReference.Resolve(ITypeResolveContext context) { @@ -59,47 +35,5 @@ namespace ICSharpCode.NRefactory.TypeSystem Contract.Ensures(Contract.Result() != null); return null; } - - IEnumerable ITypeReference.GetBaseTypes(ITypeResolveContext context) - { - Contract.Requires(context != null); - Contract.Ensures(Contract.Result>() != null); - return null; - } - - IList ITypeReference.GetNestedTypes(ITypeResolveContext context) - { - Contract.Requires(context != null); - Contract.Ensures(Contract.Result>() != null); - return null; - } - - IList ITypeReference.GetMethods(ITypeResolveContext context) - { - Contract.Requires(context != null); - Contract.Ensures(Contract.Result>() != null); - return null; - } - - IList ITypeReference.GetProperties(ITypeResolveContext context) - { - Contract.Requires(context != null); - Contract.Ensures(Contract.Result>() != null); - return null; - } - - IList ITypeReference.GetFields(ITypeResolveContext context) - { - Contract.Requires(context != null); - Contract.Ensures(Contract.Result>() != null); - return null; - } - - IList ITypeReference.GetEvents(ITypeResolveContext context) - { - Contract.Requires(context != null); - Contract.Ensures(Contract.Result>() != null); - return null; - } } } \ No newline at end of file diff --git a/ICSharpCode.NRefactory/TypeSystem/ITypeResolveContext.cs b/ICSharpCode.NRefactory/TypeSystem/ITypeResolveContext.cs index 3d94ab8fb2..c63abf4503 100644 --- a/ICSharpCode.NRefactory/TypeSystem/ITypeResolveContext.cs +++ b/ICSharpCode.NRefactory/TypeSystem/ITypeResolveContext.cs @@ -76,19 +76,19 @@ namespace ICSharpCode.NRefactory.TypeSystem Contract.Requires(fullTypeName != null); Contract.Requires(typeParameterCount >= 0); Contract.Requires(nameComparer != null); - throw new NotImplementedException(); + return null; } ISynchronizedTypeResolveContext ITypeResolveContext.Synchronize() { Contract.Ensures(Contract.Result() != null); - throw new NotImplementedException(); + return null; } IEnumerable ITypeResolveContext.GetClasses() { Contract.Ensures(Contract.Result>() != null); - throw new NotImplementedException(); + return null; } IEnumerable ITypeResolveContext.GetClasses(string nameSpace, StringComparer nameComparer) @@ -96,13 +96,13 @@ namespace ICSharpCode.NRefactory.TypeSystem Contract.Requires(nameSpace != null); Contract.Requires(nameComparer != null); Contract.Ensures(Contract.Result>() != null); - throw new NotImplementedException(); + return null; } IEnumerable ITypeResolveContext.GetNamespaces() { Contract.Ensures(Contract.Result>() != null); - throw new NotImplementedException(); + return null; } } } diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractFreezable.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractFreezable.cs index 23439da204..5f5362e405 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractFreezable.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractFreezable.cs @@ -73,6 +73,14 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation else return new ReadOnlyCollection(list.ToArray()); } + + protected static IList FreezeList(IList list) + { + if (list == null || list.Count == 0) + return EmptyList.Instance; + else + return new ReadOnlyCollection(list.ToArray()); + } } static class EmptyList diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractTypeReference.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractTypeReference.cs index 2c603f78bf..4538d0b763 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractTypeReference.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractTypeReference.cs @@ -6,38 +6,8 @@ using System.Collections.Generic; namespace ICSharpCode.NRefactory.TypeSystem.Implementation { - public abstract class AbstractTypeReference : Immutable, ITypeReference + public abstract class AbstractTypeReference : ITypeReference { public abstract IType Resolve(ITypeResolveContext context); - - public virtual IEnumerable GetBaseTypes(ITypeResolveContext context) - { - return Resolve(context).GetBaseTypes(context); - } - - public virtual IList GetNestedTypes(ITypeResolveContext context) - { - return Resolve(context).GetNestedTypes(context); - } - - public virtual IList GetMethods(ITypeResolveContext context) - { - return Resolve(context).GetMethods(context); - } - - public virtual IList GetProperties(ITypeResolveContext context) - { - return Resolve(context).GetProperties(context); - } - - public virtual IList GetFields(ITypeResolveContext context) - { - return Resolve(context).GetFields(context); - } - - public virtual IList GetEvents(ITypeResolveContext context) - { - return Resolve(context).GetEvents(context); - } } } diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultAttribute.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultAttribute.cs index b178016e80..387b304318 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultAttribute.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultAttribute.cs @@ -19,7 +19,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation protected override void FreezeInternal() { - attributeType.Freeze(); positionalArguments = FreezeList(positionalArguments); if (namedArguments == null || namedArguments.Count == 0) { diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultParameter.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultParameter.cs index 377684a7c9..e6dd3ccecd 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultParameter.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultParameter.cs @@ -47,7 +47,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation protected override void FreezeInternal() { - type.Freeze(); attributes = FreezeList(attributes); if (defaultValue != null) defaultValue.Freeze(); diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeDefinition.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeDefinition.cs index 45d9a738a2..0c48dc1f21 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeDefinition.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeDefinition.cs @@ -357,27 +357,83 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation public IList GetNestedTypes(ITypeResolveContext context) { - throw new NotImplementedException(); + IList nestedTypes = null; + foreach (var baseTypeRef in this.BaseTypes) { + IType baseType = baseTypeRef.Resolve(context); + ITypeDefinition baseTypeDef = baseType.GetDefinition(); + if (baseTypeDef != null && baseTypeDef.ClassType != ClassType.Interface) { + // get nested types from baseType (not baseTypeDef) so that generics work correctly + nestedTypes = baseType.GetNestedTypes(context); + break; // there is at most 1 non-interface base + } + } + if (nestedTypes == null) + nestedTypes = new List(); + foreach (ITypeDefinition innerClass in this.InnerClasses) { + if (innerClass.TypeParameterCount > 0) { + // Parameterize inner classes with their own type parameters, as per on IType.GetNestedTypes. + nestedTypes.Add(new ConstructedType(innerClass, innerClass.TypeParameters)); + } else { + nestedTypes.Add(innerClass); + } + } + return nestedTypes; } public IList GetMethods(ITypeResolveContext context) { - throw new NotImplementedException(); + List methods = new List(); + foreach (var baseTypeRef in this.BaseTypes) { + IType baseType = baseTypeRef.Resolve(context); + ITypeDefinition baseTypeDef = baseType.GetDefinition(); + if (baseTypeDef != null && (baseTypeDef.ClassType != ClassType.Interface || this.ClassType == ClassType.Interface)) { + methods.AddRange(baseType.GetMethods(context)); + } + } + methods.AddRange(this.Methods); + return methods; } public IList GetProperties(ITypeResolveContext context) { - throw new NotImplementedException(); + List properties = new List(); + foreach (var baseTypeRef in this.BaseTypes) { + IType baseType = baseTypeRef.Resolve(context); + ITypeDefinition baseTypeDef = baseType.GetDefinition(); + if (baseTypeDef != null && (baseTypeDef.ClassType != ClassType.Interface || this.ClassType == ClassType.Interface)) { + properties.AddRange(baseType.GetProperties(context)); + } + } + properties.AddRange(this.Properties); + return properties; } public IList GetFields(ITypeResolveContext context) { - throw new NotImplementedException(); + List fields = new List(); + foreach (var baseTypeRef in this.BaseTypes) { + IType baseType = baseTypeRef.Resolve(context); + ITypeDefinition baseTypeDef = baseType.GetDefinition(); + if (baseTypeDef != null && (baseTypeDef.ClassType != ClassType.Interface || this.ClassType == ClassType.Interface)) { + fields.AddRange(baseType.GetFields(context)); + } + } + fields.AddRange(this.Fields); + return fields; } public IList GetEvents(ITypeResolveContext context) { - throw new NotImplementedException(); + List events = new List(); + foreach (var baseTypeRef in this.BaseTypes) { + IType baseType = baseTypeRef.Resolve(context); + ITypeDefinition baseTypeDef = baseType.GetDefinition(); + if (baseTypeDef != null && (baseTypeDef.ClassType != ClassType.Interface || this.ClassType == ClassType.Interface)) { + events.AddRange(baseType.GetEvents(context)); + } + } + events.AddRange(this.Events); + return events; } public override bool Equals(object obj) diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMethod.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMethod.cs index 99717ee193..d765abc00f 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMethod.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMethod.cs @@ -34,7 +34,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation } /// - /// Performts type substitution in parameter types and in the return type. + /// Performs type substitution in parameter types and in the return type. /// public void SubstituteTypes(ITypeResolveContext context, TypeVisitor substitution) { diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedProperty.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedProperty.cs index 59c9a7c009..06b9e3911c 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedProperty.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedProperty.cs @@ -34,7 +34,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation } /// - /// Performts type substitution in parameter types and in the return type. + /// Performs type substitution in parameter types and in the return type. /// public void SubstituteTypes(ITypeResolveContext context, TypeVisitor substitution) {