Browse Source

Started implementation of CecilProjectContent.ReadTypeReference.

newNRvisualizers
Daniel Grunwald 16 years ago
parent
commit
5f1dfe8037
  1. 3
      ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj
  2. 106
      ICSharpCode.NRefactory/TypeSystem/CecilProjectContent.cs
  3. 1
      ICSharpCode.NRefactory/TypeSystem/IMember.cs
  4. 18
      ICSharpCode.NRefactory/TypeSystem/IType.cs
  5. 2
      ICSharpCode.NRefactory/TypeSystem/ITypeReference.cs
  6. 8
      ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractType.cs
  7. 82
      ICSharpCode.NRefactory/TypeSystem/Implementation/ArrayType.cs
  8. 14
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeDefinition.cs
  9. 24
      ICSharpCode.NRefactory/TypeSystem/Implementation/NestedTypeReference.cs
  10. 65
      ICSharpCode.NRefactory/TypeSystem/Implementation/PointerType.cs
  11. 45
      ICSharpCode.NRefactory/TypeSystem/Implementation/TypeWithElementType.cs
  12. 3
      ICSharpCode.NRefactory/TypeSystem/SharedTypes.cs

3
ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj

@ -147,13 +147,16 @@ @@ -147,13 +147,16 @@
<Compile Include="TypeSystem\Implementation\AbstractFreezable.cs" />
<Compile Include="TypeSystem\Implementation\AbstractType.cs" />
<Compile Include="TypeSystem\Implementation\AbstractTypeReference.cs" />
<Compile Include="TypeSystem\Implementation\ArrayType.cs" />
<Compile Include="TypeSystem\Implementation\DefaultExplicitInterfaceImplementation.cs" />
<Compile Include="TypeSystem\Implementation\DefaultParameter.cs" />
<Compile Include="TypeSystem\Implementation\GetClassTypeReference.cs" />
<Compile Include="TypeSystem\Implementation\NestedTypeReference.cs" />
<Compile Include="TypeSystem\Implementation\PointerType.cs" />
<Compile Include="TypeSystem\Implementation\ProxyTypeResolveContext.cs" />
<Compile Include="TypeSystem\Implementation\DefaultTypeDefinition.cs" />
<Compile Include="TypeSystem\Implementation\NullType.cs" />
<Compile Include="TypeSystem\Implementation\TypeWithElementType.cs" />
<Compile Include="TypeSystem\Implementation\UnknownType.cs" />
<Compile Include="TypeSystem\INamedElement.cs" />
<Compile Include="TypeSystem\IParameter.cs" />

106
ICSharpCode.NRefactory/TypeSystem/CecilProjectContent.cs

@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Text;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using Mono.Cecil;
@ -95,15 +96,14 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -95,15 +96,14 @@ namespace ICSharpCode.NRefactory.TypeSystem
ITypeResolveContext earlyBindContext = null)
{
int typeIndex = 0;
return ReadTypeReference(type, typeAttributes, entity, earlyBindContext, ref typeIndex);
return CreateType(type, entity, earlyBindContext, typeAttributes, ref typeIndex);
}
static ITypeReference ReadTypeReference(
static ITypeReference CreateType(
TypeReference type,
ICustomAttributeProvider typeAttributes,
IEntity entity ,
ITypeResolveContext earlyBindContext,
ref int typeIndex)
ICustomAttributeProvider typeAttributes, ref int typeIndex)
{
while (type is OptionalModifierType || type is RequiredModifierType) {
type = ((TypeSpecification)type).ElementType;
@ -111,7 +111,103 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -111,7 +111,103 @@ namespace ICSharpCode.NRefactory.TypeSystem
if (type == null) {
return SharedTypes.UnknownType;
}
throw new NotImplementedException();
if (type is ByReferenceType) {
throw new NotImplementedException();
} else if (type is Mono.Cecil.PointerType) {
typeIndex++;
return PointerTypeReference.Create(
CreateType(
(type as Mono.Cecil.PointerType).ElementType,
entity,
earlyBindContext,
typeAttributes, ref typeIndex));
} else if (type is Mono.Cecil.ArrayType) {
typeIndex++;
return ArrayTypeReference.Create(
CreateType(
(type as Mono.Cecil.ArrayType).ElementType,
entity,
earlyBindContext,
typeAttributes, ref typeIndex),
(type as Mono.Cecil.ArrayType).Rank);
} else if (type is GenericInstanceType) {
GenericInstanceType gType = (GenericInstanceType)type;
/*IReturnType baseType = CreateType(pc, member, gType.ElementType, attributeProvider, ref typeIndex);
IReturnType[] para = new IReturnType[gType.GenericArguments.Count];
for (int i = 0; i < para.Length; ++i) {
typeIndex++;
para[i] = CreateType(pc, member, gType.GenericArguments[i], attributeProvider, ref typeIndex);
}
return new ConstructedReturnType(baseType, para);*/
throw new NotImplementedException();
} else if (type is GenericParameter) {
throw new NotImplementedException();
/*GenericParameter typeGP = type as GenericParameter;
if (typeGP.Owner is MethodDefinition) {
IMethod method = entity as IMethod;
if (method != null) {
if (typeGP.Position < method.TypeParameters.Count) {
return method.TypeParameters[typeGP.Position];
}
}
return SharedTypes.UnknownType;
} else {
ITypeDefinition c = (entity as ITypeDefinition) ?? (entity is IMember ? ((IMember)entity).DeclaringTypeDefinition : null);
if (c != null && typeGP.Position < c.TypeParameters.Count) {
if (c.TypeParameters[typeGP.Position].Name == type.Name) {
return c.TypeParameters[typeGP.Position];
}
}
return SharedTypes.UnknownType;
}*/
} else {
string name = type.FullName;
if (name == null)
throw new ApplicationException("type.FullName returned null. Type: " + type.ToString());
if (name.IndexOf('/') > 0) {
string[] nameparts = name.Split('/');
ITypeReference typeRef = GetSimpleType(nameparts[0], earlyBindContext);
for (int i = 1; i < nameparts.Length; i++) {
int partTypeParameterCount;
string namepart = SplitTypeParameterCountFromReflectionName(nameparts[i], out partTypeParameterCount);
typeRef = new NestedTypeReference(typeRef, namepart, partTypeParameterCount);
}
return typeRef;
} else if (name == "System.Object" && HasDynamicAttribute(typeAttributes, typeIndex)) {
return SharedTypes.Dynamic;
} else {
return GetSimpleType(name, earlyBindContext);
}
}
}
static ITypeReference GetSimpleType(string reflectionName, ITypeResolveContext earlyBindContext)
{
int typeParameterCount;
string name = SplitTypeParameterCountFromReflectionName(reflectionName, out typeParameterCount);
if (earlyBindContext != null) {
IType c = earlyBindContext.GetClass(name, typeParameterCount, StringComparer.Ordinal);
if (c != null)
return c;
}
return new GetClassTypeReference(name, typeParameterCount);
}
static string SplitTypeParameterCountFromReflectionName(string reflectionName, out int typeParameterCount)
{
int pos = reflectionName.LastIndexOf('`');
if (pos < 0) {
typeParameterCount = 0;
return reflectionName;
} else {
string typeCount = reflectionName.Substring(pos + 1);
if (int.TryParse(typeCount, out typeParameterCount))
return reflectionName.Substring(0, pos);
else
return reflectionName;
}
}
static bool HasDynamicAttribute(ICustomAttributeProvider attributeProvider, int typeIndex)

1
ICSharpCode.NRefactory/TypeSystem/IMember.cs

@ -13,6 +13,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -13,6 +13,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
[ContractClass(typeof(IMemberContract))]
public interface IMember : IEntity
{
// redeclare IEntity.DeclaringTypeDefinition to clarify the documentation:
/// <summary>
/// Gets the type definition that contains the member. This property never returns null.
/// </summary>

18
ICSharpCode.NRefactory/TypeSystem/IType.cs

@ -40,16 +40,6 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -40,16 +40,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// </summary>
IType DeclaringType { get; }
/// <summary>
/// Gets whether this type is an array type.
/// </summary>
bool IsArrayType { get; }
/// <summary>
/// Gets whether this type is a pointer type.
/// </summary>
bool IsPointerType { get; }
/// <summary>
/// Gets the number of type parameters.
/// </summary>
@ -63,14 +53,6 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -63,14 +53,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
get { return null; }
}
bool IType.IsArrayType {
get { return false; }
}
bool IType.IsPointerType {
get { return false; }
}
int IType.TypeParameterCount {
get {
Contract.Ensures(Contract.Result<int>() >= 0);

2
ICSharpCode.NRefactory/TypeSystem/ITypeReference.cs

@ -24,7 +24,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -24,7 +24,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// Gets inner classes (including inherited inner classes).
/// </summary>
IList<IType> GetNestedTypes(ITypeResolveContext context);
/// <summary>
/// Gets all methods that can be called on this return type.
/// </summary>

8
ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractType.cs

@ -42,14 +42,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -42,14 +42,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public abstract bool? IsReferenceType { get; }
public virtual bool IsArrayType {
get { return false; }
}
public virtual bool IsPointerType {
get { return false; }
}
public virtual int TypeParameterCount {
get { return 0; }
}

82
ICSharpCode.NRefactory/TypeSystem/Implementation/ArrayType.cs

@ -0,0 +1,82 @@ @@ -0,0 +1,82 @@
// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{
/// <summary>
/// Represents an array type.
/// </summary>
public class ArrayType : TypeWithElementType
{
int dimensions;
public ArrayType(IType elementType, int dimensions) : base(elementType)
{
if (dimensions <= 0)
throw new ArgumentOutOfRangeException("dimensions", dimensions, "dimensions must be positive");
this.dimensions = dimensions;
}
public int Dimensions {
get { return dimensions; }
}
public override string NameSuffix {
get {
if (dimensions == 0)
return "[]";
else
return "[" + new string(',', dimensions-1) + "]";
}
}
public override Nullable<bool> IsReferenceType {
get { return true; }
}
public override int GetHashCode()
{
return unchecked(GetElementType().GetHashCode() * 71681 + dimensions);
}
public override bool Equals(IType other)
{
ArrayType a = other as ArrayType;
return a != null && elementType.Equals(a.elementType) && a.dimensions == dimensions;
}
}
public class ArrayTypeReference : AbstractTypeReference
{
ITypeReference elementType;
int dimensions;
public ArrayTypeReference(ITypeReference elementType, int dimensions)
{
if (elementType == null)
throw new ArgumentNullException("elementType");
this.elementType = elementType;
this.dimensions = dimensions;
}
public override IType Resolve(ITypeResolveContext context)
{
return new ArrayType(elementType.Resolve(context), dimensions);
}
public override string ToString()
{
return elementType.ToString() + "[" + new string(',', dimensions - 1) + "]";
}
public static ITypeReference Create(ITypeReference elementType, int dimensions)
{
if (elementType is IType)
return new ArrayType((IType)elementType, dimensions);
else
return new ArrayTypeReference(elementType, dimensions);
}
}
}

14
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeDefinition.cs

@ -157,14 +157,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -157,14 +157,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
}
}
bool IType.IsArrayType {
get { return false; }
}
bool IType.IsPointerType {
get { return false; }
}
public string FullName {
get {
if (declaringTypeDefinition != null) {
@ -390,8 +382,10 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -390,8 +382,10 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
&& this.Name == other.Name
&& this.TypeParameterCount == other.TypeParameterCount;
} else {
// We do not check the project content because assemblies might or might not
// be equivalent depending on compiler settings and runtime assembly
// redirection.
return other.DeclaringTypeDefinition == null
&& this.ProjectContent == other.ProjectContent
&& this.Namespace == other.Namespace
&& this.Name == other.Name
&& this.TypeParameterCount == other.TypeParameterCount;
@ -403,7 +397,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -403,7 +397,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
if (declaringTypeDefinition != null) {
return declaringTypeDefinition.GetHashCode() ^ name.GetHashCode();
} else {
return ns.GetHashCode() ^ name.GetHashCode() ^ projectContent.GetHashCode();
return ns.GetHashCode() ^ name.GetHashCode() ^ this.TypeParameterCount;
}
}
}

24
ICSharpCode.NRefactory/TypeSystem/Implementation/NestedTypeReference.cs

@ -13,9 +13,17 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -13,9 +13,17 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
/// </summary>
public class NestedTypeReference : AbstractTypeReference
{
ITypeReference baseTypeRef; string name; int typeParameterCount;
ITypeReference baseTypeRef;
string name;
int additionalTypeParameterCount;
public NestedTypeReference(ITypeReference baseTypeRef, string name, int typeParameterCount)
/// <summary>
/// Creates a new NestedTypeReference.
/// </summary>
/// <param name="baseTypeRef">Reference to the base type.</param>
/// <param name="name"></param>
/// <param name="additionalTypeParameterCount"></param>
public NestedTypeReference(ITypeReference baseTypeRef, string name, int additionalTypeParameterCount)
{
if (baseTypeRef == null)
throw new ArgumentNullException("baseTypeRef");
@ -23,13 +31,15 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -23,13 +31,15 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
throw new ArgumentNullException("name");
this.baseTypeRef = baseTypeRef;
this.name = name;
this.typeParameterCount = typeParameterCount;
this.additionalTypeParameterCount = additionalTypeParameterCount;
}
public override IType Resolve(ITypeResolveContext context)
{
foreach (IType type in baseTypeRef.GetNestedTypes(context)) {
if (type.Name == name && type.TypeParameterCount == typeParameterCount)
IType baseType = baseTypeRef.Resolve(context);
int tpc = baseType.TypeParameterCount;
foreach (IType type in baseType.GetNestedTypes(context)) {
if (type.Name == name && type.TypeParameterCount == tpc + additionalTypeParameterCount)
return type;
}
return SharedTypes.UnknownType;
@ -37,10 +47,10 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -37,10 +47,10 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public override string ToString()
{
if (typeParameterCount == 0)
if (additionalTypeParameterCount == 0)
return baseTypeRef + "+" + name;
else
return baseTypeRef + "+" + name + "`" + typeParameterCount;
return baseTypeRef + "+" + name + "`" + additionalTypeParameterCount;
}
}
}

65
ICSharpCode.NRefactory/TypeSystem/Implementation/PointerType.cs

@ -0,0 +1,65 @@ @@ -0,0 +1,65 @@
// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{
public class PointerType : TypeWithElementType
{
public PointerType(IType elementType) : base(elementType)
{
}
public override string NameSuffix {
get {
return "*";
}
}
public override Nullable<bool> IsReferenceType {
get { return null; }
}
public override int GetHashCode()
{
return elementType.GetHashCode() ^ 91725811;
}
public override bool Equals(IType other)
{
PointerType a = other as PointerType;
return a != null && elementType.Equals(a.elementType);
}
}
public class PointerTypeReference : AbstractTypeReference
{
ITypeReference elementType;
public PointerTypeReference(ITypeReference elementType)
{
if (elementType == null)
throw new ArgumentNullException("elementType");
this.elementType = elementType;
}
public override IType Resolve(ITypeResolveContext context)
{
return new PointerType(elementType.Resolve(context));
}
public override string ToString()
{
return elementType.ToString() + "*";
}
public static ITypeReference Create(ITypeReference elementType)
{
if (elementType is IType)
return new PointerType((IType)elementType);
else
return new PointerTypeReference(elementType);
}
}
}

45
ICSharpCode.NRefactory/TypeSystem/Implementation/TypeWithElementType.cs

@ -0,0 +1,45 @@ @@ -0,0 +1,45 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <author name="Daniel Grunwald"/>
// <version>$Revision$</version>
// </file>
using System;
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{
public abstract class TypeWithElementType : AbstractType
{
protected readonly IType elementType;
protected TypeWithElementType(IType elementType)
{
if (elementType == null)
throw new ArgumentNullException("elementType");
this.elementType = elementType;
}
public override string Name {
get { return elementType.Name + NameSuffix; }
}
public override string Namespace {
get { return elementType.Namespace; }
}
public override string FullName {
get { return elementType.FullName + NameSuffix; }
}
public override string DotNetName {
get { return elementType.DotNetName + NameSuffix; }
}
public abstract string NameSuffix { get; }
public override IType GetElementType()
{
return elementType;
}
}
}

3
ICSharpCode.NRefactory/TypeSystem/SharedTypes.cs

@ -23,6 +23,9 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -23,6 +23,9 @@ namespace ICSharpCode.NRefactory.TypeSystem
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "It's immutable")]
public readonly static IType Null = new NullType();
// TODO: implement DynamicType
public readonly static IType Dynamic = new UnknownType();
/*
* I'd like to define static instances for common types like
* void, int, etc.; but there are two problems with this:

Loading…
Cancel
Save