Permalink
Browse files

TypeSystemAstBuilder: when a type reference cannot be resolved but is…

… a C# type reference, output the original C# code that was used to created the type reference.
  • Loading branch information...
1 parent 023e13b commit f807e6166f352f6e3e25d6aaf5a19c8c7966359d @dgrunwald dgrunwald committed Aug 27, 2011
@@ -115,7 +115,7 @@ public ITypeDefinition GetTopLevelTypeDefinition(AstLocation location)
return FindEntity(topLevelTypeDefinitions, location);
}
- public ITypeDefinition GetInnerMostTypeDefinition(AstLocation location)
+ public ITypeDefinition GetInnermostTypeDefinition(AstLocation location)
{
ITypeDefinition parent = null;
ITypeDefinition type = GetTopLevelTypeDefinition(location);
@@ -128,7 +128,7 @@ public ITypeDefinition GetInnerMostTypeDefinition(AstLocation location)
public IMember GetMember(AstLocation location)
{
- ITypeDefinition type = GetInnerMostTypeDefinition(location);
+ ITypeDefinition type = GetInnermostTypeDefinition(location);
if (type == null)
return null;
return FindEntity(type.Methods, location)
@@ -1,4 +1,4 @@
-//
+//
// GenerateSwitchLabels.cs
//
// Author:
@@ -38,7 +38,7 @@ public bool IsValid (RefactoringContext context)
var result = context.Resolve (switchStatement.Expression);
if (result == null)
return false;
- return result.Type.IsEnum ();
+ return result.Type.Kind == TypeKind.Enum;
}
public void Run (RefactoringContext context)
@@ -20,6 +20,7 @@ public class TypeSystemAstBuilder
readonly CSharpResolver resolver;
readonly ITypeResolveContext context;
+ #region Constructor
/// <summary>
/// Creates a new TypeSystemAstBuilder.
/// </summary>
@@ -35,13 +36,20 @@ public TypeSystemAstBuilder(CSharpResolver resolver)
InitProperties();
}
+ /// <summary>
+ /// Creates a new TypeSystemAstBuilder.
+ /// </summary>
+ /// <param name="context">
+ /// Context used for resolving types.
+ /// </param>
public TypeSystemAstBuilder(ITypeResolveContext context)
{
if (context == null)
throw new ArgumentNullException("context");
this.context = context;
InitProperties();
}
+ #endregion
#region Properties
void InitProperties()
@@ -131,10 +139,57 @@ public AstType ConvertType(IType type)
return new SimpleType(type.Name);
}
- AstType ConvertTypeHelper(ITypeDefinition typeDef, IList<IType> typeArguments)
+ public AstType ConvertTypeReference(ITypeReference typeRef)
{
- Debug.Assert(typeArguments.Count >= typeDef.TypeParameterCount);
- switch (ReflectionHelper.GetTypeCode(typeDef)) {
+ ArrayTypeReference array = typeRef as ArrayTypeReference;
+ if (array != null) {
+ return ConvertTypeReference(array.ElementType).MakeArrayType(array.Dimensions);
+ }
+ PointerTypeReference pointer = typeRef as PointerTypeReference;
+ if (pointer != null) {
+ return ConvertTypeReference(pointer.ElementType).MakePointerType();
+ }
+ ByReferenceType brt = typeRef as ByReferenceType;
+ if (brt != null) {
+ return ConvertTypeReference(brt.ElementType);
+ }
+
+ IType type = typeRef.Resolve(context);
+ if (type.Kind != TypeKind.Unknown)
+ return ConvertType(type);
+ // Unknown type, let's try if we can find an appropriate type
+ // (anything is better than displaying a question mark)
+ KnownTypeReference knownType = typeRef as KnownTypeReference;
+ if (knownType != null) {
+ PrimitiveType primitiveType;
+ if (knownType.TypeCode == TypeCode.Empty)
+ primitiveType = new PrimitiveType("void");
+ else
+ primitiveType = ConvertPrimitiveType(knownType.TypeCode);
+ if (primitiveType != null)
+ return primitiveType;
+ }
+ SimpleTypeOrNamespaceReference str = typeRef as SimpleTypeOrNamespaceReference;
+ if (str != null) {
+ return new SimpleType(str.Identifier, str.TypeArguments.Select(ConvertTypeReference));
+ }
+ MemberTypeOrNamespaceReference mtr = typeRef as MemberTypeOrNamespaceReference;
+ if (mtr != null) {
+ return new MemberType(ConvertTypeReference(mtr.Target), mtr.Identifier, mtr.TypeArguments.Select(ConvertTypeReference)) {
+ IsDoubleColon = mtr.Target is AliasNamespaceReference
+ };
+ }
+ AliasNamespaceReference alias = typeRef as AliasNamespaceReference;
+ if (alias != null) {
+ return new SimpleType(alias.Identifier);
+ }
+ // Unknown type reference that couldn't be resolved
+ return new SimpleType("?");
+ }
+
+ PrimitiveType ConvertPrimitiveType(TypeCode typeCode)
+ {
+ switch (typeCode) {
case TypeCode.Object:
return new PrimitiveType("object");
case TypeCode.Boolean:
@@ -165,7 +220,17 @@ AstType ConvertTypeHelper(ITypeDefinition typeDef, IList<IType> typeArguments)
return new PrimitiveType("decimal");
case TypeCode.String:
return new PrimitiveType("string");
+ default:
+ return null;
}
+ }
+
+ AstType ConvertTypeHelper(ITypeDefinition typeDef, IList<IType> typeArguments)
+ {
+ Debug.Assert(typeArguments.Count >= typeDef.TypeParameterCount);
+ PrimitiveType primitiveType = ConvertPrimitiveType(ReflectionHelper.GetTypeCode(typeDef));
+ if (primitiveType != null)
+ return primitiveType;
// There is no type code for System.Void
if (typeDef.Kind == TypeKind.Void)
return new PrimitiveType("void");
@@ -337,7 +402,7 @@ public ParameterDeclaration ConvertParameter(IParameter parameter)
} else if (parameter.IsParams) {
decl.ParameterModifier = ParameterModifier.Params;
}
- decl.Type = ConvertType(parameter.Type.Resolve(context));
+ decl.Type = ConvertTypeReference(parameter.Type);
if (this.ShowParameterNames) {
decl.Name = parameter.Name;
}
@@ -428,7 +493,7 @@ AttributedNode ConvertTypeDefinition(ITypeDefinition typeDefinition)
if (this.ShowBaseTypes) {
foreach (ITypeReference baseType in typeDefinition.BaseTypes) {
- decl.BaseTypes.Add(ConvertType(baseType.Resolve(context)));
+ decl.BaseTypes.Add(ConvertTypeReference(baseType));
}
}
@@ -448,7 +513,7 @@ DelegateDeclaration ConvertDelegate(IMethod invokeMethod, Modifiers modifiers)
DelegateDeclaration decl = new DelegateDeclaration();
decl.Modifiers = modifiers;
- decl.ReturnType = ConvertType(invokeMethod.ReturnType.Resolve(context));
+ decl.ReturnType = ConvertTypeReference(invokeMethod.ReturnType);
decl.Name = d.Name;
if (this.ShowTypeParameters) {
@@ -484,7 +549,7 @@ AstNode ConvertField(IField field)
m |= Modifiers.Volatile;
}
decl.Modifiers = m;
- decl.ReturnType = ConvertType(field.ReturnType.Resolve(context));
+ decl.ReturnType = ConvertTypeReference(field.ReturnType);
Expression initializer = null;
if (field.IsConst && this.ShowConstantValues)
initializer = ConvertConstantValue(field.ConstantValue);
@@ -505,7 +570,7 @@ PropertyDeclaration ConvertProperty(IProperty property)
{
PropertyDeclaration decl = new PropertyDeclaration();
decl.Modifiers = GetMemberModifiers(property);
- decl.ReturnType = ConvertType(property.ReturnType.Resolve(context));
+ decl.ReturnType = ConvertTypeReference(property.ReturnType);
decl.Name = property.Name;
decl.Getter = ConvertAccessor(property.Getter);
decl.Setter = ConvertAccessor(property.Setter);
@@ -516,7 +581,7 @@ IndexerDeclaration ConvertIndexer(IProperty indexer)
{
IndexerDeclaration decl = new IndexerDeclaration();
decl.Modifiers = GetMemberModifiers(indexer);
- decl.ReturnType = ConvertType(indexer.ReturnType.Resolve(context));
+ decl.ReturnType = ConvertTypeReference(indexer.ReturnType);
foreach (IParameter p in indexer.Parameters) {
decl.Parameters.Add(ConvertParameter(p));
}
@@ -529,7 +594,7 @@ EventDeclaration ConvertEvent(IEvent ev)
{
EventDeclaration decl = new EventDeclaration();
decl.Modifiers = GetMemberModifiers(ev);
- decl.ReturnType = ConvertType(ev.ReturnType.Resolve(context));
+ decl.ReturnType = ConvertTypeReference(ev.ReturnType);
decl.Variables.Add(new VariableInitializer(ev.Name));
return decl;
}
@@ -538,7 +603,7 @@ MethodDeclaration ConvertMethod(IMethod method)
{
MethodDeclaration decl = new MethodDeclaration();
decl.Modifiers = GetMemberModifiers(method);
- decl.ReturnType = ConvertType(method.ReturnType.Resolve(context));
+ decl.ReturnType = ConvertTypeReference(method.ReturnType);
decl.Name = method.Name;
if (this.ShowTypeParameters) {
@@ -570,7 +635,7 @@ AstNode ConvertOperator(IMethod op)
OperatorDeclaration decl = new OperatorDeclaration();
decl.Modifiers = GetMemberModifiers(op);
decl.OperatorType = opType.Value;
- decl.ReturnType = ConvertType(op.ReturnType.Resolve(context));
+ decl.ReturnType = ConvertTypeReference(op.ReturnType);
foreach (IParameter p in op.Parameters) {
decl.Parameters.Add(ConvertParameter(p));
}
@@ -663,7 +728,7 @@ Constraint ConvertTypeParameterConstraint(ITypeParameter tp)
c.BaseTypes.Add(new PrimitiveType("struct"));
}
foreach (ITypeReference tr in tp.Constraints) {
- c.BaseTypes.Add(ConvertType(tr.Resolve(context)));
+ c.BaseTypes.Add(ConvertTypeReference(tr));
}
if (tp.HasDefaultConstructorConstraint) {
c.BaseTypes.Add(new PrimitiveType("new"));
@@ -677,7 +742,7 @@ public VariableDeclarationStatement ConvertVariable(IVariable v)
{
VariableDeclarationStatement decl = new VariableDeclarationStatement();
decl.Modifiers = v.IsConst ? Modifiers.Const : Modifiers.None;
- decl.Type = ConvertType(v.Type.Resolve(context));
+ decl.Type = ConvertTypeReference(v.Type);
Expression initializer = null;
if (v.IsConst)
initializer = ConvertConstantValue(v.ConstantValue);
@@ -42,6 +42,10 @@ public AliasNamespaceReference(string identifier, UsingScope parentUsingScope)
this.parentUsingScope = parentUsingScope;
}
+ public string Identifier {
+ get { return identifier; }
+ }
+
public ResolveResult DoResolve(ITypeResolveContext context)
{
CSharpResolver r = new CSharpResolver(context);
@@ -1895,7 +1895,7 @@ public ResolveResult ResolveCast(IType targetType, ResolveResult expression)
return new ConstantResolveResult(targetType, expression.ConstantValue);
else
return new ErrorResolveResult(targetType);
- } else if (targetType.IsEnum()) {
+ } else if (targetType.Kind == TypeKind.Enum) {
code = ReflectionHelper.GetTypeCode(targetType.GetEnumUnderlyingType(context));
if (code >= TypeCode.SByte && code <= TypeCode.UInt64 && expression.ConstantValue != null) {
try {
@@ -534,7 +534,7 @@ bool ImplicitEnumerationConversion(ResolveResult rr, IType toType)
Debug.Assert(rr.IsCompileTimeConstant);
TypeCode constantType = ReflectionHelper.GetTypeCode(rr.Type);
if (constantType >= TypeCode.SByte && constantType <= TypeCode.Decimal && Convert.ToDouble(rr.ConstantValue) == 0) {
- return NullableType.GetUnderlyingType(toType).IsEnum();
+ return NullableType.GetUnderlyingType(toType).Kind == TypeKind.Enum;
}
return false;
}
@@ -18,6 +18,7 @@
using System;
using System.Collections.Generic;
+using System.Collections.ObjectModel;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.Utils;
@@ -48,6 +49,18 @@ public MemberTypeOrNamespaceReference(ITypeOrNamespaceReference target, string i
this.parentUsingScope = parentUsingScope;
}
+ public string Identifier {
+ get { return identifier; }
+ }
+
+ public ITypeOrNamespaceReference Target {
+ get { return target; }
+ }
+
+ public IList<ITypeReference> TypeArguments {
+ get { return new ReadOnlyCollection<ITypeReference>(typeArguments); }
+ }
+
/// <summary>
/// Adds a suffix to the identifier.
/// Does not modify the existing type reference, but returns a new one.
@@ -18,6 +18,7 @@
using System;
using System.Collections.Generic;
+using System.Collections.ObjectModel;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.Utils;
@@ -46,6 +47,14 @@ public SimpleTypeOrNamespaceReference(string identifier, IList<ITypeReference> t
this.lookupMode = lookupMode;
}
+ public string Identifier {
+ get { return identifier; }
+ }
+
+ public IList<ITypeReference> TypeArguments {
+ get { return new ReadOnlyCollection<ITypeReference>(typeArguments); }
+ }
+
/// <summary>
/// Adds a suffix to the identifier.
/// Does not modify the existing type reference, but returns a new one.
@@ -253,9 +253,9 @@ public static IEnumerable<ITypeDefinition> GetAllTypes(this ITypeResolveContext
/// Gets the type (potentially a nested type) defined at the specified location.
/// Returns null if no type is defined at that location.
/// </summary>
- public static ITypeDefinition GetTypeDefinition (this IParsedFile file, int line, int column)
+ public static ITypeDefinition GetInnermostTypeDefinition (this IParsedFile file, int line, int column)
{
- return file.GetInnerMostTypeDefinition (new AstLocation (line, column));
+ return file.GetInnermostTypeDefinition (new AstLocation (line, column));
}
/// <summary>
@@ -67,7 +67,7 @@ public interface IParsedFile : IFreezable
/// Gets the type (potentially a nested type) defined at the specified location.
/// Returns null if no type is defined at that location.
/// </summary>
- ITypeDefinition GetInnerMostTypeDefinition(AstLocation location);
+ ITypeDefinition GetInnermostTypeDefinition(AstLocation location);
/// <summary>
/// Gets the member defined at the specified location.
@@ -129,6 +129,10 @@ public sealed class KnownTypeReference : ITypeReference
readonly TypeCode typeCode;
+ public TypeCode TypeCode {
+ get { return typeCode; }
+ }
+
public KnownTypeReference(TypeCode typeCode)
{
this.typeCode = typeCode;

0 comments on commit f807e61

Please sign in to comment.