Browse Source

Fix ResolveType method

pull/191/merge
Eusebiu Marcu 16 years ago
parent
commit
951acde9c4
  1. 386
      Debugger/Debugger.Core/NRefactory/Ast/ExpressionExtensionMethods.cs

386
Debugger/Debugger.Core/NRefactory/Ast/ExpressionExtensionMethods.cs

@ -170,56 +170,58 @@ namespace ICSharpCode.NRefactory.Ast
public static AstType GetTypeReference(this Type type) public static AstType GetTypeReference(this Type type)
{ {
List<int> arrayRanks = new List<int>(); return new SimpleType(type.Name).SetStaticType((DebugType)type);
while(type.IsArray) {
// C# uses reverse array order // List<int> arrayRanks = new List<int>();
arrayRanks.Add(type.GetArrayRank() - 1); // while(type.IsArray) {
type = type.GetElementType(); // // C# uses reverse array order
} // arrayRanks.Add(type.GetArrayRank() - 1);
// type = type.GetElementType();
int pointerNest = 0; // }
while(type.IsPointer) { //
pointerNest++; // int pointerNest = 0;
type = type.GetElementType(); // while(type.IsPointer) {
} // pointerNest++;
// type = type.GetElementType();
if (type.IsArray) // }
throw new DebuggerException("C# does not support pointers to arrays"); //
// if (type.IsArray)
string name = type.Name; // throw new DebuggerException("C# does not support pointers to arrays");
if (name.IndexOf('`') != -1) //
name = name.Substring(0, name.IndexOf('`')); // string name = type.Name;
if (!string.IsNullOrEmpty(type.Namespace)) // if (name.IndexOf('`') != -1)
name = type.Namespace + "." + name; // name = name.Substring(0, name.IndexOf('`'));
// if (!string.IsNullOrEmpty(type.Namespace))
List<Type> genArgs = new List<Type>(); // name = type.Namespace + "." + name;
// This inludes the generic arguments of the outter types //
genArgs.AddRange(type.GetGenericArguments()); // List<Type> genArgs = new List<Type>();
if (type.DeclaringType != null) // // This inludes the generic arguments of the outter types
genArgs.RemoveRange(0, type.DeclaringType.GetGenericArguments().Length); // genArgs.AddRange(type.GetGenericArguments());
List<AstType> genTypeRefs = new List<AstType>(); // if (type.DeclaringType != null)
foreach(Type genArg in genArgs) { // genArgs.RemoveRange(0, type.DeclaringType.GetGenericArguments().Length);
genTypeRefs.Add(genArg.GetTypeReference()); // List<AstType> genTypeRefs = new List<AstType>();
} // foreach(Type genArg in genArgs) {
// genTypeRefs.Add(genArg.GetTypeReference());
if (type.DeclaringType != null) { // }
var outterRef = type.DeclaringType.GetTypeReference(); //
var innerRef = new ComposedType() { // if (type.DeclaringType != null) {
PointerRank = pointerNest, // var outterRef = type.DeclaringType.GetTypeReference();
//ArraySpecifiers = arrayRanks.ConvertAll(r => new ArraySpecifier(r)), // var innerRef = new ComposedType() {
// BaseType = new MemberType() { // PointerRank = pointerNest,
// Target = outterRef, MemberName = name, TypeArguments = genTypeRefs } // //ArraySpecifiers = arrayRanks.ConvertAll(r => new ArraySpecifier(r)),
}; //// BaseType = new MemberType() {
//// Target = outterRef, MemberName = name, TypeArguments = genTypeRefs }
return innerRef.SetStaticType((DebugType)type); // };
} else { //
return (new ComposedType() { // return innerRef.SetStaticType((DebugType)type);
PointerRank = pointerNest, // } else {
//ArraySpecifiers = arrayRanks.ConvertAll(r => new ArraySpecifier(r)), // return (new ComposedType() {
BaseType = new SimpleType() { // PointerRank = pointerNest,
Identifier = name, // //ArraySpecifiers = arrayRanks.ConvertAll(r => new ArraySpecifier(r)),
/*TypeArguments = genTypeRefs*/ }}).SetStaticType((DebugType)type); // BaseType = new SimpleType() {
} // Identifier = name,
// /*TypeArguments = genTypeRefs*/ }}).SetStaticType((DebugType)type);
// }
} }
/// <summary> /// <summary>
@ -227,156 +229,158 @@ namespace ICSharpCode.NRefactory.Ast
/// Dotted names are split into separate nodes. /// Dotted names are split into separate nodes.
/// It does not normalize generic arguments. /// It does not normalize generic arguments.
/// </summary> /// </summary>
static AstType NormalizeTypeReference(this AstNode expr) // static AstType NormalizeTypeReference(this AstNode expr)
{ // {
if (expr is IdentifierExpression) { // if (expr is IdentifierExpression) {
return new SimpleType() { // return new SimpleType() {
Identifier = ((IdentifierExpression)expr).Identifier/*, // Identifier = ((IdentifierExpression)expr).Identifier/*,
TypeArguments = ((IdentifierExpression)expr).TypeArguments*/ // TypeArguments = ((IdentifierExpression)expr).TypeArguments*/
}; // };
} else if (expr is MemberReferenceExpression) { // } else if (expr is MemberReferenceExpression) {
var outter = NormalizeTypeReference(((MemberReferenceExpression)expr).Target); // var outter = NormalizeTypeReference(((MemberReferenceExpression)expr).Target);
return new MemberType() { Target = outter, // return new MemberType() { Target = outter,
MemberName = ((MemberReferenceExpression)expr).MemberName/*, // MemberName = ((MemberReferenceExpression)expr).MemberName/*,
TypeArguments = ((MemberReferenceExpression)expr).TypeArguments*/ }; // TypeArguments = ((MemberReferenceExpression)expr).TypeArguments*/ };
} else if (expr is TypeReferenceExpression) { // } else if (expr is TypeReferenceExpression) {
return NormalizeTypeReference(((TypeReferenceExpression)expr).Type); // return NormalizeTypeReference(((TypeReferenceExpression)expr).Type);
} else if (expr is ComposedType) { // Frist - it is also TypeReference // } else if (expr is ComposedType) { // Frist - it is also TypeReference
var typeRef = (ComposedType)expr; // var typeRef = (ComposedType)expr;
string[] names = null; // string[] names = null;
if (typeRef.BaseType is SimpleType) // if (typeRef.BaseType is SimpleType)
names = (((SimpleType)typeRef.BaseType)).Identifier.Split('.'); // names = (((SimpleType)typeRef.BaseType)).Identifier.Split('.');
else // else
names = (((MemberType)typeRef.BaseType)).MemberName.Split('.'); // names = (((MemberType)typeRef.BaseType)).MemberName.Split('.');
//
var newRef = NormalizeTypeReference(typeRef.BaseType) as ComposedType; // var newRef = NormalizeTypeReference(typeRef.BaseType) as ComposedType;
foreach(string name in names) { // foreach(string name in names) {
newRef = new ComposedType() { // newRef = new ComposedType() {
BaseType = new SimpleType() { Identifier = name/*, TypeArguments = new List<AstType>() */} // BaseType = new SimpleType() { Identifier = name/*, TypeArguments = new List<AstType>() */}
}; // };
} // }
//(((MemberType)newRef).TypeArguments as List<AstType>).AddRange(typeRef.TypeArguments); // //(((MemberType)newRef).TypeArguments as List<AstType>).AddRange(typeRef.TypeArguments);
newRef.PointerRank = typeRef.PointerRank; // newRef.PointerRank = typeRef.PointerRank;
//newRef.ArraySpecifiers = typeRef.ArraySpecifiers; // //newRef.ArraySpecifiers = typeRef.ArraySpecifiers;
return newRef; // return newRef;
} // } else if (expr is SimpleType) {
else if (expr is SimpleType) { // var typeRef = (SimpleType)expr;
var typeRef = (SimpleType)expr; // string[] names = typeRef.Identifier.Split('.');
string[] names = typeRef.Identifier.Split('.'); // if (names.Length == 1)
if (names.Length == 1) // return typeRef;
return typeRef; // AstType newRef = null;
AstType newRef = null; // foreach(string name in names) {
foreach(string name in names) { // if (newRef == null) {
if (newRef == null) { // newRef = new SimpleType() { Identifier = name/*, TypeArguments = new List<AstType>()*/ };
newRef = new SimpleType() { Identifier = name/*, TypeArguments = new List<AstType>()*/ }; // } else {
} else { // newRef = new MemberType() { Target = newRef, MemberName = name/*, TypeArguments = new List<AstType>() */};
newRef = new MemberType() { Target = newRef, MemberName = name/*, TypeArguments = new List<AstType>() */}; // }
} // }
} // //((List<AstType>)newRef.TypeArguments).AddRange(typeRef.TypeArguments);
//((List<AstType>)newRef.TypeArguments).AddRange(typeRef.TypeArguments); // //newRef.PointerNestingLevel = typeRef.PointerNestingLevel;
//newRef.PointerNestingLevel = typeRef.PointerNestingLevel; // //newRef.RankSpecifier = typeRef.RankSpecifier;
//newRef.RankSpecifier = typeRef.RankSpecifier; // return newRef;
return newRef; // } else if (expr is PrimitiveType) {
} // return (PrimitiveType)expr;
else { // } else {
throw new EvaluateException(expr, "Type expected. {0} seen.", expr.GetType().FullName); // throw new EvaluateException(expr, "Type expected. {0} seen.", expr.GetType().FullName);
} // }
} // }
//
static string GetNameWithArgCounts(AstType typeRef) // static string GetNameWithArgCounts(AstType typeRef)
{ // {
string name = string.Empty; // string name = string.Empty;
//
if (typeRef is SimpleType) // if (typeRef is SimpleType)
{ // {
name = ((SimpleType)typeRef).Identifier; // name = ((SimpleType)typeRef).Identifier;
if (((SimpleType)typeRef).TypeArguments.Count() > 0) // if (((SimpleType)typeRef).TypeArguments.Count() > 0)
name += "`" + ((SimpleType)typeRef).TypeArguments.Count().ToString(); // name += "`" + ((SimpleType)typeRef).TypeArguments.Count().ToString();
} // }
//
if (typeRef is MemberType) { // if (typeRef is MemberType) {
name = ((MemberType)typeRef).MemberName; // name = ((MemberType)typeRef).MemberName;
return GetNameWithArgCounts(((MemberType)typeRef).Target) + "." + name; // return GetNameWithArgCounts(((MemberType)typeRef).Target) + "." + name;
} else { // } else {
return name; // return name;
} // }
} // }
//
public static DebugType ResolveType(this AstNode expr, Debugger.AppDomain appDomain) public static DebugType ResolveType(this AstNode expr, Debugger.AppDomain appDomain)
{ {
if (expr is AstType && expr.GetStaticType() != null)
return expr.GetStaticType(); return expr.GetStaticType();
if (expr is TypeReferenceExpression && ((TypeReferenceExpression)expr).Type.GetStaticType() != null)
return ((TypeReferenceExpression)expr).Type.GetStaticType();
appDomain.Process.TraceMessage("Resolving {0}", expr.PrettyPrint());
var typeRef = NormalizeTypeReference(expr);
List<AstType> genTypeRefs = null; // if (expr is AstType && expr.GetStaticType() != null)
if (typeRef is MemberType) { // return expr.GetStaticType();
//FIXME genTypeRefs = ((MemberType)typeRef).CombineToNormalTypeReference().TypeArguments as List<AstType>; // if (expr is TypeReferenceExpression && ((TypeReferenceExpression)expr).Type.GetStaticType() != null)
} else { // return ((TypeReferenceExpression)expr).Type.GetStaticType();
if (typeRef is SimpleType) { //
//genTypeRefs = ((SimpleType)typeRef).TypeArguments as List<AstType>; // appDomain.Process.TraceMessage("Resolving {0}", expr.PrettyPrint());
} //
} // var typeRef = NormalizeTypeReference(expr);
//
List<DebugType> genArgs = new List<DebugType>(); // List<AstType> genTypeRefs = null;
foreach(var genTypeRef in genTypeRefs) { // if (typeRef is MemberType) {
genArgs.Add(ResolveType(genTypeRef, appDomain)); // //FIXME genTypeRefs = ((MemberType)typeRef).CombineToNormalTypeReference().TypeArguments as List<AstType>;
} // } else {
// if (typeRef is SimpleType) {
return ResolveTypeInternal(typeRef, genArgs.ToArray(), appDomain); // //genTypeRefs = ((SimpleType)typeRef).TypeArguments as List<AstType>;
// }
// }
//
// List<DebugType> genArgs = new List<DebugType>();
// foreach(var genTypeRef in genTypeRefs) {
// genArgs.Add(ResolveType(genTypeRef, appDomain));
// }
//
// return ResolveTypeInternal(typeRef, genArgs.ToArray(), appDomain);
} }
/// <summary> /// <summary>
/// For performance this is separate method. /// For performance this is separate method.
/// 'genArgs' should hold type for each generic parameter in 'typeRef'. /// 'genArgs' should hold type for each generic parameter in 'typeRef'.
/// </summary> /// </summary>
static DebugType ResolveTypeInternal(AstType typeRef, DebugType[] genArgs, Debugger.AppDomain appDomain) // static DebugType ResolveTypeInternal(AstType typeRef, DebugType[] genArgs, Debugger.AppDomain appDomain)
{ // {
DebugType type = null; // DebugType type = null;
//
if (typeRef is SimpleType) { // if (typeRef is SimpleType) {
// Try to construct non-nested type // // Try to construct non-nested type
// If there are generic types up in the tree, it must be nested type // // If there are generic types up in the tree, it must be nested type
var simple = (SimpleType)typeRef; // var simple = (SimpleType)typeRef;
//
if (genArgs.Length == simple.TypeArguments.Count()) { // if (genArgs.Length == simple.TypeArguments.Count()) {
string name = GetNameWithArgCounts(simple); // string name = GetNameWithArgCounts(simple);
type = DebugType.CreateFromNameOrNull(appDomain, name, null, genArgs); // type = DebugType.CreateFromNameOrNull(appDomain, name, null, genArgs);
} // }
} // }
// Try to construct nested type // // Try to construct nested type
if (type == null && typeRef is MemberType) { // if (type == null && typeRef is MemberType) {
var member = (MemberType)typeRef; // var member = (MemberType)typeRef;
DebugType[] outterGenArgs = genArgs; // DebugType[] outterGenArgs = genArgs;
// Do not pass our generic arguments to outter type // // Do not pass our generic arguments to outter type
Array.Resize(ref outterGenArgs, genArgs.Length - member.TypeArguments.Count()); // Array.Resize(ref outterGenArgs, genArgs.Length - member.TypeArguments.Count());
//
DebugType outter = ResolveTypeInternal(member.Target, outterGenArgs, appDomain); // DebugType outter = ResolveTypeInternal(member.Target, outterGenArgs, appDomain);
string nestedName = member.TypeArguments.Count() == 0 ? // string nestedName = member.TypeArguments.Count() == 0 ?
member.MemberName : member.MemberName + "`" + member.TypeArguments.Count(); // member.MemberName : member.MemberName + "`" + member.TypeArguments.Count();
type = DebugType.CreateFromNameOrNull(appDomain, nestedName, outter, genArgs); // type = DebugType.CreateFromNameOrNull(appDomain, nestedName, outter, genArgs);
} // }
//
if (type == null) // if (type == null)
throw new GetValueException("Can not resolve " + typeRef.PrettyPrint()); // throw new GetValueException("Can not resolve " + typeRef.PrettyPrint());
//
if (typeRef is ComposedType) { // if (typeRef is ComposedType) {
//
for(int i = 0; i < ((ComposedType)typeRef).PointerRank; i++) { // for(int i = 0; i < ((ComposedType)typeRef).PointerRank; i++) {
type = (DebugType)type.MakePointerType(); // type = (DebugType)type.MakePointerType();
} // }
if (((ComposedType)typeRef).ArraySpecifiers != null) { // if (((ComposedType)typeRef).ArraySpecifiers != null) {
var enumerator = ((ComposedType)typeRef).ArraySpecifiers.Reverse().GetEnumerator(); // var enumerator = ((ComposedType)typeRef).ArraySpecifiers.Reverse().GetEnumerator();
while (enumerator.MoveNext()) { // while (enumerator.MoveNext()) {
type = (DebugType)type.MakeArrayType(enumerator.Current.Dimensions + 1); // type = (DebugType)type.MakeArrayType(enumerator.Current.Dimensions + 1);
} // }
} // }
} // }
return type; // return type;
} // }
} }
} }

Loading…
Cancel
Save