From 4d7b266e87a769e9699997c10d1e6624ad2bc459 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Wed, 4 Aug 2010 15:43:44 +0200 Subject: [PATCH] Add simple type references. --- .../ICSharpCode.NRefactory.csproj | 2 + .../TypeSystem/CecilProjectContent.cs | 81 ++++++++++++++++++- .../TypeSystem/Implementation/AbstractType.cs | 5 ++ .../Implementation/GetClassTypeReference.cs | 40 +++++++++ .../Implementation/NestedTypeReference.cs | 46 +++++++++++ README | 3 + 6 files changed, 174 insertions(+), 3 deletions(-) create mode 100644 ICSharpCode.NRefactory/TypeSystem/Implementation/GetClassTypeReference.cs create mode 100644 ICSharpCode.NRefactory/TypeSystem/Implementation/NestedTypeReference.cs diff --git a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj index 19756fd08e..cc57d509d1 100644 --- a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj +++ b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj @@ -149,6 +149,8 @@ + + diff --git a/ICSharpCode.NRefactory/TypeSystem/CecilProjectContent.cs b/ICSharpCode.NRefactory/TypeSystem/CecilProjectContent.cs index a661b0969a..ba1842d60b 100644 --- a/ICSharpCode.NRefactory/TypeSystem/CecilProjectContent.cs +++ b/ICSharpCode.NRefactory/TypeSystem/CecilProjectContent.cs @@ -77,10 +77,59 @@ namespace ICSharpCode.NRefactory.TypeSystem #endregion #region Read Type Reference - public static ITypeReference ReadTypeReference(TypeReference attributeType, ITypeResolveContext earlyBindContext) + /// + /// Reads a type reference. + /// + /// The Cecil type reference that should be converted into + /// a type system type reference. + /// Attributes associated with the Cecil type reference. + /// This is used to support the 'dynamic' type. + /// Early binding context - used to pre-resolve + /// type references where possible. + /// The entity that owns this type reference. + /// Used for generic type references. + public static ITypeReference ReadTypeReference( + TypeReference type, + ICustomAttributeProvider typeAttributes = null, + IEntity entity = null, + ITypeResolveContext earlyBindContext = null) { + int typeIndex = 0; + return ReadTypeReference(type, typeAttributes, entity, earlyBindContext, ref typeIndex); + } + + static ITypeReference ReadTypeReference( + TypeReference type, + ICustomAttributeProvider typeAttributes, + IEntity entity , + ITypeResolveContext earlyBindContext, + ref int typeIndex) + { + while (type is OptionalModifierType || type is RequiredModifierType) { + type = ((TypeSpecification)type).ElementType; + } + if (type == null) { + return SharedTypes.UnknownType; + } throw new NotImplementedException(); } + + static bool HasDynamicAttribute(ICustomAttributeProvider attributeProvider, int typeIndex) + { + if (attributeProvider == null || !attributeProvider.HasCustomAttributes) + return false; + foreach (CustomAttribute a in attributeProvider.CustomAttributes) { + if (a.Constructor.DeclaringType.FullName == "System.Runtime.CompilerServices.DynamicAttribute") { + if (a.ConstructorArguments.Count == 1) { + CustomAttributeArgument[] values = a.ConstructorArguments[0].Value as CustomAttributeArgument[]; + if (values != null && typeIndex < values.Length && values[typeIndex].Value is bool) + return (bool)values[typeIndex].Value; + } + return true; + } + } + return false; + } #endregion #region Read Attributes @@ -107,7 +156,7 @@ namespace ICSharpCode.NRefactory.TypeSystem public CecilAttribute(CustomAttribute ca, ITypeResolveContext earlyBindContext) { - this.attributeType = ReadTypeReference(ca.AttributeType, earlyBindContext); + this.attributeType = ReadTypeReference(ca.AttributeType, earlyBindContext: earlyBindContext); this.ca = ca; this.earlyBindContext = earlyBindContext; } @@ -176,7 +225,33 @@ namespace ICSharpCode.NRefactory.TypeSystem #region Read Constant Value public static IConstantValue ReadConstantValue(CustomAttributeArgument arg, ITypeResolveContext earlyBindContext) { - throw new NotImplementedException(); + return new CecilConstantValue(arg.Type, arg.Value, earlyBindContext); + } + + sealed class CecilConstantValue : Immutable, IConstantValue + { + ITypeReference type; + object value; + + public CecilConstantValue(TypeReference type, object value, ITypeResolveContext earlyBindContext) + { + this.type = ReadTypeReference(type, earlyBindContext: earlyBindContext); + TypeReference valueType = value as TypeReference; + if (valueType != null) + this.value = ReadTypeReference(valueType, earlyBindContext: earlyBindContext); + else + this.value = value; + } + + public IType GetValueType(ITypeResolveContext context) + { + return type.Resolve(context); + } + + public object GetValue(ITypeResolveContext context) + { + return value; + } } #endregion } diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractType.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractType.cs index 948c865767..70b7b9d13b 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractType.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractType.cs @@ -110,5 +110,10 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation public abstract override int GetHashCode(); public abstract bool Equals(IType other); + + public override string ToString() + { + return this.DotNetName; + } } } diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/GetClassTypeReference.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/GetClassTypeReference.cs new file mode 100644 index 0000000000..9314fcf4a9 --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/GetClassTypeReference.cs @@ -0,0 +1,40 @@ +// +// +// +// +// $Revision$ +// +using System; + +namespace ICSharpCode.NRefactory.TypeSystem.Implementation +{ + /// + /// Type Reference used when the fully qualified type name is known. + /// + public class GetClassTypeReference : AbstractTypeReference + { + string fullTypeName; + int typeParameterCount; + + public GetClassTypeReference(string fullTypeName, int typeParameterCount) + { + if (fullTypeName == null) + throw new ArgumentNullException("fullTypeName"); + this.fullTypeName = fullTypeName; + this.typeParameterCount = typeParameterCount; + } + + public override IType Resolve(ITypeResolveContext context) + { + return context.GetClass(fullTypeName, typeParameterCount, StringComparer.Ordinal); + } + + public override string ToString() + { + if (typeParameterCount == 0) + return fullTypeName; + else + return fullTypeName + "`" + typeParameterCount; + } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/NestedTypeReference.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/NestedTypeReference.cs new file mode 100644 index 0000000000..bedddacc2a --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/NestedTypeReference.cs @@ -0,0 +1,46 @@ +// +// +// +// +// $Revision$ +// +using System; + +namespace ICSharpCode.NRefactory.TypeSystem.Implementation +{ + /// + /// Type reference used to reference nested types. + /// + public class NestedTypeReference : AbstractTypeReference + { + ITypeReference baseTypeRef; string name; int typeParameterCount; + + public NestedTypeReference(ITypeReference baseTypeRef, string name, int typeParameterCount) + { + if (baseTypeRef == null) + throw new ArgumentNullException("baseTypeRef"); + if (name == null) + throw new ArgumentNullException("name"); + this.baseTypeRef = baseTypeRef; + this.name = name; + this.typeParameterCount = typeParameterCount; + } + + public override IType Resolve(ITypeResolveContext context) + { + foreach (IType type in baseTypeRef.GetNestedTypes(context)) { + if (type.Name == name && type.TypeParameterCount == typeParameterCount) + return type; + } + return SharedTypes.UnknownType; + } + + public override string ToString() + { + if (typeParameterCount == 0) + return baseTypeRef + "+" + name; + else + return baseTypeRef + "+" + name + "`" + typeParameterCount; + } + } +} diff --git a/README b/README index 7e2fb708c8..8d4c1ba86d 100644 --- a/README +++ b/README @@ -5,3 +5,6 @@ ICSharpCode.NRefactory.TypeSystem: ICSharpCode.NRefactory.TypeSystem.Implementation: Contains base classes that help implementing the type system interfaces. + +ICSharpCode.NRefactory.CSharp.Dom: + Abstract Syntax Tree for C#