Skip to content
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...
dgrunwald committed Aug 27, 2011
1 parent 023e13b commit f807e6166f352f6e3e25d6aaf5a19c8c7966359d
@@ -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.
You can’t perform that action at this time.