Browse Source

Adjusted C# resolver to refactored type system.

newNRvisualizers
Daniel Grunwald 14 years ago
parent
commit
9d7c018fb2
  1. 13
      ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpAmbience.cs
  2. 10
      ICSharpCode.NRefactory.CSharp/Resolver/CSharpOperators.cs
  3. 13
      ICSharpCode.NRefactory.CSharp/Resolver/CSharpResolver.cs
  4. 2
      ICSharpCode.NRefactory.CSharp/Resolver/Conversions.cs
  5. 18
      ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolution.cs
  6. 26
      ICSharpCode.NRefactory.CSharp/Resolver/ResolveAtLocation.cs
  7. 327
      ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs
  8. 77
      ICSharpCode.NRefactory.CSharp/Resolver/TypeInference.cs
  9. 16
      ICSharpCode.NRefactory.CSharp/TypeSystem/AttributeTypeReference.cs
  10. 2
      ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpUnresolvedTypeDefinition.cs
  11. 36
      ICSharpCode.NRefactory.CSharp/TypeSystem/ConstantValues.cs
  12. 51
      ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs
  13. 10
      ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseSelfTests.cs
  14. 5
      ICSharpCode.NRefactory.Tests/CSharp/Refactoring/TypeSystemAstBuilderTests.cs
  15. 4
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/AttributeTests.cs
  16. 4
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/BinaryOperatorTests.cs
  17. 18
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/ConversionsTest.cs
  18. 9
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/MemberLookupTests.cs
  19. 6
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/NameLookupTests.cs
  20. 112
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/OverloadResolutionTests.cs
  21. 2
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs
  22. 20
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/TypeInferenceTests.cs
  23. 2
      ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.TestCase.cs
  24. 69
      ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.cs
  25. 3
      ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj
  26. 2
      ICSharpCode.NRefactory/Semantics/TypeOfResolveResult.cs
  27. 1
      ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs
  28. 5
      ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs
  29. 14
      ICSharpCode.NRefactory/TypeSystem/IAmbience.cs
  30. 1
      ICSharpCode.NRefactory/TypeSystem/IMethod.cs
  31. 7
      ICSharpCode.NRefactory/TypeSystem/ITypeDefinition.cs
  32. 2
      ICSharpCode.NRefactory/TypeSystem/ITypeParameter.cs
  33. 14
      ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractResolvedTypeParameter.cs
  34. 17
      ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractUnresolvedEntity.cs
  35. 106
      ICSharpCode.NRefactory/TypeSystem/Implementation/AnonymousType.cs
  36. 36
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultMemberReference.cs
  37. 28
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultParameter.cs
  38. 92
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedEvent.cs
  39. 12
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedMethod.cs
  40. 32
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs
  41. 10
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeParameter.cs
  42. 14
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedAssembly.cs
  43. 4
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedEvent.cs
  44. 2
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedField.cs
  45. 2
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedMethod.cs
  46. 7
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedParameter.cs
  47. 2
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedProperty.cs
  48. 17
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedTypeDefinition.cs
  49. 134
      ICSharpCode.NRefactory/TypeSystem/Implementation/DummyTypeParameter.cs
  50. 2
      ICSharpCode.NRefactory/TypeSystem/Implementation/KnownTypeCache.cs
  51. 5
      ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMember.cs
  52. 37
      ICSharpCode.NRefactory/TypeSystem/ParameterListComparer.cs
  53. 3
      ICSharpCode.NRefactory/TypeSystem/TypeKind.cs

13
ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpAmbience.cs

@ -76,6 +76,19 @@ namespace ICSharpCode.NRefactory.CSharp @@ -76,6 +76,19 @@ namespace ICSharpCode.NRefactory.CSharp
}
writer.Write((node is IndexerDeclaration) ? ']' : ')');
}
if ((ConversionFlags & ConversionFlags.ShowBody) == ConversionFlags.ShowBody) {
IProperty property = member as IProperty;
if (property != null) {
writer.Write(" { ");
if (property.CanGet)
writer.Write("get; ");
if (property.CanSet)
writer.Write("set; ");
writer.Write('}');
} else {
writer.Write(';');
}
}
}
TypeSystemAstBuilder CreateAstBuilder()

10
ICSharpCode.NRefactory.CSharp/Resolver/CSharpOperators.cs

@ -592,7 +592,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -592,7 +592,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
: base(operators.compilation)
{
this.canEvaluateAtCompileTime = p1 == TypeCode.String && p2 == TypeCode.String;
this.ReturnType = KnownTypeReference.String.Resolve(operators.compilation.TypeResolveContext);
this.ReturnType = operators.compilation.FindType(KnownTypeCode.String);
this.Parameters.Add(operators.MakeParameter(p1));
this.Parameters.Add(operators.MakeParameter(p2));
}
@ -766,7 +766,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -766,7 +766,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return ops;
} else {
return LazyInit.GetOrSet(ref equalityOperators, Lift(
equalityOperatorsFor.Select(c => new EqualityOperatorMethod(this, c, true)).ToArray()
equalityOperatorsFor.Select(c => new EqualityOperatorMethod(this, c, false)).ToArray()
));
}
}
@ -782,7 +782,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -782,7 +782,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return ops;
} else {
return LazyInit.GetOrSet(ref inequalityOperators, Lift(
equalityOperatorsFor.Select(c => new EqualityOperatorMethod(this, c, false)).ToArray()
equalityOperatorsFor.Select(c => new EqualityOperatorMethod(this, c, true)).ToArray()
));
}
}
@ -803,6 +803,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -803,6 +803,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
this.func = func;
}
public override bool CanEvaluateAtCompileTime {
get { return true; }
}
public override object Invoke(CSharpResolver resolver, object lhs, object rhs)
{
return func((T1)resolver.CSharpPrimitiveCast(Type.GetTypeCode(typeof(T1)), lhs),

13
ICSharpCode.NRefactory.CSharp/Resolver/CSharpResolver.cs

@ -724,7 +724,13 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -724,7 +724,13 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
CSharpOperators.BinaryOperatorMethod PointerArithmeticOperator(IType resultType, IType inputType1, IType inputType2)
{
throw new NotImplementedException();
return new CSharpOperators.BinaryOperatorMethod(compilation) {
ReturnType = resultType,
Parameters = {
new DefaultParameter(inputType1, string.Empty),
new DefaultParameter(inputType2, string.Empty)
}
};
}
#endregion
@ -2000,5 +2006,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2000,5 +2006,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return new ArrayCreateResolveResult(arrayType, sizeArguments, initializerElements);
}
#endregion
public ResolveResult ResolveTypeOf(IType referencedType)
{
return new TypeOfResolveResult(compilation.FindType(KnownTypeCode.Type), referencedType);
}
}
}

2
ICSharpCode.NRefactory.CSharp/Resolver/Conversions.cs

@ -625,7 +625,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -625,7 +625,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
|| ImplicitReferenceConversion(fromArray.ElementType, toPT.GetTypeArgument(0));
}
// conversion from any array to System.Array and the interfaces it implements:
IType systemArray = KnownTypeReference.Array.Resolve(compilation.TypeResolveContext);
IType systemArray = compilation.FindType(KnownTypeCode.Array);
return systemArray.Kind != TypeKind.Unknown && (systemArray.Equals(toType) || ImplicitReferenceConversion(systemArray, toType));
}

18
ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolution.cs

@ -42,6 +42,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -42,6 +42,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// </summary>
public readonly bool IsExpandedForm;
/// <summary>
/// Gets the parameter types. In the first step, these are the types without any substition.
/// After type inference, substitutions will be performed.
/// </summary>
public readonly IType[] ParameterTypes;
/// <summary>
@ -61,6 +65,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -61,6 +65,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// </summary>
public readonly IList<IParameter> Parameters;
/// <summary>
/// Gets the original method type parameters (before any substitution!)
/// </summary>
public readonly IList<ITypeParameter> TypeParameters;
/// <summary>
/// Conversions applied to the arguments.
/// This field is set by the CheckApplicability step.
@ -92,11 +101,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -92,11 +101,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
{
this.Member = member;
this.IsExpandedForm = isExpanded;
if (this.IsGenericMethod) {
IMethod method = member as IMethod;
if (method != null && method.TypeParameters.Count > 0) {
// For generic methods, go back to the original parameters
// (without any type parameter substitution, not even class type parameters)
// We'll re-substitute them as part of RunTypeInference().
this.Parameters = ((IParameterizedMember)member.MemberDefinition).Parameters;
method = (IMethod)method.MemberDefinition;
this.Parameters = method.Parameters;
this.TypeParameters = method.TypeParameters;
} else {
this.Parameters = member.Parameters;
}
@ -364,7 +376,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -364,7 +376,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} else {
TypeInference ti = new TypeInference(compilation, conversions);
bool success;
candidate.InferredTypes = ti.InferTypeArguments(method.TypeParameters, arguments, candidate.ParameterTypes, out success, classTypeArguments);
candidate.InferredTypes = ti.InferTypeArguments(candidate.TypeParameters, arguments, candidate.ParameterTypes, out success, classTypeArguments);
if (!success)
candidate.AddError(OverloadResolutionErrors.TypeInferenceFailed);
}

26
ICSharpCode.NRefactory.CSharp/Resolver/ResolveAtLocation.cs

@ -70,21 +70,17 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -70,21 +70,17 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
else
navigator = new NodeListResolveVisitorNavigator(new[] { resolvableNode });
throw new NotImplementedException();
/*
using (var ctx = context.Synchronize()) {
CSharpResolver resolver = new CSharpResolver(ctx, cancellationToken);
ResolveVisitor v = new ResolveVisitor(resolver, parsedFile, navigator);
v.Scan(cu);
// Prefer the RR from the token itself, if it was assigned a ResolveResult
// (this can happen with the identifiers in various nodes such as catch clauses or foreach statements)
ResolveResult rr = v.GetResolveResult(node) ?? v.GetResolveResult(resolvableNode);
if (rr is MethodGroupResolveResult && parentInvocation != null)
return v.GetResolveResult(parentInvocation);
else
return rr;
}*/
CSharpResolver resolver = new CSharpResolver(compilation);
ResolveVisitor v = new ResolveVisitor(resolver, parsedFile, navigator);
v.Scan(cu);
// Prefer the RR from the token itself, if it was assigned a ResolveResult
// (this can happen with the identifiers in various nodes such as catch clauses or foreach statements)
ResolveResult rr = v.GetResolveResult(node) ?? v.GetResolveResult(resolvableNode);
if (rr is MethodGroupResolveResult && parentInvocation != null)
return v.GetResolveResult(parentInvocation);
else
return rr;
}
}
}

327
ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs

@ -26,6 +26,7 @@ using ICSharpCode.NRefactory.CSharp.TypeSystem; @@ -26,6 +26,7 @@ using ICSharpCode.NRefactory.CSharp.TypeSystem;
using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using ICSharpCode.NRefactory.Utils;
namespace ICSharpCode.NRefactory.CSharp.Resolver
{
@ -504,7 +505,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -504,7 +505,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
try {
ITypeDefinition newTypeDefinition = null;
if (resolver.CurrentTypeDefinition != null) {
int totalTypeParameterCount = resolver.CurrentTypeDefinition.TypeParameterCount;
int totalTypeParameterCount = resolver.CurrentTypeDefinition.TypeParameterCount + typeParameterCount;
foreach (ITypeDefinition nestedType in resolver.CurrentTypeDefinition.NestedTypes) {
if (nestedType.Name == name && nestedType.TypeParameterCount == totalTypeParameterCount) {
newTypeDefinition = nestedType;
@ -512,9 +513,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -512,9 +513,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
}
} else if (resolver.CurrentUsingScope != null) {
INamespace ns = resolver.CurrentUsingScope.Namespace;
if (ns != null)
newTypeDefinition = ns.GetTypeDefinition(name, typeParameterCount);
newTypeDefinition = resolver.CurrentUsingScope.Namespace.GetTypeDefinition(name, typeParameterCount);
}
if (newTypeDefinition != null)
resolver.CurrentTypeDefinition = newTypeDefinition;
@ -568,7 +567,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -568,7 +567,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResolveResult VisitFieldOrEventDeclaration(AttributedNode fieldOrEventDeclaration)
{
int initializerCount = fieldOrEventDeclaration.GetChildrenByRole(FieldDeclaration.Roles.Variable).Count;
//int initializerCount = fieldOrEventDeclaration.GetChildrenByRole(FieldDeclaration.Roles.Variable).Count;
for (AstNode node = fieldOrEventDeclaration.FirstChild; node != null; node = node.NextSibling) {
if (node.Role == FieldDeclaration.Roles.Variable) {
resolver.CurrentMember = GetMemberFromLocation(node.StartLocation);
@ -585,7 +584,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -585,7 +584,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
IMember GetMemberFromLocation(TextLocation location)
{
throw new NotImplementedException();
ITypeDefinition typeDef = resolver.CurrentTypeDefinition;
if (typeDef == null)
return null;
return typeDef.GetMembers(m => m.ParsedFile == parsedFile && m.Region.IsInside(location), GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions).FirstOrDefault();
}
ResolveResult IAstVisitor<object, ResolveResult>.VisitVariableInitializer(VariableInitializer variableInitializer, object data)
@ -863,7 +865,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -863,7 +865,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
#endregion
#region Visit Expressions
#region Visit AnonymousTypeCreateExpression
static string GetAnonymousTypePropertyName(Expression expr, out Expression resolveExpr)
{
if (expr is NamedExpression) {
@ -887,32 +889,54 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -887,32 +889,54 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResolveResult IAstVisitor<object, ResolveResult>.VisitAnonymousTypeCreateExpression(AnonymousTypeCreateExpression anonymousTypeCreateExpression, object data)
{
// 7.6.10.6 Anonymous object creation expressions
throw new NotImplementedException();
/*
if (resolver.ProjectContent == null) {
ScanChildren(anonymousTypeCreateExpression);
return errorResult;
}
var anonymousType = new DefaultTypeDefinition(resolver.ProjectContent, string.Empty, "$Anonymous$");
anonymousType.IsSynthetic = true;
resolver.PushInitializerType(anonymousType);
List<IUnresolvedProperty> properties = new List<IUnresolvedProperty>();
foreach (var expr in anonymousTypeCreateExpression.Initializers) {
Scan(expr);
Expression resolveExpr;
var name = GetAnonymousTypePropertyName(expr, out resolveExpr);
if (!string.IsNullOrEmpty(name)) {
var property = new DefaultProperty(anonymousType, name) {
var property = new DefaultUnresolvedProperty {
Name = name,
Accessibility = Accessibility.Public,
ReturnType = new VarTypeReference(this, resolver.Clone(), resolveExpr, false)
ReturnType = new VarTypeReference(this, resolver.Clone(), resolveExpr),
Getter = DefaultUnresolvedAccessor.GetFromAccessibility(Accessibility.Public)
};
anonymousType.Properties.Add(property);
properties.Add(property);
}
}
return new ResolveResult(new AnonymousType(resolver.Compilation, properties));
}
sealed class VarTypeReference : ITypeReference
{
readonly ResolveVisitor visitor;
readonly CSharpResolver storedContext;
readonly Expression expression;
IType result;
public VarTypeReference(ResolveVisitor visitor, CSharpResolver storedContext, Expression expression)
{
this.visitor = visitor;
this.storedContext = storedContext;
this.expression = expression;
}
public IType Resolve(ITypeResolveContext context)
{
lock (visitor) {
visitor.ResetContext(
storedContext,
delegate {
result = visitor.Resolve(expression).Type;
});
Debug.Assert(result != null);
return result;
}
Scan(expr);
}
ScanChildren(anonymousTypeCreateExpression);
resolver.PopInitializerType();
return new ResolveResult(anonymousType);*/
}
#endregion
#region Visit Expressions
ResolveResult IAstVisitor<object, ResolveResult>.VisitArrayCreateExpression(ArrayCreateExpression arrayCreateExpression, object data)
{
if (!resolverEnabled) {
@ -1331,11 +1355,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1331,11 +1355,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResolveResult IAstVisitor<object, ResolveResult>.VisitTypeOfExpression(TypeOfExpression typeOfExpression, object data)
{
ScanChildren(typeOfExpression);
if (resolverEnabled)
return new ResolveResult(KnownTypeReference.Type.Resolve(resolver.Compilation.TypeResolveContext));
else
if (resolverEnabled) {
return resolver.ResolveTypeOf(ResolveType(typeOfExpression.Type));
} else {
Scan(typeOfExpression.Type);
return null;
}
}
ResolveResult IAstVisitor<object, ResolveResult>.VisitTypeReferenceExpression(TypeReferenceExpression typeReferenceExpression, object data)
@ -1388,7 +1413,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1388,7 +1413,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
resultType = SpecialType.UnknownType;
break;
case UndocumentedExpressionType.RefType:
resultType = KnownTypeReference.Type.Resolve(resolver.Compilation.TypeResolveContext);
resultType = resolver.Compilation.FindType(KnownTypeCode.Type);
break;
case UndocumentedExpressionType.MakeRef:
resultType = resolver.Compilation.FindType(typeof(TypedReference));
@ -2197,9 +2222,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2197,9 +2222,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (resultType.Kind == TypeKind.Unknown)
return SpecialType.UnknownType;
if (resultType.Kind == TypeKind.Void)
return KnownTypeReference.Task.Resolve(resolver.Compilation.TypeResolveContext);
return resolver.Compilation.FindType(KnownTypeCode.Task);
ITypeDefinition def = KnownTypeReference.TaskOfT.Resolve(resolver.Compilation.TypeResolveContext).GetDefinition();
ITypeDefinition def = resolver.Compilation.FindType(KnownTypeCode.TaskOfT).GetDefinition();
if (def != null)
return new ParameterizedType(def, new[] { resultType });
else
@ -2647,24 +2672,225 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2647,24 +2672,225 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
IVariable MakeVariable(IType type, Identifier variableName)
{
throw new NotImplementedException();
return new SimpleVariable(MakeRegion(variableName), type, variableName.Name);
}
IVariable MakeVariable(AstType type, Identifier variableName)
{
throw new NotImplementedException();
return new ExplicitlyTypedVariable(this, resolver.Clone(), MakeRegion(variableName), type, variableName.Name, null);
}
IVariable MakeConstant(AstType type, Identifier variableName, Expression initializer)
{
throw new NotImplementedException();
return new ExplicitlyTypedVariable(this, resolver.Clone(), MakeRegion(variableName), type, variableName.Name, initializer);
}
IVariable MakeImplicitlyTypedVariable(Identifier variableName, Expression initializer, bool isForEach)
{
throw new NotImplementedException();
return new ImplicitlyTypedVariable(this, resolver.Clone(), MakeRegion(variableName), variableName.Name, initializer, isForEach);
}
sealed class SimpleVariable : IVariable
{
readonly DomRegion region;
readonly IType type;
readonly string name;
public SimpleVariable(DomRegion region, IType type, string name)
{
Debug.Assert(type != null);
Debug.Assert(name != null);
this.region = region;
this.type = type;
this.name = name;
}
string IVariable.Name {
get { return name; }
}
DomRegion IVariable.Region {
get { return region; }
}
IType IVariable.Type {
get { return type; }
}
bool IVariable.IsConst {
get { return false; }
}
object IVariable.ConstantValue {
get { return null; }
}
public override string ToString()
{
return type.ToString() + " " + name + ";";
}
}
sealed class ExplicitlyTypedVariable : IVariable
{
readonly ResolveVisitor visitor;
readonly CSharpResolver storedContext;
readonly DomRegion region;
readonly string name;
readonly AstType type;
volatile IType resolvedType;
readonly Expression constantInitializer;
bool constantValueCalculated;
object constantValue;
public ExplicitlyTypedVariable(ResolveVisitor visitor, CSharpResolver storedContext, DomRegion region, AstType type, string name, Expression constantInitializer)
{
Debug.Assert(visitor != null);
Debug.Assert(storedContext != null);
Debug.Assert(type != null);
Debug.Assert(name != null);
this.visitor = visitor;
this.storedContext = storedContext;
this.region = region;
this.type = type;
this.name = name;
this.constantInitializer = constantInitializer;
}
string IVariable.Name {
get { return name; }
}
DomRegion IVariable.Region {
get { return region; }
}
IType IVariable.Type {
get {
if (this.resolvedType == null) {
// This property might be accessed by user code outside the main resolver lock,
// so we need to acquire the lock again.
lock (visitor) {
if (this.resolvedType == null) {
visitor.ResetContext(
storedContext,
delegate {
this.resolvedType = visitor.ResolveType(type);
});
Debug.Assert(this.resolvedType != null);
}
}
}
return this.resolvedType;
}
}
bool IVariable.IsConst {
get { return constantInitializer != null; }
}
object IVariable.ConstantValue {
get {
// This property might be accessed by user code outside the main resolver lock,
// so we need to acquire the lock.
lock (visitor) {
if (!constantValueCalculated) {
visitor.ResetContext(
storedContext,
delegate {
this.constantValue = visitor.Resolve(constantInitializer).ConstantValue;
});
constantValueCalculated = true;
}
return constantValue;
}
}
}
public override string ToString()
{
if (constantInitializer != null)
return type.ToString() + " " + name + " = " + constantInitializer + ";";
else
return type.ToString() + " " + name + ";";
}
}
sealed class ImplicitlyTypedVariable : IVariable
{
readonly ResolveVisitor visitor;
readonly CSharpResolver storedContext;
readonly DomRegion region;
readonly string name;
readonly Expression initializer;
readonly bool isForEach;
volatile IType resolvedType;
public ImplicitlyTypedVariable(ResolveVisitor visitor, CSharpResolver storedContext, DomRegion region, string name, Expression initializer, bool isForEach)
{
Debug.Assert(visitor != null);
Debug.Assert(storedContext != null);
Debug.Assert(name != null);
Debug.Assert(initializer != null);
this.visitor = visitor;
this.storedContext = storedContext;
this.region = region;
this.name = name;
this.initializer = initializer;
this.isForEach = isForEach;
}
string IVariable.Name {
get { return name; }
}
DomRegion IVariable.Region {
get { return region; }
}
IType IVariable.Type {
get {
if (this.resolvedType == null) {
// This property might be accessed by user code outside the main resolver lock,
// so we need to acquire the lock again.
lock (visitor) {
if (this.resolvedType == null) {
visitor.ResetContext(
storedContext,
delegate {
var result = visitor.Resolve(initializer).Type;
if (isForEach) {
result = GetElementType(result, storedContext.Compilation, false);
}
this.resolvedType = result;
});
Debug.Assert(this.resolvedType != null);
}
}
}
return this.resolvedType;
}
}
bool IVariable.IsConst {
get { return false; }
}
object IVariable.ConstantValue {
get { return null; }
}
public override string ToString()
{
return "var " + name + (isForEach ? " in " : " = ") + initializer + ";";
}
}
/*
sealed class VarTypeReference : ITypeReference
{
ResolveVisitor visitor;
@ -2710,7 +2936,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2710,7 +2936,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return "var (not yet resolved)";
}
}
*/
static IType GetElementType(IType result, ICompilation compilation, bool allowIEnumerator)
{
bool foundNonGenericIEnumerable = false;
@ -2804,23 +3030,22 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2804,23 +3030,22 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return new TypeResolveResult(type);
}
ResolveResult HandleAttributeType(AstType astType)
{
throw new NotImplementedException();
}
ResolveResult IAstVisitor<object, ResolveResult>.VisitSimpleType(SimpleType simpleType, object data)
{
if (!resolverEnabled) {
ScanChildren(simpleType);
return null;
}
if (simpleType.Parent is Attribute) {
return HandleAttributeType(simpleType);
}
var typeArguments = GetTypeArguments(simpleType.TypeArguments);
return resolver.LookupSimpleNameOrTypeName(simpleType.Identifier, typeArguments, currentTypeLookupMode);
Identifier identifier = simpleType.IdentifierToken;
ResolveResult rr = resolver.LookupSimpleNameOrTypeName(identifier.Name, typeArguments, currentTypeLookupMode);
if (simpleType.Parent is Attribute && !identifier.IsVerbatim) {
var withSuffix = resolver.LookupSimpleNameOrTypeName(identifier.Name + "Attribute", typeArguments, currentTypeLookupMode);
if (AttributeTypeReference.PreferAttributeTypeWithSuffix(rr.Type, withSuffix.Type, resolver.Compilation))
return withSuffix;
}
return rr;
}
ResolveResult IAstVisitor<object, ResolveResult>.VisitMemberType(MemberType memberType, object data)
@ -2829,9 +3054,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2829,9 +3054,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ScanChildren(memberType);
return null;
}
if (memberType.Parent is Attribute) {
return HandleAttributeType(memberType);
}
ResolveResult target;
if (memberType.IsDoubleColon && memberType.Target is SimpleType) {
SimpleType t = (SimpleType)memberType.Target;
@ -2843,7 +3066,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2843,7 +3066,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
var typeArguments = GetTypeArguments(memberType.TypeArguments);
return resolver.ResolveMemberType(target, memberType.MemberName, typeArguments);
Identifier identifier = memberType.MemberNameToken;
ResolveResult rr = resolver.ResolveMemberType(target, identifier.Name, typeArguments);
if (memberType.Parent is Attribute && !identifier.IsVerbatim) {
var withSuffix = resolver.ResolveMemberType(target, identifier.Name + "Attribute", typeArguments);
if (AttributeTypeReference.PreferAttributeTypeWithSuffix(rr.Type, withSuffix.Type, resolver.Compilation))
return withSuffix;
}
return rr;
}
ResolveResult IAstVisitor<object, ResolveResult>.VisitComposedType(ComposedType composedType, object data)
@ -3177,6 +3407,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3177,6 +3407,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
else
groupParameterType = SpecialType.UnknownType;
StoreCurrentState(queryJoinClause.IntoIdentifierToken);
groupVariable = MakeVariable(groupParameterType, queryJoinClause.IntoIdentifierToken);
resolver.AddVariable(groupVariable);
}

77
ICSharpCode.NRefactory.CSharp/Resolver/TypeInference.cs

@ -793,7 +793,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -793,7 +793,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
Log.WriteCollection("GetBestCommonType() for ", expressions);
try {
DummyTypeParameter tp = new DummyTypeParameter(compilation);
ITypeParameter tp = DummyTypeParameter.GetMethodTypeParameter(0);
this.typeParameters = new TP[1] { new TP(tp) };
foreach (ResolveResult r in expressions) {
MakeOutputTypeInference(r, tp);
@ -804,81 +804,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -804,81 +804,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
Reset();
}
}
sealed class DummyTypeParameter : AbstractType, ITypeParameter
{
readonly ICompilation compilation;
public DummyTypeParameter(ICompilation compilation)
{
this.compilation = compilation;
}
ICompilation IResolved.Compilation {
get { return compilation; }
}
public override string Name {
get { return "X"; }
}
public override bool? IsReferenceType {
get { return null; }
}
public override TypeKind Kind {
get { return TypeKind.TypeParameter; }
}
public override ITypeReference ToTypeReference()
{
throw new NotSupportedException();
}
int ITypeParameter.Index {
get { return 0; }
}
IList<IAttribute> ITypeParameter.Attributes {
get { return EmptyList<IAttribute>.Instance; }
}
EntityType ITypeParameter.OwnerType {
get { return EntityType.Method; }
}
VarianceModifier ITypeParameter.Variance {
get { return VarianceModifier.Invariant; }
}
DomRegion ITypeParameter.Region {
get { return DomRegion.Empty; }
}
IEntity ITypeParameter.Owner {
get { return null; }
}
IType ITypeParameter.EffectiveBaseClass {
get { return SpecialType.UnknownType; }
}
IList<IType> ITypeParameter.EffectiveInterfaceSet {
get { return EmptyList<IType>.Instance; }
}
bool ITypeParameter.HasDefaultConstructorConstraint {
get { return false; }
}
bool ITypeParameter.HasReferenceTypeConstraint {
get { return false; }
}
bool ITypeParameter.HasValueTypeConstraint {
get { return false; }
}
}
#endregion
#region FindTypeInBounds

16
ICSharpCode.NRefactory.CSharp/TypeSystem/AttributeTypeReference.cs

@ -51,19 +51,23 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -51,19 +51,23 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
{
IType t1 = withoutSuffix.Resolve(context);
IType t2 = withSuffix.Resolve(context);
return PreferAttributeTypeWithSuffix(t1, t2, context.Compilation) ? t2 : t1;
}
internal static bool PreferAttributeTypeWithSuffix(IType t1, IType t2, ICompilation compilation)
{
if (t2.Kind == TypeKind.Unknown) return false;
if (t1.Kind == TypeKind.Unknown) return true;
if (t2.Kind == TypeKind.Unknown) return t1;
if (t1.Kind == TypeKind.Unknown) return t2;
var attrTypeDef = KnownTypeReference.Attribute.Resolve(context).GetDefinition();
var attrTypeDef = compilation.FindType(KnownTypeCode.Attribute).GetDefinition();
if (attrTypeDef != null) {
bool t1IsAttribute = (t1.GetDefinition() != null && t1.GetDefinition().IsDerivedFrom(attrTypeDef));
bool t2IsAttribute = (t2.GetDefinition() != null && t2.GetDefinition().IsDerivedFrom(attrTypeDef));
if (t2IsAttribute && !t1IsAttribute)
return t2;
return true;
// If both types exist and are attributes, C# considers that to be an ambiguity, but we are less strict.
}
return t1;
return false;
}
public override string ToString()

2
ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpUnresolvedTypeDefinition.cs

@ -31,12 +31,14 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -31,12 +31,14 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
: base(usingScope.NamespaceName, name)
{
this.usingScope = usingScope;
this.AddDefaultConstructorIfRequired = true;
}
public CSharpUnresolvedTypeDefinition(CSharpUnresolvedTypeDefinition declaringTypeDefinition, string name)
: base(declaringTypeDefinition, name)
{
this.usingScope = declaringTypeDefinition.usingScope;
this.AddDefaultConstructorIfRequired = true;
}
public override ITypeResolveContext CreateResolveContext(ITypeResolveContext parentContext)

36
ICSharpCode.NRefactory.CSharp/TypeSystem/ConstantValues.cs

@ -207,6 +207,42 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues @@ -207,6 +207,42 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues
}
}
[Serializable]
public sealed class TypeOfConstantExpression : ConstantExpression, ISupportsInterning
{
ITypeReference type;
public ITypeReference Type {
get { return type; }
}
public TypeOfConstantExpression(ITypeReference type)
{
this.type = type;
}
public override ResolveResult Resolve(CSharpResolver resolver)
{
return resolver.ResolveTypeOf(type.Resolve(resolver.CurrentTypeResolveContext));
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
type = provider.Intern(type);
}
int ISupportsInterning.GetHashCodeForInterning()
{
return type.GetHashCode();
}
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
{
TypeOfConstantExpression o = other as TypeOfConstantExpression;
return o != null && type == o.type;
}
}
[Serializable]
public sealed class ConstantCast : ConstantExpression, ISupportsInterning
{

51
ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs

@ -178,6 +178,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -178,6 +178,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
parsedFile.TopLevelTypeDefinitions.Add(newType);
}
newType.ParsedFile = parsedFile;
newType.HasExtensionMethods = false; // gets set to true when an extension method is added
return newType;
}
@ -417,12 +418,17 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -417,12 +418,17 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
ConvertAttributes(m.ReturnTypeAttributes, methodDeclaration.Attributes.Where(s => s.AttributeTarget == "return"));
ApplyModifiers(m, methodDeclaration.Modifiers);
m.IsExtensionMethod = methodDeclaration.IsExtensionMethod;
if (methodDeclaration.IsExtensionMethod) {
m.IsExtensionMethod = true;
currentTypeDefinition.HasExtensionMethods = true;
}
ConvertParameters(m.Parameters, methodDeclaration.Parameters);
if (!methodDeclaration.PrivateImplementationType.IsNull) {
m.Accessibility = Accessibility.None;
m.InterfaceImplementations.Add(ConvertInterfaceImplementation(methodDeclaration.PrivateImplementationType, m.Name));
m.InterfaceImplementations.Add(new DefaultMemberReference(
m.EntityType, ConvertType(methodDeclaration.PrivateImplementationType), m.Name,
m.TypeParameters.Count, GetParameterTypes(m.Parameters)));
}
currentTypeDefinition.Members.Add(m);
@ -433,6 +439,17 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -433,6 +439,17 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
return m;
}
IList<ITypeReference> GetParameterTypes(IList<IUnresolvedParameter> parameters)
{
if (parameters.Count == 0)
return EmptyList<ITypeReference>.Instance;
ITypeReference[] types = new ITypeReference[parameters.Count];
for (int i = 0; i < types.Length; i++) {
types[i] = parameters[i].Type;
}
return types;
}
bool InheritsConstraints(MethodDeclaration methodDeclaration)
{
// overrides and explicit interface implementations inherit constraints
@ -480,10 +497,14 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -480,10 +497,14 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
}
}
IMemberReference ConvertInterfaceImplementation(AstType interfaceType, string memberName)
IMemberReference ConvertInterfaceImplementation(AstType interfaceType, AbstractUnresolvedMember unresolvedMember)
{
throw new NotImplementedException();
//return new DefaultExplicitInterfaceImplementation(ConvertType(interfaceType), memberName);
ITypeReference interfaceTypeReference = ConvertType(interfaceType);
if (unresolvedMember.EntityType == EntityType.Method || unresolvedMember.EntityType == EntityType.Indexer) {
throw new NotImplementedException();
} else {
return new DefaultMemberReference(unresolvedMember.EntityType, ConvertType(interfaceType), unresolvedMember.Name);
}
}
#endregion
@ -574,7 +595,8 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -574,7 +595,8 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
ConvertAttributes(p.Attributes, propertyDeclaration.Attributes);
if (!propertyDeclaration.PrivateImplementationType.IsNull) {
p.Accessibility = Accessibility.None;
p.InterfaceImplementations.Add(ConvertInterfaceImplementation(propertyDeclaration.PrivateImplementationType, p.Name));
p.InterfaceImplementations.Add(new DefaultMemberReference(
p.EntityType, ConvertType(propertyDeclaration.PrivateImplementationType), p.Name));
}
p.Getter = ConvertAccessor(propertyDeclaration.Getter, p.Accessibility);
p.Setter = ConvertAccessor(propertyDeclaration.Setter, p.Accessibility);
@ -594,13 +616,17 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -594,13 +616,17 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
ApplyModifiers(p, indexerDeclaration.Modifiers);
p.ReturnType = ConvertType(indexerDeclaration.ReturnType);
ConvertAttributes(p.Attributes, indexerDeclaration.Attributes);
if (!indexerDeclaration.PrivateImplementationType.IsNull) {
p.Accessibility = Accessibility.None;
p.InterfaceImplementations.Add(ConvertInterfaceImplementation(indexerDeclaration.PrivateImplementationType, p.Name));
}
p.Getter = ConvertAccessor(indexerDeclaration.Getter, p.Accessibility);
p.Setter = ConvertAccessor(indexerDeclaration.Setter, p.Accessibility);
ConvertParameters(p.Parameters, indexerDeclaration.Parameters);
if (!indexerDeclaration.PrivateImplementationType.IsNull) {
p.Accessibility = Accessibility.None;
p.InterfaceImplementations.Add(new DefaultMemberReference(
p.EntityType, ConvertType(indexerDeclaration.PrivateImplementationType), p.Name, 0, GetParameterTypes(p.Parameters)));
}
currentTypeDefinition.Members.Add(p);
if (interningProvider != null) {
p.ApplyInterningProvider(interningProvider);
@ -676,7 +702,8 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -676,7 +702,8 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
if (!eventDeclaration.PrivateImplementationType.IsNull) {
e.Accessibility = Accessibility.None;
e.InterfaceImplementations.Add(ConvertInterfaceImplementation(eventDeclaration.PrivateImplementationType, e.Name));
e.InterfaceImplementations.Add(new DefaultMemberReference(
e.EntityType, ConvertType(eventDeclaration.PrivateImplementationType), e.Name));
}
e.AddAccessor = ConvertAccessor(eventDeclaration.AddAccessor, e.Accessibility);
@ -1071,7 +1098,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -1071,7 +1098,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
public override ConstantExpression VisitTypeOfExpression(TypeOfExpression typeOfExpression, object data)
{
if (isAttributeArgument) {
return new PrimitiveConstantExpression(KnownTypeReference.Type, ConvertType(typeOfExpression.Type));
return new TypeOfConstantExpression(ConvertType(typeOfExpression.Type));
} else {
return null;
}

10
ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseSelfTests.cs

@ -54,7 +54,15 @@ namespace ICSharpCode.NRefactory.CSharp.Parser @@ -54,7 +54,15 @@ namespace ICSharpCode.NRefactory.CSharp.Parser
using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.SequentialScan)) {
cu = parser.Parse(fs);
}
pc = pc.UpdateProjectContent(null, cu.ToTypeSystem(fileName));
var parsedFile = cu.ToTypeSystem(fileName);
foreach (var td in parsedFile.GetAllTypeDefinitions()) {
Assert.AreSame(parsedFile, td.ParsedFile);
foreach (var member in td.Members) {
Assert.AreSame(parsedFile, member.ParsedFile);
Assert.AreSame(td, member.DeclaringTypeDefinition);
}
}
pc = pc.UpdateProjectContent(null, parsedFile);
}
}

5
ICSharpCode.NRefactory.Tests/CSharp/Refactoring/TypeSystemAstBuilderTests.cs

@ -62,6 +62,7 @@ namespace OtherNS { @@ -62,6 +62,7 @@ namespace OtherNS {
public void SetUp()
{
pc = new CSharpProjectContent();
pc = pc.SetAssemblyName("MyAssembly");
parsedFile = new CSharpParser().Parse(new StringReader(program)).ToTypeSystem("program.cs");
pc = pc.UpdateProjectContent(null, parsedFile);
pc = pc.AddAssemblyReferences(new [] { CecilLoaderTests.Mscorlib });
@ -71,7 +72,7 @@ namespace OtherNS { @@ -71,7 +72,7 @@ namespace OtherNS {
baseClass = compilation.RootNamespace.GetTypeDefinition("Base", 1);
nestedClass = baseClass.NestedTypes.Single();
derivedClass = compilation.RootNamespace.GetTypeDefinition("Derived", 2);
systemClass = compilation.FindType("NS.System").GetDefinition();
systemClass = compilation.FindType("NS.System, MyAssembly").GetDefinition();
}
TypeSystemAstBuilder CreateBuilder(ITypeDefinition currentTypeDef = null)
@ -207,7 +208,7 @@ namespace OtherNS { @@ -207,7 +208,7 @@ namespace OtherNS {
public void AmbiguousType()
{
Assert.AreEqual("System.Array", TypeToString(compilation.FindType(typeof(Array))));
Assert.AreEqual("OtherNS.Array", TypeToString(compilation.FindType("OtherNS.Array")));
Assert.AreEqual("OtherNS.Array", TypeToString(compilation.FindType("OtherNS.Array, MyAssembly")));
}
}
}

4
ICSharpCode.NRefactory.Tests/CSharp/Resolver/AttributeTests.cs

@ -108,8 +108,8 @@ enum E { A, B } @@ -108,8 +108,8 @@ enum E { A, B }
{
string program = @"using System;
class Flags {
[Flags]
enum $Test$ { }
$[Flags]
enum Test { }$
}";
TypeResolveResult result = Resolve<TypeResolveResult>(program);
Assert.AreEqual("Flags.Test", result.Type.FullName);

4
ICSharpCode.NRefactory.Tests/CSharp/Resolver/BinaryOperatorTests.cs

@ -515,10 +515,10 @@ class Test { @@ -515,10 +515,10 @@ class Test {
var irr = Resolve<CSharpInvocationResolveResult>(program);
Assert.IsFalse(irr.IsError);
Assert.IsTrue(irr.IsLiftedOperatorInvocation);
Assert.IsTrue(irr.Member is OverloadResolution.ILiftedOperator);
Assert.AreEqual("A.op_Addition", irr.Member.FullName);
// even though we're calling the lifted operator, trr.Member should be the original operator method
Assert.AreEqual("S", irr.Member.ReturnType.ReflectionName);
Assert.AreEqual("System.Nullable`1[[S]]", irr.Type.ReflectionName);
Assert.AreEqual("System.Nullable`1[[S]]", irr.Member.ReturnType.ReflectionName);
Conversion lhsConv = ((ConversionResolveResult)irr.Arguments[0]).Conversion;
Conversion rhsConv = ((ConversionResolveResult)irr.Arguments[1]).Conversion;

18
ICSharpCode.NRefactory.Tests/CSharp/Resolver/ConversionsTest.cs

@ -253,9 +253,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -253,9 +253,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test]
public void UnconstrainedTypeParameter()
{
ITypeParameter t = new DefaultTypeParameter(EntityType.TypeDefinition, 0, "T");
ITypeParameter t2 = new DefaultTypeParameter(EntityType.TypeDefinition, 1, "T2");
ITypeParameter tm = new DefaultTypeParameter(EntityType.Method, 0, "TM");
ITypeParameter t = new DefaultTypeParameter(compilation, EntityType.TypeDefinition, 0, "T");
ITypeParameter t2 = new DefaultTypeParameter(compilation, EntityType.TypeDefinition, 1, "T2");
ITypeParameter tm = new DefaultTypeParameter(compilation, EntityType.Method, 0, "TM");
Assert.AreEqual(C.None, conversions.ImplicitConversion(SpecialType.NullType, t));
Assert.AreEqual(C.BoxingConversion, conversions.ImplicitConversion(t, compilation.FindType(KnownTypeCode.Object)));
@ -272,7 +272,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -272,7 +272,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test]
public void TypeParameterWithReferenceTypeConstraint()
{
ITypeParameter t = new DefaultTypeParameter(EntityType.TypeDefinition, 0, "T", hasReferenceTypeConstraint: true);
ITypeParameter t = new DefaultTypeParameter(compilation, EntityType.TypeDefinition, 0, "T", hasReferenceTypeConstraint: true);
Assert.AreEqual(C.NullLiteralConversion, conversions.ImplicitConversion(SpecialType.NullType, t));
Assert.AreEqual(C.ImplicitReferenceConversion, conversions.ImplicitConversion(t, compilation.FindType(KnownTypeCode.Object)));
@ -283,7 +283,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -283,7 +283,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test]
public void TypeParameterWithValueTypeConstraint()
{
ITypeParameter t = new DefaultTypeParameter(EntityType.TypeDefinition, 0, "T", hasValueTypeConstraint: true);
ITypeParameter t = new DefaultTypeParameter(compilation, EntityType.TypeDefinition, 0, "T", hasValueTypeConstraint: true);
Assert.AreEqual(C.None, conversions.ImplicitConversion(SpecialType.NullType, t));
Assert.AreEqual(C.BoxingConversion, conversions.ImplicitConversion(t, compilation.FindType(KnownTypeCode.Object)));
@ -294,8 +294,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -294,8 +294,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test]
public void TypeParameterWithClassConstraint()
{
ITypeParameter t = new DefaultTypeParameter(EntityType.TypeDefinition, 0, "T",
constraints: new[] { compilation.FindType(typeof(StringComparer)) });
ITypeParameter t = new DefaultTypeParameter(compilation, EntityType.TypeDefinition, 0, "T",
constraints: new[] { compilation.FindType(typeof(StringComparer)) });
Assert.AreEqual(C.NullLiteralConversion,
conversions.ImplicitConversion(SpecialType.NullType, t));
@ -316,8 +316,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -316,8 +316,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test]
public void TypeParameterWithInterfaceConstraint()
{
ITypeParameter t = new DefaultTypeParameter(EntityType.TypeDefinition, 0, "T",
constraints: new [] { compilation.FindType(typeof(IList)) });
ITypeParameter t = new DefaultTypeParameter(compilation, EntityType.TypeDefinition, 0, "T",
constraints: new [] { compilation.FindType(typeof(IList)) });
Assert.AreEqual(C.None, conversions.ImplicitConversion(SpecialType.NullType, t));
Assert.AreEqual(C.BoxingConversion,

9
ICSharpCode.NRefactory.Tests/CSharp/Resolver/MemberLookupTests.cs

@ -60,7 +60,8 @@ class Middle : Base { @@ -60,7 +60,8 @@ class Middle : Base {
class Derived : Middle {
public override void Method() {}
}";
ITypeDefinition derived = compilation.MainAssembly.GetTypeDefinition(Parse(program).TopLevelTypeDefinitions[2]);
var parsedFile = Parse(program);
ITypeDefinition derived = compilation.MainAssembly.GetTypeDefinition(parsedFile.TopLevelTypeDefinitions[2]);
var rr = lookup.Lookup(new ResolveResult(derived), "Method", EmptyList<IType>.Instance, true) as MethodGroupResolveResult;
Assert.AreEqual(2, rr.MethodsGroupedByDeclaringType.Count());
@ -86,7 +87,8 @@ class Derived : Base<int> { @@ -86,7 +87,8 @@ class Derived : Base<int> {
public override void Method(int a) {}
public override void Method(string a) {}
}";
ITypeDefinition derived = compilation.MainAssembly.GetTypeDefinition(Parse(program).TopLevelTypeDefinitions[1]);
var parsedFile = Parse(program);
ITypeDefinition derived = compilation.MainAssembly.GetTypeDefinition(parsedFile.TopLevelTypeDefinitions[1]);
var rr = lookup.Lookup(new ResolveResult(derived), "Method", EmptyList<IType>.Instance, true) as MethodGroupResolveResult;
Assert.AreEqual(2, rr.MethodsGroupedByDeclaringType.Count());
@ -113,7 +115,8 @@ class Base { @@ -113,7 +115,8 @@ class Base {
class Derived : Base {
public override void Method<S>(S a) {}
}";
ITypeDefinition derived = compilation.MainAssembly.GetTypeDefinition(Parse(program).TopLevelTypeDefinitions[1]);
var parsedFile = Parse(program);
ITypeDefinition derived = compilation.MainAssembly.GetTypeDefinition(parsedFile.TopLevelTypeDefinitions[1]);
var rr = lookup.Lookup(new ResolveResult(derived), "Method", EmptyList<IType>.Instance, true) as MethodGroupResolveResult;
Assert.AreEqual(1, rr.MethodsGroupedByDeclaringType.Count());

6
ICSharpCode.NRefactory.Tests/CSharp/Resolver/NameLookupTests.cs

@ -133,9 +133,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -133,9 +133,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public void AliasToImportedType()
{
resolver.CurrentUsingScope = MakeUsingScope(usings: new [] { "System" }, usingAliases: new [] { new KeyValuePair<string, string>( "x", "String" )});
TypeResolveResult trr = (TypeResolveResult)resolver.ResolveSimpleName("x", new IType[0]);
// Unknown type (as String isn't looked up in System)
Assert.AreSame(SpecialType.UnknownType, trr.Type);
UnknownIdentifierResolveResult rr = (UnknownIdentifierResolveResult)resolver.ResolveSimpleName("x", new IType[0]);
// Unknown identifier (as String isn't looked up in System)
Assert.AreEqual("String", rr.Identifier);
}
[Test]

112
ICSharpCode.NRefactory.Tests/CSharp/Resolver/OverloadResolutionTests.cs

@ -31,25 +31,30 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -31,25 +31,30 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[TestFixture]
public class OverloadResolutionTests
{
/*
readonly ICompilation compilation = new SimpleCompilation(
CecilLoaderTests.SystemCore, new[] { CecilLoaderTests.Mscorlib });
readonly DefaultTypeDefinition dummyClass = new DefaultTypeDefinition(CecilLoaderTests.Mscorlib, string.Empty, "DummyClass");
ResolveResult[] MakeArgumentList(params Type[] argumentTypes)
{
return argumentTypes.Select(t => new ResolveResult(t.ToTypeReference().Resolve(context))).ToArray();
return argumentTypes.Select(t => new ResolveResult(compilation.FindType(t))).ToArray();
}
DefaultMethod MakeMethod(params object[] parameterTypesOrDefaultValues)
IMethod MakeMethod(params object[] parameterTypesOrDefaultValues)
{
DefaultMethod m = new DefaultMethod(dummyClass, "Method");
var context = new SimpleTypeResolveContext(compilation.MainAssembly);
return (IMethod)MakeUnresolvedMethod(parameterTypesOrDefaultValues).CreateResolved(context);
}
DefaultUnresolvedMethod MakeUnresolvedMethod(params object[] parameterTypesOrDefaultValues)
{
var m = new DefaultUnresolvedMethod();
m.Name = "Method";
foreach (var typeOrDefaultValue in parameterTypesOrDefaultValues) {
Type type = typeOrDefaultValue as Type;
if (type != null)
m.Parameters.Add(new DefaultParameter(type.ToTypeReference(), string.Empty));
m.Parameters.Add(new DefaultUnresolvedParameter(type.ToTypeReference(), string.Empty));
else if (Type.GetTypeCode(typeOrDefaultValue.GetType()) > TypeCode.Object)
m.Parameters.Add(new DefaultParameter(typeOrDefaultValue.GetType().ToTypeReference(), string.Empty) {
m.Parameters.Add(new DefaultUnresolvedParameter(typeOrDefaultValue.GetType().ToTypeReference(), string.Empty) {
DefaultValue = new SimpleConstantValue(typeOrDefaultValue.GetType().ToTypeReference(), typeOrDefaultValue)
});
else
@ -58,16 +63,17 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -58,16 +63,17 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return m;
}
DefaultMethod MakeParamsMethod(params object[] parameterTypesOrDefaultValues)
IMethod MakeParamsMethod(params object[] parameterTypesOrDefaultValues)
{
DefaultMethod m = MakeMethod(parameterTypesOrDefaultValues);
((DefaultParameter)m.Parameters.Last()).IsParams = true;
return m;
var m = MakeUnresolvedMethod(parameterTypesOrDefaultValues);
((DefaultUnresolvedParameter)m.Parameters.Last()).IsParams = true;
var context = new SimpleTypeResolveContext(compilation.MainAssembly);
return (IMethod)m.CreateResolved(context);
}
DefaultParameter MakeOptionalParameter(IType type, string name)
IUnresolvedParameter MakeOptionalParameter(ITypeReference type, string name)
{
return new DefaultParameter(type, name) {
return new DefaultUnresolvedParameter(type, name) {
DefaultValue = new SimpleConstantValue(type, null)
};
}
@ -75,7 +81,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -75,7 +81,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test]
public void PreferIntOverUInt()
{
OverloadResolution r = new OverloadResolution(context, MakeArgumentList(typeof(ushort)));
OverloadResolution r = new OverloadResolution(compilation, MakeArgumentList(typeof(ushort)));
var c1 = MakeMethod(typeof(int));
Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(c1));
Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(MakeMethod(typeof(uint))));
@ -86,7 +92,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -86,7 +92,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test]
public void NullableIntAndNullableUIntIsAmbiguous()
{
OverloadResolution r = new OverloadResolution(context, MakeArgumentList(typeof(ushort?)));
OverloadResolution r = new OverloadResolution(compilation, MakeArgumentList(typeof(ushort?)));
Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(MakeMethod(typeof(int?))));
Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(MakeMethod(typeof(uint?))));
Assert.AreEqual(OverloadResolutionErrors.AmbiguousMatch, r.BestCandidateErrors);
@ -100,7 +106,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -100,7 +106,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test]
public void ParamsMethodMatchesEmptyArgumentList()
{
OverloadResolution r = new OverloadResolution(context, MakeArgumentList());
OverloadResolution r = new OverloadResolution(compilation, MakeArgumentList());
Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(MakeParamsMethod(typeof(int[]))));
Assert.IsTrue(r.BestCandidateIsExpandedForm);
}
@ -108,7 +114,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -108,7 +114,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test]
public void ParamsMethodMatchesOneArgumentInExpandedForm()
{
OverloadResolution r = new OverloadResolution(context, MakeArgumentList(typeof(int)));
OverloadResolution r = new OverloadResolution(compilation, MakeArgumentList(typeof(int)));
Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(MakeParamsMethod(typeof(int[]))));
Assert.IsTrue(r.BestCandidateIsExpandedForm);
}
@ -116,7 +122,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -116,7 +122,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test]
public void ParamsMethodMatchesInUnexpandedForm()
{
OverloadResolution r = new OverloadResolution(context, MakeArgumentList(typeof(int[])));
OverloadResolution r = new OverloadResolution(compilation, MakeArgumentList(typeof(int[])));
Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(MakeParamsMethod(typeof(int[]))));
Assert.IsFalse(r.BestCandidateIsExpandedForm);
}
@ -124,7 +130,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -124,7 +130,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test]
public void LessArgumentsPassedToParamsIsBetter()
{
OverloadResolution r = new OverloadResolution(context, MakeArgumentList(typeof(int), typeof(int), typeof(int)));
OverloadResolution r = new OverloadResolution(compilation, MakeArgumentList(typeof(int), typeof(int), typeof(int)));
Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(MakeParamsMethod(typeof(int[]))));
Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(MakeParamsMethod(typeof(int), typeof(int[]))));
Assert.IsFalse(r.IsAmbiguous);
@ -134,7 +140,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -134,7 +140,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test]
public void CallInvalidParamsDeclaration()
{
OverloadResolution r = new OverloadResolution(context, MakeArgumentList(typeof(int[,])));
OverloadResolution r = new OverloadResolution(compilation, MakeArgumentList(typeof(int[,])));
Assert.AreEqual(OverloadResolutionErrors.ArgumentTypeMismatch, r.AddCandidate(MakeParamsMethod(typeof(int))));
Assert.IsFalse(r.BestCandidateIsExpandedForm);
}
@ -145,7 +151,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -145,7 +151,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
var m1 = MakeMethod();
var m2 = MakeMethod(1);
OverloadResolution r = new OverloadResolution(context, MakeArgumentList());
OverloadResolution r = new OverloadResolution(compilation, MakeArgumentList());
Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(m1));
Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(m2));
Assert.IsFalse(r.IsAmbiguous);
@ -158,49 +164,54 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -158,49 +164,54 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
// http://msmvps.com/blogs/jon_skeet/archive/2010/11/02/evil-code-overload-resolution-workaround.aspx
// static void Foo<T>(T? ignored = default(T?)) where T : struct
var m1 = MakeMethod();
m1.TypeParameters.Add(new DefaultTypeParameter(EntityType.Method, 0, "T") { HasValueTypeConstraint = true });
var m1 = MakeUnresolvedMethod();
m1.TypeParameters.Add(new DefaultUnresolvedTypeParameter(EntityType.Method, 0, "T") { HasValueTypeConstraint = true });
m1.Parameters.Add(MakeOptionalParameter(
NullableType.Create(m1.TypeParameters[0], context),
NullableType.Create(new TypeParameterReference(EntityType.Method, 0)),
"ignored"
));
// class ClassConstraint<T> where T : class {}
DefaultTypeDefinition classConstraint = new DefaultTypeDefinition(dummyClass, "ClassConstraint");
classConstraint.TypeParameters.Add(new DefaultTypeParameter(EntityType.TypeDefinition, 0, "T") { HasReferenceTypeConstraint = true });
var classConstraint = new DefaultUnresolvedTypeDefinition(string.Empty, "ClassConstraint");
classConstraint.TypeParameters.Add(new DefaultUnresolvedTypeParameter(EntityType.TypeDefinition, 0, "T") { HasReferenceTypeConstraint = true });
// static void Foo<T>(ClassConstraint<T> ignored = default(ClassConstraint<T>))
// where T : class
var m2 = MakeMethod();
m2.TypeParameters.Add(new DefaultTypeParameter(EntityType.Method, 0, "T") { HasReferenceTypeConstraint = true });
var m2 = MakeUnresolvedMethod();
m2.TypeParameters.Add(new DefaultUnresolvedTypeParameter(EntityType.Method, 0, "T") { HasReferenceTypeConstraint = true });
m2.Parameters.Add(MakeOptionalParameter(
new ParameterizedType(classConstraint, new[] { m2.TypeParameters[0] }),
new ParameterizedTypeReference(classConstraint, new[] { new TypeParameterReference(EntityType.Method, 0) }),
"ignored"
));
// static void Foo<T>()
var m3 = MakeMethod();
m3.TypeParameters.Add(new DefaultTypeParameter(EntityType.Method, 0, "T"));
var m3 = MakeUnresolvedMethod();
m3.TypeParameters.Add(new DefaultUnresolvedTypeParameter(EntityType.Method, 0, "T"));
var context = new SimpleTypeResolveContext(compilation.MainAssembly);
IMethod resolvedM1 = (IMethod)m1.CreateResolved(context);
IMethod resolvedM2 = (IMethod)m2.CreateResolved(context);
IMethod resolvedM3 = (IMethod)m3.CreateResolved(context);
// Call: Foo<int>();
OverloadResolution o;
o = new OverloadResolution(context, new ResolveResult[0], typeArguments: new[] { typeof(int).ToTypeReference().Resolve(context) });
Assert.AreEqual(OverloadResolutionErrors.None, o.AddCandidate(m1));
Assert.AreEqual(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint, o.AddCandidate(m2));
Assert.AreSame(m1, o.BestCandidate);
o = new OverloadResolution(compilation, new ResolveResult[0], typeArguments: new[] { compilation.FindType(typeof(int)) });
Assert.AreEqual(OverloadResolutionErrors.None, o.AddCandidate(resolvedM1));
Assert.AreEqual(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint, o.AddCandidate(resolvedM2));
Assert.AreSame(resolvedM1, o.BestCandidate);
// Call: Foo<string>();
o = new OverloadResolution(context, new ResolveResult[0], typeArguments: new[] { typeof(string).ToTypeReference().Resolve(context) });
Assert.AreEqual(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint, o.AddCandidate(m1));
Assert.AreEqual(OverloadResolutionErrors.None, o.AddCandidate(m2));
Assert.AreSame(m2, o.BestCandidate);
o = new OverloadResolution(compilation, new ResolveResult[0], typeArguments: new[] { compilation.FindType(typeof(string)) });
Assert.AreEqual(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint, o.AddCandidate(resolvedM1));
Assert.AreEqual(OverloadResolutionErrors.None, o.AddCandidate(resolvedM2));
Assert.AreSame(resolvedM2, o.BestCandidate);
// Call: Foo<int?>();
o = new OverloadResolution(context, new ResolveResult[0], typeArguments: new[] { typeof(int?).ToTypeReference().Resolve(context) });
Assert.AreEqual(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint, o.AddCandidate(m1));
Assert.AreEqual(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint, o.AddCandidate(m2));
Assert.AreEqual(OverloadResolutionErrors.None, o.AddCandidate(m3));
Assert.AreSame(m3, o.BestCandidate);
o = new OverloadResolution(compilation, new ResolveResult[0], typeArguments: new[] { compilation.FindType(typeof(int?)) });
Assert.AreEqual(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint, o.AddCandidate(resolvedM1));
Assert.AreEqual(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint, o.AddCandidate(resolvedM2));
Assert.AreEqual(OverloadResolutionErrors.None, o.AddCandidate(resolvedM3));
Assert.AreSame(resolvedM3, o.BestCandidate);
}
/// <summary>
@ -259,10 +270,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -259,10 +270,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
// M(() => default(byte));
ResolveResult[] args = {
new MockLambda(KnownTypeReference.Byte.Resolve(context))
new MockLambda(compilation.FindType(KnownTypeCode.Byte))
};
OverloadResolution r = new OverloadResolution(context, args);
OverloadResolution r = new OverloadResolution(compilation, args);
Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(m1));
Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(m2));
Assert.AreSame(m2, r.BestCandidate);
@ -277,10 +288,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -277,10 +288,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
// M(() => default(byte));
ResolveResult[] args = {
new MockLambda(KnownTypeReference.Byte.Resolve(context))
new MockLambda(compilation.FindType(KnownTypeCode.Byte))
};
OverloadResolution r = new OverloadResolution(context, args);
OverloadResolution r = new OverloadResolution(compilation, args);
Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(m1));
Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(m2));
Assert.AreSame(m2, r.BestCandidate);
@ -295,14 +306,13 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -295,14 +306,13 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
// M(() => default(int));
ResolveResult[] args = {
new MockLambda(KnownTypeReference.Int32.Resolve(context))
new MockLambda(compilation.FindType(KnownTypeCode.Int32))
};
OverloadResolution r = new OverloadResolution(context, args);
OverloadResolution r = new OverloadResolution(compilation, args);
Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(m1));
Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(m2));
Assert.AreEqual(OverloadResolutionErrors.AmbiguousMatch, r.BestCandidateErrors);
}
*/
}
}

2
ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs

@ -42,7 +42,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -42,7 +42,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[SetUp]
public virtual void SetUp()
{
project = new CSharpProjectContent().AddAssemblyReferences(new [] { mscorlib });
project = new CSharpProjectContent().AddAssemblyReferences(new [] { mscorlib, CecilLoaderTests.SystemCore });
compilation = project.CreateCompilation();
}

20
ICSharpCode.NRefactory.Tests/CSharp/Resolver/TypeInferenceTests.cs

@ -56,7 +56,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -56,7 +56,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test]
public void ArrayToEnumerable()
{
ITypeParameter tp = new DefaultTypeParameter(EntityType.Method, 0, "T");
ITypeParameter tp = new DefaultTypeParameter(compilation, EntityType.Method, 0, "T");
IType stringType = compilation.FindType(KnownTypeCode.String);
ITypeDefinition enumerableType = compilation.FindType(KnownTypeCode.IEnumerableOfT).GetDefinition();
@ -73,7 +73,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -73,7 +73,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test]
public void EnumerableToArrayInContravariantType()
{
ITypeParameter tp = new DefaultTypeParameter(EntityType.Method, 0, "T");
ITypeParameter tp = new DefaultTypeParameter(compilation, EntityType.Method, 0, "T");
IType stringType = compilation.FindType(KnownTypeCode.String);
ITypeDefinition enumerableType = compilation.FindType(typeof(IEnumerable<>)).GetDefinition();
ITypeDefinition comparerType = compilation.FindType(typeof(IComparer<>)).GetDefinition();
@ -98,8 +98,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -98,8 +98,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
{
// static void M<A, B>(Func<A, B> f) {}
// M(int.Parse); // type inference fails
var A = new DefaultTypeParameter(EntityType.Method, 0, "A");
var B = new DefaultTypeParameter(EntityType.Method, 1, "B");
var A = new DefaultTypeParameter(compilation, EntityType.Method, 0, "A");
var B = new DefaultTypeParameter(compilation, EntityType.Method, 1, "B");
IType declType = compilation.FindType(typeof(int));
var methods = new MethodListWithDeclaringType(declType, declType.GetMethods(m => m.Name == "Parse"));
@ -118,7 +118,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -118,7 +118,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
// static void M<T>(Func<T> f) {}
// M(Console.ReadKey); // type inference produces ConsoleKeyInfo
var T = new DefaultTypeParameter(EntityType.Method, 0, "T");
var T = new DefaultTypeParameter(compilation, EntityType.Method, 0, "T");
IType declType = compilation.FindType(typeof(Console));
var methods = new MethodListWithDeclaringType(declType, declType.GetMethods(m => m.Name == "ReadKey"));
@ -200,9 +200,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -200,9 +200,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public void TestLambdaInference()
{
ITypeParameter[] typeParameters = {
new DefaultTypeParameter(EntityType.Method, 0, "X"),
new DefaultTypeParameter(EntityType.Method, 1, "Y"),
new DefaultTypeParameter(EntityType.Method, 2, "Z")
new DefaultTypeParameter(compilation, EntityType.Method, 0, "X"),
new DefaultTypeParameter(compilation, EntityType.Method, 1, "Y"),
new DefaultTypeParameter(compilation, EntityType.Method, 2, "Z")
};
IType[] parameterTypes = {
typeParameters[0],
@ -230,8 +230,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -230,8 +230,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test]
public void ConvertAllLambdaInference()
{
ITypeParameter[] classTypeParameters = { new DefaultTypeParameter(EntityType.TypeDefinition, 0, "T") };
ITypeParameter[] methodTypeParameters = { new DefaultTypeParameter(EntityType.Method, 0, "R") };
ITypeParameter[] classTypeParameters = { new DefaultTypeParameter(compilation, EntityType.TypeDefinition, 0, "T") };
ITypeParameter[] methodTypeParameters = { new DefaultTypeParameter(compilation, EntityType.Method, 0, "R") };
IType[] parameterTypes = {
new ParameterizedType(compilation.FindType(typeof(Converter<,>)).GetDefinition(),

2
ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.TestCase.cs

@ -40,7 +40,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.TestCase @@ -40,7 +40,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.TestCase
public TypeTestAttribute(int a1, Type a2, Type a3) {}
}
[Params(1, StringComparison.CurrentCulture, null, 4.0)]
[Params(1, StringComparison.CurrentCulture, null, 4.0, "Test")]
public class ParamsAttribute : Attribute
{
public ParamsAttribute(params object[] x) {}

69
ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.cs

@ -528,24 +528,63 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -528,24 +528,63 @@ namespace ICSharpCode.NRefactory.TypeSystem
Assert.AreEqual("ICSharpCode.NRefactory.TypeSystem.TestCase.OuterGeneric`1+Inner[[ICSharpCode.NRefactory.TypeSystem.TestCase.OuterGeneric`1+Inner[[`0]]]]", field3.Type.ReflectionName);
}
[Test]
public void ParamsAttributeTest()
ResolveResult GetParamsAttributeArgument(int index)
{
ITypeDefinition type = GetTypeDefinition(typeof(ParamsAttribute)).GetDefinition();
var arr = (ArrayCreateResolveResult)type.Attributes.Single().PositionalArguments.Single();
Assert.AreEqual(4, arr.InitializerElements.Length);
Assert.AreEqual("System.Int32", arr.InitializerElements[0].Type.FullName);
Assert.AreEqual(1, arr.InitializerElements[0].ConstantValue);
Assert.AreEqual("System.StringComparison", arr.InitializerElements[1].Type.FullName);
Assert.AreEqual((int)StringComparison.CurrentCulture, arr.InitializerElements[1].ConstantValue);
Assert.AreEqual("System.String", arr.InitializerElements[2].Type.FullName);
Assert.IsNull(arr.InitializerElements[2].ConstantValue);
Assert.AreEqual("System.Double", arr.InitializerElements[3].Type.FullName);
Assert.AreEqual(4.0, arr.InitializerElements[3].ConstantValue);
Assert.AreEqual(5, arr.InitializerElements.Length);
return arr.InitializerElements[index];
}
ResolveResult Unbox(ResolveResult resolveResult)
{
ConversionResolveResult crr = (ConversionResolveResult)resolveResult;
Assert.AreEqual(TypeKind.Class, crr.Type.Kind);
Assert.AreEqual("System.Object", crr.Type.FullName);
Assert.AreEqual(Conversion.BoxingConversion, crr.Conversion);
return crr.Input;
}
[Test, Ignore("CecilLoader does not create ConversionResolveResult")]
public void ParamsAttribute_Integer()
{
ResolveResult rr = Unbox(GetParamsAttributeArgument(0));
Assert.AreEqual("System.Int32", rr.Type.FullName);
Assert.AreEqual(1, rr.ConstantValue);
}
[Test, Ignore("CecilLoader does not create ConversionResolveResult")]
public void ParamsAttribute_Enum()
{
ResolveResult rr = Unbox(GetParamsAttributeArgument(1));
Assert.AreEqual("System.StringComparison", rr.Type.FullName);
Assert.AreEqual((int)StringComparison.CurrentCulture, rr.ConstantValue);
}
[Test, Ignore("CecilLoader does not create ConversionResolveResult")]
public void ParamsAttribute_NullReference()
{
ResolveResult rr = GetParamsAttributeArgument(2);
Assert.AreEqual("System.Object", rr.Type.FullName);
Assert.IsTrue(rr.IsCompileTimeConstant);
Assert.IsNull(rr.ConstantValue);
}
[Test, Ignore("CecilLoader does not create ConversionResolveResult")]
public void ParamsAttribute_Double()
{
ResolveResult rr = Unbox(GetParamsAttributeArgument(3));
Assert.AreEqual("System.Double", rr.Type.FullName);
Assert.AreEqual(4.0, rr.ConstantValue);
}
[Test, Ignore("CecilLoader does not create ConversionResolveResult")]
public void ParamsAttribute_String()
{
ConversionResolveResult rr = (ConversionResolveResult)GetParamsAttributeArgument(4);
Assert.AreEqual("System.Object", rr.Type.FullName);
Assert.AreEqual("System.String", rr.Input.Type.FullName);
Assert.AreEqual("Test", rr.Input.ConstantValue);
}
}
}

3
ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj

@ -125,11 +125,13 @@ @@ -125,11 +125,13 @@
<Compile Include="TypeSystem\Implementation\AbstractType.cs" />
<Compile Include="TypeSystem\Implementation\AbstractUnresolvedEntity.cs" />
<Compile Include="TypeSystem\Implementation\AbstractUnresolvedMember.cs" />
<Compile Include="TypeSystem\Implementation\AnonymousType.cs" />
<Compile Include="TypeSystem\Implementation\BaseTypeCollector.cs" />
<Compile Include="TypeSystem\Implementation\DefaultAssemblyReference.cs" />
<Compile Include="TypeSystem\Implementation\DefaultMemberReference.cs" />
<Compile Include="TypeSystem\Implementation\DefaultParameter.cs" />
<Compile Include="TypeSystem\Implementation\DefaultResolvedAccessor.cs" />
<Compile Include="TypeSystem\Implementation\DefaultResolvedEvent.cs" />
<Compile Include="TypeSystem\Implementation\DefaultResolvedField.cs" />
<Compile Include="TypeSystem\Implementation\DefaultResolvedMethod.cs" />
<Compile Include="TypeSystem\Implementation\DefaultResolvedProperty.cs" />
@ -145,6 +147,7 @@ @@ -145,6 +147,7 @@
<Compile Include="TypeSystem\Implementation\DefaultUnresolvedProperty.cs" />
<Compile Include="TypeSystem\Implementation\DefaultUnresolvedTypeDefinition.cs" />
<Compile Include="TypeSystem\Implementation\DefaultUnresolvedTypeParameter.cs" />
<Compile Include="TypeSystem\Implementation\DummyTypeParameter.cs" />
<Compile Include="TypeSystem\Implementation\FullNameAndTypeParameterCount.cs" />
<Compile Include="TypeSystem\Implementation\GetClassTypeReference.cs" />
<Compile Include="TypeSystem\Implementation\GetMembersHelper.cs" />

2
ICSharpCode.NRefactory/Semantics/TypeOfResolveResult.cs

@ -31,6 +31,8 @@ namespace ICSharpCode.NRefactory.Semantics @@ -31,6 +31,8 @@ namespace ICSharpCode.NRefactory.Semantics
public TypeOfResolveResult(IType systemType, IType referencedType)
: base(systemType)
{
if (referencedType == null)
throw new ArgumentNullException("referencedType");
this.referencedType = referencedType;
}

1
ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs

@ -1451,6 +1451,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -1451,6 +1451,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
InitNestedTypes(typeDefinition, td); // nested types can be initialized only after generic parameters were created
AddAttributes(typeDefinition, td);
td.HasExtensionMethods = HasExtensionAttribute(typeDefinition);
// set base classes
if (typeDefinition.IsEnum) {

5
ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs

@ -178,6 +178,11 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -178,6 +178,11 @@ namespace ICSharpCode.NRefactory.TypeSystem
#endregion
#region GetType/Member
public static IEnumerable<IUnresolvedTypeDefinition> GetAllTypeDefinitions (this IParsedFile file)
{
return TreeTraversal.PreOrder(file.TopLevelTypeDefinitions, t => t.NestedTypes);
}
/// <summary>
/// Gets the type (potentially a nested type) defined at the specified location.
/// Returns null if no type is defined at that location.

14
ICSharpCode.NRefactory/TypeSystem/IAmbience.cs

@ -54,16 +54,21 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -54,16 +54,21 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// <summary>
/// Show the return type
/// </summary>
ShowReturnType = 0x100,
ShowReturnType = 0x40,
/// <summary>
/// Use fully qualified names for return type and parameters.
/// </summary>
UseFullyQualifiedTypeNames = 0x200,
UseFullyQualifiedTypeNames = 0x80,
/// <summary>
/// Show the list of type parameters on method and class declarations.
/// Type arguments for parameter/return types are always shown.
/// </summary>
ShowTypeParameterList = 0x800,
ShowTypeParameterList = 0x100,
/// <summary>
/// For fields, events and methods: adds a semicolon at the end.
/// For properties: shows "{ get; }" or similar.
/// </summary>
ShowBody = 0x200,
StandardConversionFlags = ShowParameterNames |
ShowAccessibility |
@ -71,7 +76,8 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -71,7 +76,8 @@ namespace ICSharpCode.NRefactory.TypeSystem
ShowReturnType |
ShowModifiers |
ShowTypeParameterList |
ShowDefinitionKeyWord,
ShowDefinitionKeyWord |
ShowBody,
All = 0xfff,
}

1
ICSharpCode.NRefactory/TypeSystem/IMethod.cs

@ -32,7 +32,6 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -32,7 +32,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
IList<IUnresolvedTypeParameter> TypeParameters { get; }
bool IsExtensionMethod { get; }
bool IsConstructor { get; }
bool IsDestructor { get; }
bool IsOperator { get; }

7
ICSharpCode.NRefactory/TypeSystem/ITypeDefinition.cs

@ -36,6 +36,13 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -36,6 +36,13 @@ namespace ICSharpCode.NRefactory.TypeSystem
IList<IUnresolvedTypeDefinition> NestedTypes { get; }
IList<IUnresolvedMember> Members { get; }
/// <summary>
/// Gets whether the type definition contains extension methods.
/// Returns null when the type definition needs to be resolved in order to determine whether
/// methods are extension methods.
/// </summary>
bool? HasExtensionMethods { get; }
/// <summary>
/// Creates a type resolve context for this part of the type definition.
/// This method is used to add language-specific elements like the C# UsingScope

2
ICSharpCode.NRefactory/TypeSystem/ITypeParameter.cs

@ -60,7 +60,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -60,7 +60,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// <summary>
/// Type parameter of a generic class/method.
/// </summary>
public interface ITypeParameter : IType, IResolved
public interface ITypeParameter : IType
{
/// <summary>
/// Get the type of this type parameter's owner.

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

@ -26,6 +26,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -26,6 +26,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{
public abstract class AbstractTypeParameter : ITypeParameter
{
readonly ICompilation compilation;
readonly EntityType ownerType;
readonly IEntity owner;
readonly int index;
@ -39,6 +40,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -39,6 +40,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
if (owner == null)
throw new ArgumentNullException("owner");
this.owner = owner;
this.compilation = owner.Compilation;
this.ownerType = owner.EntityType;
this.index = index;
this.name = name ?? ((this.OwnerType == EntityType.Method ? "!!" : "!") + index.ToString());
@ -47,8 +49,11 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -47,8 +49,11 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
this.variance = variance;
}
protected AbstractTypeParameter(EntityType ownerType, int index, string name, VarianceModifier variance, IList<IAttribute> attributes, DomRegion region)
protected AbstractTypeParameter(ICompilation compilation, EntityType ownerType, int index, string name, VarianceModifier variance, IList<IAttribute> attributes, DomRegion region)
{
if (compilation == null)
throw new ArgumentNullException("compilation");
this.compilation = compilation;
this.ownerType = ownerType;
this.index = index;
this.name = name ?? ((this.OwnerType == EntityType.Method ? "!!" : "!") + index.ToString());
@ -82,7 +87,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -82,7 +87,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
}
public ICompilation Compilation {
get { return owner.Compilation; }
get { return compilation; }
}
volatile IType effectiveBaseClass;
@ -312,5 +317,10 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -312,5 +317,10 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{
return this == other; // use reference equality for type parameters
}
public override string ToString()
{
return this.ReflectionName;
}
}
}

17
ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractUnresolvedEntity.cs

@ -52,6 +52,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -52,6 +52,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
internal const ushort FlagStatic = 0x0020;
// flags for DefaultUnresolvedTypeDefinition
internal const ushort FlagAddDefaultConstructorIfRequired = 0x0040;
internal const ushort FlagHasExtensionMethods = 0x0080;
internal const ushort FlagHasNoExtensionMethods = 0x0100;
// flags for AbstractUnresolvedMember:
internal const ushort FlagExplicitInterfaceImplementation = 0x0040;
internal const ushort FlagVirtual = 0x0080;
@ -130,17 +132,26 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -130,17 +132,26 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public DomRegion Region {
get { return rareFields != null ? rareFields.region : DomRegion.Empty; }
set { WriteRareFields().region = value; }
set {
if (value != DomRegion.Empty || rareFields != null)
WriteRareFields().region = value;
}
}
public DomRegion BodyRegion {
get { return rareFields != null ? rareFields.bodyRegion : DomRegion.Empty; }
set { WriteRareFields().bodyRegion = value; }
set {
if (value != DomRegion.Empty || rareFields != null)
WriteRareFields().bodyRegion = value;
}
}
public IParsedFile ParsedFile {
get { return rareFields != null ? rareFields.parsedFile : null; }
set { WriteRareFields().parsedFile = value; }
set {
if (value != null || rareFields != null)
WriteRareFields().parsedFile = value;
}
}
public IUnresolvedTypeDefinition DeclaringTypeDefinition {

106
ICSharpCode.NRefactory/TypeSystem/Implementation/AnonymousType.cs

@ -0,0 +1,106 @@ @@ -0,0 +1,106 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.NRefactory.Utils;
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{
/// <summary>
/// Anonymous type.
/// </summary>
public class AnonymousType : AbstractType
{
ICompilation compilation;
IUnresolvedProperty[] unresolvedProperties;
IList<IProperty> resolvedProperties;
public AnonymousType(ICompilation compilation, IList<IUnresolvedProperty> properties)
{
if (compilation == null)
throw new ArgumentNullException("compilation");
if (properties == null)
throw new ArgumentNullException("properties");
this.compilation = compilation;
this.unresolvedProperties = properties.ToArray();
var context = new SimpleTypeResolveContext(compilation.MainAssembly);
this.resolvedProperties = new ProjectedList<ITypeResolveContext, IUnresolvedProperty, IProperty>(context, unresolvedProperties, (c, p) => (IProperty)p.CreateResolved(c));
}
public override ITypeReference ToTypeReference()
{
throw new NotSupportedException();
}
public override string Name {
get { return "Anonymous Type"; }
}
public override TypeKind Kind {
get { return TypeKind.Anonymous; }
}
public override bool? IsReferenceType {
get { return true; }
}
public IList<IProperty> Properties {
get { return resolvedProperties; }
}
public override IEnumerable<IMethod> GetMethods(Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
{
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)
return EmptyList<IMethod>.Instance;
else
return compilation.FindType(KnownTypeCode.Object).GetMethods(filter, options);
}
public override IEnumerable<IMethod> GetMethods(IList<IType> typeArguments, Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
{
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)
return EmptyList<IMethod>.Instance;
else
return compilation.FindType(KnownTypeCode.Object).GetMethods(typeArguments, filter, options);
}
public override IEnumerable<IProperty> GetProperties(Predicate<IUnresolvedProperty> filter = null, GetMemberOptions options = GetMemberOptions.None)
{
for (int i = 0; i < unresolvedProperties.Length; i++) {
if (filter == null || filter(unresolvedProperties[i]))
yield return resolvedProperties[i];
}
}
public override bool Equals(IType other)
{
AnonymousType o = other as AnonymousType;
if (o == null || resolvedProperties.Count != o.resolvedProperties.Count)
return false;
for (int i = 0; i < resolvedProperties.Count; i++) {
IProperty p1 = resolvedProperties[i];
IProperty p2 = o.resolvedProperties[i];
if (p1.Name != p2.Name || !p1.ReturnType.Equals(p2.ReturnType))
return false;
}
return true;
}
}
}

36
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultMemberReference.cs

@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
@ -31,39 +32,66 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -31,39 +32,66 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
EntityType entityType;
ITypeReference typeReference;
string name;
int typeParameterCount;
IList<ITypeReference> parameterTypes;
public DefaultMemberReference(EntityType entityType, ITypeReference typeReference, string name)
public DefaultMemberReference(EntityType entityType, ITypeReference typeReference, string name, int typeParameterCount = 0, IList<ITypeReference> parameterTypes = null)
{
if (typeReference == null)
throw new ArgumentNullException("typeReference");
if (name == null)
throw new ArgumentNullException("name");
if (typeParameterCount != 0 && entityType != EntityType.Method)
throw new ArgumentException("Type parameter count > 0 is only supported for methods.");
this.entityType = entityType;
this.typeReference = typeReference;
this.name = name;
this.typeParameterCount = typeParameterCount;
this.parameterTypes = parameterTypes ?? EmptyList<ITypeReference>.Instance;
}
public IMember Resolve(ITypeResolveContext context)
{
IType type = typeReference.Resolve(context);
return type.GetMembers(m => m.Name == name && m.EntityType == entityType, GetMemberOptions.IgnoreInheritedMembers).FirstOrDefault();
IEnumerable<IMember> members;
if (entityType == EntityType.Method) {
members = type.GetMethods(
m => m.Name == name && m.EntityType == EntityType.Method && m.TypeParameters.Count == typeParameterCount,
GetMemberOptions.IgnoreInheritedMembers);
} else {
members = type.GetMembers(
m => m.Name == name && m.EntityType == entityType,
GetMemberOptions.IgnoreInheritedMembers);
}
var resolvedParameterTypes = parameterTypes.Resolve(context);
foreach (IMember member in members) {
IParameterizedMember parameterizedMember = member as IParameterizedMember;
if (parameterTypes.Count == 0) {
if (parameterizedMember == null || parameterizedMember.Parameters.Count == 0)
return member;
} else if (parameterTypes.Count == parameterizedMember.Parameters.Count) {
}
}
return null;
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
typeReference = provider.Intern(typeReference);
name = provider.Intern(name);
parameterTypes = provider.InternList(parameterTypes);
}
int ISupportsInterning.GetHashCodeForInterning()
{
return (int)entityType ^ typeReference.GetHashCode() ^ name.GetHashCode();
return (int)entityType ^ typeReference.GetHashCode() ^ name.GetHashCode() ^ parameterTypes.GetHashCode();
}
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
{
DefaultMemberReference o = other as DefaultMemberReference;
return o != null && entityType == o.entityType && typeReference == o.typeReference && name == o.name;
return o != null && entityType == o.entityType && typeReference == o.typeReference && name == o.name && parameterTypes == o.parameterTypes;
}
}
}

28
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultParameter.cs

@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{
@ -100,5 +101,32 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -100,5 +101,32 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public object ConstantValue {
get { return defaultValue; }
}
public override string ToString()
{
return ToString(this);
}
public static string ToString(IParameter p)
{
StringBuilder b = new StringBuilder();
if (p.IsRef)
b.Append("ref ");
if (p.IsOut)
b.Append("out ");
if (p.IsParams)
b.Append("params ");
b.Append(p.Name);
b.Append(':');
b.Append(p.Type.ToString());
if (p.IsOptional) {
b.Append(" = ");
if (p.ConstantValue != null)
b.Append(p.ConstantValue.ToString());
else
b.Append("null");
}
return b.ToString();
}
}
}

92
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedEvent.cs

@ -0,0 +1,92 @@ @@ -0,0 +1,92 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using ICSharpCode.NRefactory.Utils;
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{
public class DefaultResolvedEvent : AbstractResolvedMember, IEvent
{
protected new readonly IUnresolvedEvent unresolved;
IAccessor addAccessor;
IAccessor removeAccessor;
IAccessor invokeAccessor;
public DefaultResolvedEvent(IUnresolvedEvent unresolved, ITypeResolveContext parentContext)
: base(unresolved, parentContext)
{
this.unresolved = unresolved;
}
public bool CanAdd {
get { return unresolved.CanAdd; }
}
public bool CanRemove {
get { return unresolved.CanRemove; }
}
public bool CanInvoke {
get { return unresolved.CanInvoke; }
}
public IAccessor AddAccessor {
get {
if (!unresolved.CanAdd)
return null;
IAccessor result = this.addAccessor;
if (result != null) {
LazyInit.ReadBarrier();
return result;
} else {
return LazyInit.GetOrSet(ref this.addAccessor, unresolved.AddAccessor.CreateResolvedAccessor(context));
}
}
}
public IAccessor RemoveAccessor {
get {
if (!unresolved.CanRemove)
return null;
IAccessor result = this.removeAccessor;
if (result != null) {
LazyInit.ReadBarrier();
return result;
} else {
return LazyInit.GetOrSet(ref this.removeAccessor, unresolved.RemoveAccessor.CreateResolvedAccessor(context));
}
}
}
public IAccessor InvokeAccessor {
get {
if (!unresolved.CanInvoke)
return null;
IAccessor result = this.invokeAccessor;
if (result != null) {
LazyInit.ReadBarrier();
return result;
} else {
return LazyInit.GetOrSet(ref this.invokeAccessor, unresolved.InvokeAccessor.CreateResolvedAccessor(context));
}
}
}
}
}

12
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedMethod.cs

@ -27,21 +27,25 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -27,21 +27,25 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
/// </summary>
public class DefaultResolvedMethod : AbstractResolvedMember, IMethod
{
public DefaultResolvedMethod(IUnresolvedMethod unresolved, ITypeResolveContext parentContext)
public DefaultResolvedMethod(DefaultUnresolvedMethod unresolved, ITypeResolveContext parentContext)
: this(unresolved, parentContext, unresolved.IsExtensionMethod)
{
}
public DefaultResolvedMethod(IUnresolvedMethod unresolved, ITypeResolveContext parentContext, bool isExtensionMethod)
: base(unresolved, parentContext)
{
this.Parameters = unresolved.Parameters.CreateResolvedParameters(context);
this.ReturnTypeAttributes = unresolved.ReturnTypeAttributes.CreateResolvedAttributes(parentContext);
this.TypeParameters = unresolved.TypeParameters.CreateResolvedTypeParameters(context);
this.IsExtensionMethod = isExtensionMethod;
}
public IList<IParameter> Parameters { get; private set; }
public IList<IAttribute> ReturnTypeAttributes { get; private set; }
public IList<ITypeParameter> TypeParameters { get; private set; }
public bool IsExtensionMethod {
get { return ((IUnresolvedMethod)unresolved).IsExtensionMethod; }
}
public bool IsExtensionMethod { get; private set; }
public bool IsConstructor {
get { return ((IUnresolvedMethod)unresolved).IsConstructor; }

32
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs

@ -181,6 +181,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -181,6 +181,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
get {
KnownTypeCode result = this.knownTypeCode;
if (result == (KnownTypeCode)(-1)) {
result = KnownTypeCode.None;
for (int i = 0; i < KnownTypeReference.KnownTypeCodeCount; i++) {
KnownTypeReference r = KnownTypeReference.Get((KnownTypeCode)i);
if (r != null && r.Resolve(parentContext) == this) {
@ -201,7 +202,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -201,7 +202,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
IType result = this.enumUnderlyingType;
if (result == null) {
if (this.Kind == TypeKind.Enum) {
result = CalculateEnumUnderlyingType();
} else {
result = SpecialType.UnknownType;
}
@ -224,10 +225,37 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -224,10 +225,37 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
return this.Compilation.FindType(KnownTypeCode.Int32);
}
volatile byte hasExtensionMethods; // 0 = unknown, 1 = true, 2 = false
public bool HasExtensionMethods {
get {
throw new NotImplementedException();
byte val = this.hasExtensionMethods;
if (val == 0) {
if (CalculateHasExtensionMethods())
val = 1;
else
val = 2;
this.hasExtensionMethods = val;
}
return val == 1;
}
}
bool CalculateHasExtensionMethods()
{
bool noExtensionMethods = true;
foreach (var part in parts) {
// Return true if any part has extension methods
if (part.HasExtensionMethods == true)
return true;
if (part.HasExtensionMethods == null)
noExtensionMethods = false;
}
// Return false if all parts are known to have no extension methods
if (noExtensionMethods)
return false;
// If unsure, look at the resolved methods.
return Methods.Any(m => m.IsExtensionMethod);
}
public bool? IsReferenceType {

10
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeParameter.cs

@ -32,8 +32,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -32,8 +32,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
readonly IList<IType> constraints;
public DefaultTypeParameter(
IEntity owner, int index,
string name = null,
IEntity owner,
int index, string name = null,
VarianceModifier variance = VarianceModifier.Invariant,
IList<IAttribute> attributes = null,
DomRegion region = default(DomRegion),
@ -48,14 +48,14 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -48,14 +48,14 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
}
public DefaultTypeParameter(
EntityType ownerType, int index,
string name = null,
ICompilation compilation, EntityType ownerType,
int index, string name = null,
VarianceModifier variance = VarianceModifier.Invariant,
IList<IAttribute> attributes = null,
DomRegion region = default(DomRegion),
bool hasValueTypeConstraint = false, bool hasReferenceTypeConstraint = false, bool hasDefaultConstructorConstraint = false,
IList<IType> constraints = null)
: base(ownerType, index, name, variance, attributes, region)
: base(compilation, ownerType, index, name, variance, attributes, region)
{
this.hasValueTypeConstraint = hasValueTypeConstraint;
this.hasReferenceTypeConstraint = hasReferenceTypeConstraint;

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

@ -282,6 +282,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -282,6 +282,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
readonly UnresolvedNamespace ns;
readonly INamespace parentNamespace;
readonly IList<NS> childNamespaces;
IEnumerable<ITypeDefinition> types;
public NS(DefaultResolvedAssembly assembly, UnresolvedNamespace ns, INamespace parentNamespace)
{
@ -328,7 +329,18 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -328,7 +329,18 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
IEnumerable<ITypeDefinition> INamespace.Types {
get {
throw new NotImplementedException();
var result = this.types;
if (result != null) {
LazyInit.ReadBarrier();
return result;
} else {
var hashSet = new HashSet<ITypeDefinition>();
foreach (IUnresolvedTypeDefinition typeDef in assembly.UnresolvedAssembly.TopLevelTypeDefinitions) {
if (typeDef.Namespace == ns.FullName)
hashSet.Add(assembly.GetTypeDefinition(typeDef));
}
return LazyInit.GetOrSet(ref this.types, hashSet.ToArray());
}
}
}

4
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedEvent.cs

@ -54,6 +54,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -54,6 +54,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
this.EntityType = EntityType.Event;
this.DeclaringTypeDefinition = declaringType;
this.Name = name;
if (declaringType != null)
this.ParsedFile = declaringType.ParsedFile;
}
public bool CanAdd {
@ -94,7 +96,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -94,7 +96,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public override IMember CreateResolved(ITypeResolveContext context)
{
throw new NotImplementedException();
return new DefaultResolvedEvent(this, context);
}
}
}

2
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedField.cs

@ -50,6 +50,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -50,6 +50,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
this.EntityType = EntityType.Field;
this.DeclaringTypeDefinition = declaringType;
this.Name = name;
if (declaringType != null)
this.ParsedFile = declaringType.ParsedFile;
}
public bool IsConst {

2
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedMethod.cs

@ -60,6 +60,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -60,6 +60,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
this.EntityType = EntityType.Method;
this.DeclaringTypeDefinition = declaringType;
this.Name = name;
if (declaringType != null)
this.ParsedFile = declaringType.ParsedFile;
}
public IList<IUnresolvedAttribute> ReturnTypeAttributes {

7
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedParameter.cs

@ -228,7 +228,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -228,7 +228,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public bool IsOut { get; internal set; }
public bool IsParams { get; internal set; }
public bool IsOptional { get { return true; } }
public bool IsConst { get { return false; } }
bool IVariable.IsConst { get { return false; } }
ResolveResult resolvedDefaultValue;
@ -244,6 +244,11 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -244,6 +244,11 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
}
}
}
public override string ToString()
{
return DefaultParameter.ToString(this);
}
}
}
}

2
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedProperty.cs

@ -56,6 +56,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -56,6 +56,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
this.EntityType = EntityType.Property;
this.DeclaringTypeDefinition = declaringType;
this.Name = name;
if (declaringType != null)
this.ParsedFile = declaringType.ParsedFile;
}
public bool IsIndexer {

17
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedTypeDefinition.cs

@ -52,6 +52,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -52,6 +52,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
this.DeclaringTypeDefinition = declaringTypeDefinition;
this.namespaceName = declaringTypeDefinition.Namespace;
this.Name = name;
this.ParsedFile = declaringTypeDefinition.ParsedFile;
}
public TypeKind Kind {
@ -70,6 +71,22 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -70,6 +71,22 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
}
}
public bool? HasExtensionMethods {
get {
if (flags[FlagHasExtensionMethods])
return true;
else if (flags[FlagHasNoExtensionMethods])
return false;
else
return null;
}
set {
ThrowIfFrozen();
flags[FlagHasExtensionMethods] = (value == true);
flags[FlagHasNoExtensionMethods] = (value == false);
}
}
public override string Namespace {
get { return namespaceName; }
set {

134
ICSharpCode.NRefactory/TypeSystem/Implementation/DummyTypeParameter.cs

@ -0,0 +1,134 @@ @@ -0,0 +1,134 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Threading;
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{
public sealed class DummyTypeParameter : AbstractType, ITypeParameter
{
static ITypeParameter[] methodTypeParameters = { new DummyTypeParameter(EntityType.Method, 0) };
static ITypeParameter[] classTypeParameters = { new DummyTypeParameter(EntityType.TypeDefinition, 0) };
public static ITypeParameter GetMethodTypeParameter(int index)
{
return GetTypeParameter(ref methodTypeParameters, EntityType.Method, index);
}
public static ITypeParameter GetClassTypeParameter(int index)
{
return GetTypeParameter(ref classTypeParameters, EntityType.TypeDefinition, index);
}
static ITypeParameter GetTypeParameter(ref ITypeParameter[] typeParameters, EntityType entityType, int index)
{
ITypeParameter[] tps = typeParameters;
while (index >= tps.Length) {
// We don't have a normal type parameter for this index, so we need to extend our array.
// Because the array can be used concurrently from multiple threads, we have to use
// Interlocked.CompareExchange.
ITypeParameter[] newTps = new ITypeParameter[index + 1];
tps.CopyTo(newTps, 0);
for (int i = tps.Length; i < newTps.Length; i++) {
newTps[i] = new DummyTypeParameter(entityType, i);
}
ITypeParameter[] oldTps = Interlocked.CompareExchange(ref typeParameters, newTps, tps);
if (oldTps == tps) {
// exchange successful
tps = newTps;
} else {
// exchange not successful
tps = oldTps;
}
}
return tps[index];
}
readonly EntityType ownerType;
readonly int index;
private DummyTypeParameter(EntityType ownerType, int index)
{
this.ownerType = ownerType;
this.index = index;
}
public override string Name {
get { return "!" + index; }
}
public override bool? IsReferenceType {
get { return null; }
}
public override TypeKind Kind {
get { return TypeKind.TypeParameter; }
}
public override ITypeReference ToTypeReference()
{
throw new NotSupportedException();
}
public int Index {
get { return index; }
}
IList<IAttribute> ITypeParameter.Attributes {
get { return EmptyList<IAttribute>.Instance; }
}
EntityType ITypeParameter.OwnerType {
get { return ownerType; }
}
VarianceModifier ITypeParameter.Variance {
get { return VarianceModifier.Invariant; }
}
DomRegion ITypeParameter.Region {
get { return DomRegion.Empty; }
}
IEntity ITypeParameter.Owner {
get { return null; }
}
IType ITypeParameter.EffectiveBaseClass {
get { return SpecialType.UnknownType; }
}
IList<IType> ITypeParameter.EffectiveInterfaceSet {
get { return EmptyList<IType>.Instance; }
}
bool ITypeParameter.HasDefaultConstructorConstraint {
get { return false; }
}
bool ITypeParameter.HasReferenceTypeConstraint {
get { return false; }
}
bool ITypeParameter.HasValueTypeConstraint {
get { return false; }
}
}
}

2
ICSharpCode.NRefactory/TypeSystem/Implementation/KnownTypeCache.cs

@ -47,6 +47,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -47,6 +47,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
IType SearchType(KnownTypeCode typeCode)
{
KnownTypeReference typeRef = KnownTypeReference.Get(typeCode);
if (typeRef == null)
return SpecialType.UnknownType;
ITypeDefinition typeDef;
foreach (IAssembly asm in compilation.ReferencedAssemblies) {
typeDef = asm.GetTypeDefinition(typeRef.Namespace, typeRef.Name, typeRef.TypeParameterCount);

5
ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMember.cs

@ -330,6 +330,11 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -330,6 +330,11 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public object ConstantValue {
get { return originalParameter.ConstantValue; }
}
public override string ToString()
{
return DefaultParameter.ToString(this);
}
}
}
}

37
ICSharpCode.NRefactory/TypeSystem/ParameterListComparer.cs

@ -37,40 +37,29 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -37,40 +37,29 @@ namespace ICSharpCode.NRefactory.TypeSystem
// We want to consider the parameter lists "Method<T>(T a)" and "Method<S>(S b)" as equal.
// However, the parameter types are not considered equal, as T is a different type parameter than S.
// In order to compare the method signatures, we will normalize all method type parameters.
sealed class NormalizeMethodTypeParameters : TypeVisitor
sealed class NormalizeMethodTypeParametersVisitor : TypeVisitor
{
ITypeParameter[] normalTypeParameters = { new DefaultTypeParameter(EntityType.Method, 0) };
public override IType VisitTypeParameter(ITypeParameter type)
{
if (type.OwnerType == EntityType.Method) {
ITypeParameter[] tps = this.normalTypeParameters;
while (type.Index >= tps.Length) {
// We don't have a normal type parameter for this index, so we need to extend our array.
// Because the array can be used concurrently from multiple threads, we have to use
// Interlocked.CompareExchange.
ITypeParameter[] newTps = new ITypeParameter[type.Index + 1];
tps.CopyTo(newTps, 0);
for (int i = tps.Length; i < newTps.Length; i++) {
newTps[i] = new DefaultTypeParameter(EntityType.Method, i);
}
ITypeParameter[] oldTps = Interlocked.CompareExchange(ref normalTypeParameters, newTps, tps);
if (oldTps == tps) {
// exchange successful
tps = newTps;
} else {
// exchange not successful
tps = oldTps;
}
}
return tps[type.Index];
return DummyTypeParameter.GetMethodTypeParameter(type.Index);
} else {
return base.VisitTypeParameter(type);
}
}
}
readonly NormalizeMethodTypeParameters normalization = new NormalizeMethodTypeParameters();
readonly NormalizeMethodTypeParametersVisitor normalization = new NormalizeMethodTypeParametersVisitor();
/// <summary>
/// Replaces all occurrences of method type parameters in the given type
/// by normalized type parameters. This allows comparing parameter types from different
/// generic methods.
/// </summary>
public IType NormalizeMethodTypeParameters(IType type)
{
return type.AcceptVisitor(normalization);
}
public bool Equals(IList<IParameter> x, IList<IParameter> y)
{

3
ICSharpCode.NRefactory/TypeSystem/TypeKind.cs

@ -73,6 +73,9 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -73,6 +73,9 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// <summary>A managed reference type</summary>
/// <see cref="ByReferenceType"/>
ByReference,
/// <summary>An anonymous type</summary>
/// <see cref="AnonymousType"/>
Anonymous,
/// <summary>Intersection of several types</summary>
/// <see cref="IntersectionType"/>

Loading…
Cancel
Save