Browse Source

Change IConstantValue API to use ResolveResult.

newNRvisualizers
Daniel Grunwald 15 years ago
parent
commit
611c310eb2
  1. 72
      ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.cs
  2. 8
      ICSharpCode.NRefactory/CSharp/Parser/TypeSystemConvertVisitor.cs
  3. 32
      ICSharpCode.NRefactory/CSharp/Refactoring/TypeSystemAstBuilder.cs
  4. 47
      ICSharpCode.NRefactory/CSharp/Resolver/CSharpAttribute.cs
  5. 6
      ICSharpCode.NRefactory/CSharp/Resolver/CSharpResolver.cs
  6. 120
      ICSharpCode.NRefactory/CSharp/Resolver/ConstantValues.cs
  7. 2
      ICSharpCode.NRefactory/CSharp/Resolver/MemberResolveResult.cs
  8. 51
      ICSharpCode.NRefactory/CSharp/Resolver/OperatorResolveResult.cs
  9. 27
      ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs
  10. 44
      ICSharpCode.NRefactory/CSharp/Resolver/TypeOfResolveResult.cs
  11. 1
      ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj
  12. 5
      ICSharpCode.NRefactory/TypeSystem/IAttribute.cs
  13. 32
      ICSharpCode.NRefactory/TypeSystem/IConstantValue.cs
  14. 9
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultAttribute.cs
  15. 8
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultParameter.cs
  16. 17
      ICSharpCode.NRefactory/TypeSystem/Implementation/SimpleConstantValue.cs

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

@ -20,6 +20,7 @@ using System; @@ -20,6 +20,7 @@ using System;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using ICSharpCode.NRefactory.CSharp.Resolver;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using ICSharpCode.NRefactory.TypeSystem.TestCase;
using NUnit.Framework;
@ -132,14 +133,15 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -132,14 +133,15 @@ namespace ICSharpCode.NRefactory.TypeSystem
var posArgs = typeTest.GetPositionalArguments(ctx);
Assert.AreEqual(3, posArgs.Count);
// first argument is (int)42
Assert.AreEqual(42, (int)posArgs[0].GetValue(ctx));
Assert.AreEqual(42, (int)posArgs[0].ConstantValue);
// second argument is typeof(System.Action<>)
IType rt = (IType)posArgs[1].GetValue(ctx);
Assert.IsFalse(rt is ParameterizedType); // rt must not be constructed - it's just an unbound type
Assert.AreEqual("System.Action", rt.FullName);
Assert.AreEqual(1, rt.TypeParameterCount);
TypeOfResolveResult rt = (TypeOfResolveResult)posArgs[1];
Assert.IsFalse(rt.ReferencedType is ParameterizedType); // rt must not be constructed - it's just an unbound type
Assert.AreEqual("System.Action", rt.ReferencedType.FullName);
Assert.AreEqual(1, rt.ReferencedType.TypeParameterCount);
// third argument is typeof(IDictionary<string, IList<TestAttribute>>)
ParameterizedType crt = (ParameterizedType)posArgs[2].GetValue(ctx);
rt = (TypeOfResolveResult)posArgs[2];
ParameterizedType crt = (ParameterizedType)rt.ReferencedType;
Assert.AreEqual("System.Collections.Generic.IDictionary", crt.FullName);
Assert.AreEqual("System.String", crt.TypeArguments[0].FullName);
// ? for NUnit.TestAttribute (because that assembly isn't in ctx)
@ -153,8 +155,8 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -153,8 +155,8 @@ namespace ICSharpCode.NRefactory.TypeSystem
var forwardAttribute = attributes.Single(a => a.AttributeType.Resolve(ctx).FullName == typeof(TypeForwardedToAttribute).FullName);
var posArgs = forwardAttribute.GetPositionalArguments(ctx);
Assert.AreEqual(1, posArgs.Count);
IType rt = (IType)posArgs[0].GetValue(ctx);
Assert.AreEqual("System.Func`2", rt.ReflectionName);
TypeOfResolveResult rt = (TypeOfResolveResult)posArgs[0];
Assert.AreEqual("System.Func`2", rt.ReferencedType.ReflectionName);
}
[Test]
@ -254,33 +256,25 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -254,33 +256,25 @@ namespace ICSharpCode.NRefactory.TypeSystem
Assert.IsTrue(f.IsStatic);
Assert.IsTrue(f.IsConst);
Assert.AreEqual(Accessibility.Public, f.Accessibility);
Assert.AreSame(e, f.ConstantValue.GetValueType(ctx));
Assert.AreEqual(typeof(short), f.ConstantValue.GetValue(ctx).GetType());
Assert.AreSame(e, f.ConstantValue.Resolve(ctx).Type);
Assert.AreEqual(typeof(short), f.ConstantValue.Resolve(ctx).ConstantValue.GetType());
}
Assert.AreEqual("First", e.Fields[0].Name);
Assert.AreEqual(0, e.Fields[0].ConstantValue.GetValue(ctx));
Assert.AreEqual(0, e.Fields[0].ConstantValue.Resolve(ctx).ConstantValue);
Assert.AreEqual("Second", e.Fields[1].Name);
Assert.AreSame(e, e.Fields[1].ConstantValue.GetValueType(ctx));
Assert.AreEqual(1, e.Fields[1].ConstantValue.GetValue(ctx));
Assert.AreSame(e, e.Fields[1].ConstantValue.Resolve(ctx).Type);
Assert.AreEqual(1, e.Fields[1].ConstantValue.Resolve(ctx).ConstantValue);
Assert.AreEqual("Flag1", e.Fields[2].Name);
Assert.AreEqual(0x10, e.Fields[2].ConstantValue.GetValue(ctx));
Assert.AreEqual(0x10, e.Fields[2].ConstantValue.Resolve(ctx).ConstantValue);
Assert.AreEqual("Flag2", e.Fields[3].Name);
Assert.AreEqual(0x20, e.Fields[3].ConstantValue.GetValue(ctx));
Assert.AreEqual(0x20, e.Fields[3].ConstantValue.Resolve(ctx).ConstantValue);
Assert.AreEqual("CombinedFlags", e.Fields[4].Name);
Assert.AreEqual(0x30, e.Fields[4].ConstantValue.GetValue(ctx));
}
[Test]
public void GetNestedTypesFromGenericClassTest()
{
ITypeDefinition b = ctx.GetTypeDefinition(typeof(Base<>));
// Base.GetNestedTypes() = { Base`1+Nested`1[`0, unbound] }
Assert.AreEqual(0x30, e.Fields[4].ConstantValue.Resolve(ctx).ConstantValue);
}
[Test]
@ -336,20 +330,20 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -336,20 +330,20 @@ namespace ICSharpCode.NRefactory.TypeSystem
{
IAttribute attr = ctx.GetTypeDefinition(typeof(ExplicitFieldLayoutStruct)).Attributes.Single();
Assert.AreEqual("System.Runtime.InteropServices.StructLayoutAttribute", attr.AttributeType.Resolve(ctx).FullName);
IConstantValue arg1 = attr.GetPositionalArguments(ctx).Single();
Assert.AreEqual("System.Runtime.InteropServices.LayoutKind", arg1.GetValueType(ctx).FullName);
Assert.AreEqual((int)LayoutKind.Explicit, arg1.GetValue(ctx));
ResolveResult arg1 = attr.GetPositionalArguments(ctx).Single();
Assert.AreEqual("System.Runtime.InteropServices.LayoutKind", arg1.Type.FullName);
Assert.AreEqual((int)LayoutKind.Explicit, arg1.ConstantValue);
var namedArgs = attr.GetNamedArguments(ctx);
var arg2 = namedArgs[0];
Assert.AreEqual("CharSet", arg2.Key);
Assert.AreEqual("System.Runtime.InteropServices.CharSet", arg2.Value.GetValueType(ctx).FullName);
Assert.AreEqual((int)CharSet.Unicode, arg2.Value.GetValue(ctx));
Assert.AreEqual("System.Runtime.InteropServices.CharSet", arg2.Value.Type.FullName);
Assert.AreEqual((int)CharSet.Unicode, arg2.Value.ConstantValue);
var arg3 = namedArgs[1];
Assert.AreEqual("Pack", arg3.Key);
Assert.AreEqual("System.Int32", arg3.Value.GetValueType(ctx).FullName);
Assert.AreEqual(8, arg3.Value.GetValue(ctx));
Assert.AreEqual("System.Int32", arg3.Value.Type.FullName);
Assert.AreEqual(8, arg3.Value.ConstantValue);
}
[Test]
@ -357,15 +351,15 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -357,15 +351,15 @@ namespace ICSharpCode.NRefactory.TypeSystem
{
IField field = ctx.GetTypeDefinition(typeof(ExplicitFieldLayoutStruct)).Fields.Single(f => f.Name == "Field0");
Assert.AreEqual("System.Runtime.InteropServices.FieldOffsetAttribute", field.Attributes.Single().AttributeType.Resolve(ctx).FullName);
IConstantValue arg = field.Attributes.Single().GetPositionalArguments(ctx).Single();
Assert.AreEqual("System.Int32", arg.GetValueType(ctx).FullName);
Assert.AreEqual(0, arg.GetValue(ctx));
ResolveResult arg = field.Attributes.Single().GetPositionalArguments(ctx).Single();
Assert.AreEqual("System.Int32", arg.Type.FullName);
Assert.AreEqual(0, arg.ConstantValue);
field = ctx.GetTypeDefinition(typeof(ExplicitFieldLayoutStruct)).Fields.Single(f => f.Name == "Field100");
Assert.AreEqual("System.Runtime.InteropServices.FieldOffsetAttribute", field.Attributes.Single().AttributeType.Resolve(ctx).FullName);
arg = field.Attributes.Single().GetPositionalArguments(ctx).Single();
Assert.AreEqual("System.Int32", arg.GetValueType(ctx).FullName);
Assert.AreEqual(100, arg.GetValue(ctx));
Assert.AreEqual("System.Int32", arg.Type.FullName);
Assert.AreEqual(100, arg.ConstantValue);
}
[Test]
@ -374,8 +368,8 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -374,8 +368,8 @@ namespace ICSharpCode.NRefactory.TypeSystem
IMethod method = ctx.GetTypeDefinition(typeof(NonCustomAttributes)).Methods.Single(m => m.Name == "DllMethod");
IAttribute dllImport = method.Attributes.Single();
Assert.AreEqual("System.Runtime.InteropServices.DllImportAttribute", dllImport.AttributeType.Resolve(ctx).FullName);
Assert.AreEqual("unmanaged.dll", dllImport.GetPositionalArguments(ctx)[0].GetValue(ctx));
Assert.AreEqual((int)CharSet.Unicode, dllImport.GetNamedArguments(ctx).Single().Value.GetValue(ctx));
Assert.AreEqual("unmanaged.dll", dllImport.GetPositionalArguments(ctx)[0].ConstantValue);
Assert.AreEqual((int)CharSet.Unicode, dllImport.GetNamedArguments(ctx).Single().Value.ConstantValue);
}
[Test]
@ -394,7 +388,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -394,7 +388,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
{
IMethod method = ctx.GetTypeDefinition(typeof(NonCustomAttributes)).Methods.Single(m => m.Name == "DllMethod");
IAttribute marshalAs = method.ReturnTypeAttributes.Single();
Assert.AreEqual((int)UnmanagedType.Bool, marshalAs.GetPositionalArguments(ctx).Single().GetValue(ctx));
Assert.AreEqual((int)UnmanagedType.Bool, marshalAs.GetPositionalArguments(ctx).Single().ConstantValue);
}
[Test]

8
ICSharpCode.NRefactory/CSharp/Parser/TypeSystemConvertVisitor.cs

@ -765,12 +765,12 @@ namespace ICSharpCode.NRefactory.CSharp @@ -765,12 +765,12 @@ namespace ICSharpCode.NRefactory.CSharp
namedCtorArguments = new List<KeyValuePair<string, IConstantValue>>();
namedCtorArguments.Add(new KeyValuePair<string, IConstantValue>(nae.Identifier, ConvertAttributeArgument(nae.Expression)));
} else {
AssignmentExpression ae = expr as AssignmentExpression;
if (ae != null && ae.Left is IdentifierExpression && ae.Operator == AssignmentOperatorType.Assign) {
string name = ((IdentifierExpression)ae.Left).Identifier;
NamedExpression namedExpression = expr as NamedExpression;
if (namedExpression != null) {
string name = namedExpression.Identifier;
if (namedArguments == null)
namedArguments = new List<KeyValuePair<string, IConstantValue>>();
namedArguments.Add(new KeyValuePair<string, IConstantValue>(name, ConvertAttributeArgument(ae.Right)));
namedArguments.Add(new KeyValuePair<string, IConstantValue>(name, ConvertAttributeArgument(namedExpression.Expression)));
} else {
if (positionalArguments == null)
positionalArguments = new List<IConstantValue>();

32
ICSharpCode.NRefactory/CSharp/Refactoring/TypeSystemAstBuilder.cs

@ -335,17 +335,31 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -335,17 +335,31 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
if (constantValue == null)
throw new ArgumentNullException("constantValue");
IType type = constantValue.GetValueType(context);
object val = constantValue.GetValue(context);
if (val == null) {
if (type.IsReferenceType(context) == true)
return new NullReferenceExpression();
else
return new DefaultValueExpression(ConvertType(type));
} else if (type.Kind == TypeKind.Enum) {
return ConvertConstantValue(constantValue.Resolve(context));
}
Expression ConvertConstantValue(ResolveResult rr)
{
if (rr is TypeOfResolveResult) {
return new TypeOfExpression(ConvertType(((TypeOfResolveResult)rr).Type));
} else if (rr is ArrayCreateResolveResult) {
ArrayCreateResolveResult acrr = (ArrayCreateResolveResult)rr;
AstType type = ConvertType(acrr.Type);
throw new NotImplementedException();
} else if (rr.IsCompileTimeConstant) {
object val = rr.ConstantValue;
if (val == null) {
if (rr.Type.IsReferenceType(context) == true)
return new NullReferenceExpression();
else
return new DefaultValueExpression(ConvertType(rr.Type));
} else if (rr.Type.Kind == TypeKind.Enum) {
throw new NotImplementedException();
} else {
return new PrimitiveExpression(val);
}
} else {
return new PrimitiveExpression(val);
return new EmptyExpression();
}
}
#endregion

47
ICSharpCode.NRefactory/CSharp/Resolver/CSharpAttribute.cs

@ -19,6 +19,8 @@ @@ -19,6 +19,8 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
@ -70,14 +72,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -70,14 +72,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (positionalArguments != null) {
while (i < positionalArguments.Count) {
IConstantValue cv = positionalArguments[i];
arguments[i] = new ConstantResolveResult(cv.GetValueType(context), cv.GetValue(context));
arguments[i] = cv.Resolve(context);
i++;
}
}
if (namedCtorArguments != null) {
foreach (var pair in namedCtorArguments) {
argumentNames[i] = pair.Key;
arguments[i] = new ConstantResolveResult(pair.Value.GetValueType(context), pair.Value.GetValue(context));
arguments[i] = pair.Value.Resolve(context);
i++;
}
}
@ -85,17 +87,19 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -85,17 +87,19 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return mrr != null ? mrr.Member as IMethod : null;
}
public IList<IConstantValue> GetPositionalArguments(ITypeResolveContext context)
public IList<ResolveResult> GetPositionalArguments(ITypeResolveContext context)
{
List<ResolveResult> result = new List<ResolveResult>();
if (positionalArguments != null) {
foreach (var arg in positionalArguments) {
result.Add(Resolve(arg, context));
}
}
if (namedCtorArguments == null || namedCtorArguments.Count == 0) {
// no namedCtorArguments: just return the positionalArguments
if (positionalArguments != null)
return new ReadOnlyCollection<IConstantValue>(positionalArguments);
else
return EmptyList<IConstantValue>.Instance;
return result.AsReadOnly();
}
// we do have namedCtorArguments, which need to be re-ordered and appended to the positional arguments
List<IConstantValue> result = new List<IConstantValue>(this.positionalArguments);
IMethod method = ResolveConstructor(context);
if (method != null) {
for (int i = result.Count; i < method.Parameters.Count; i++) {
@ -103,25 +107,40 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -103,25 +107,40 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
bool found = false;
foreach (var pair in namedCtorArguments) {
if (pair.Key == p.Name) {
result.Add(pair.Value);
result.Add(Resolve(pair.Value, context));
found = true;
}
}
if (!found) {
// add the parameter's default value:
result.Add(p.DefaultValue ?? new SimpleConstantValue(p.Type, CSharpResolver.GetDefaultValue(p.Type.Resolve(context))));
if (p.DefaultValue != null) {
result.Add(Resolve(p.DefaultValue, context));
} else {
IType type = p.Type.Resolve(context);
result.Add(new ConstantResolveResult(type, CSharpResolver.GetDefaultValue(type)));
}
}
}
}
return result.AsReadOnly();
}
public IList<KeyValuePair<string, IConstantValue>> GetNamedArguments(ITypeResolveContext context)
ResolveResult Resolve(IConstantValue constantValue, ITypeResolveContext context)
{
if (namedArguments != null)
return new ReadOnlyCollection<KeyValuePair<string, IConstantValue>>(namedArguments);
if (constantValue != null)
return constantValue.Resolve(context);
else
return EmptyList<KeyValuePair<string, IConstantValue>>.Instance;
return new ErrorResolveResult(SharedTypes.UnknownType);
}
public IList<KeyValuePair<string, ResolveResult>> GetNamedArguments(ITypeResolveContext context)
{
if (namedArguments != null) {
return namedArguments.Select(p => new KeyValuePair<string, ResolveResult>(p.Key, p.Value.Resolve(context)))
.ToList().AsReadOnly();
} else {
return EmptyList<KeyValuePair<string, ResolveResult>>.Instance;
}
}
}

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

@ -1960,7 +1960,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1960,7 +1960,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
// Look in local variables
foreach (IVariable v in this.LocalVariables) {
if (v.Name == identifier) {
object constantValue = v.IsConst ? v.ConstantValue.GetValue(context) : null;
object constantValue = v.IsConst ? v.ConstantValue.Resolve(context).ConstantValue : null;
return new LocalResolveResult(v, v.Type.Resolve(context), constantValue);
}
}
@ -2788,7 +2788,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2788,7 +2788,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// Specifies whether to allow treating single-dimensional arrays like compile-time constants.
/// This is used for attribute arguments.
/// </param>
public ArrayCreateResolveResult ResolveArrayCreation(IType elementType, int dimensions = 1, ResolveResult[] sizeArguments = null, ResolveResult[] initializerElements = null, bool allowArrayConstants = false)
public ArrayCreateResolveResult ResolveArrayCreation(IType elementType, int dimensions = 1, ResolveResult[] sizeArguments = null, ResolveResult[] initializerElements = null)
{
if (sizeArguments != null && dimensions != Math.Max(1, sizeArguments.Length))
throw new ArgumentException("dimensions and sizeArguments.Length don't match");
@ -2807,7 +2807,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2807,7 +2807,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
initializerElements[i] = Convert(initializerElements[i], elementType);
}
}
return new ArrayCreateResolveResult(arrayType, sizeArguments, initializerElements, allowArrayConstants);
return new ArrayCreateResolveResult(arrayType, sizeArguments, initializerElements);
}
#endregion
}

120
ICSharpCode.NRefactory/CSharp/Resolver/ConstantValues.cs

@ -57,72 +57,56 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver.ConstantValues @@ -57,72 +57,56 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver.ConstantValues
};
}
sealed class ConstantValueResult
{
public readonly IType ValueType;
public readonly object Value;
public ConstantValueResult(IType valueType, object value)
{
this.ValueType = valueType;
this.Value = value;
}
}
ConstantValueResult DoResolve(ITypeResolveContext context)
public ResolveResult Resolve(ITypeResolveContext context)
{
CacheManager cache = context.CacheManager;
if (cache != null) {
ConstantValueResult cachedResult = cache.GetShared(this) as ConstantValueResult;
ResolveResult cachedResult = cache.GetShared(this) as ResolveResult;
if (cachedResult != null)
return cachedResult;
}
CSharpResolver resolver = CreateResolver(context);
ResolveResult rr = expression.Resolve(resolver);
IType type = rr.Type;
object val = rr.ConstantValue;
if (resolver.Context != context) {
// Retrieve the equivalent type in the new resolve context.
// E.g. if the constant is defined in a .NET 2.0 project, type might be Int32 from mscorlib 2.0.
// However, the calling project might be a .NET 4.0 project, so we need to return Int32 from mscorlib 4.0.
type = type.AcceptVisitor(new MapTypeIntoNewContext(context));
// If 'val' is a type or an array containing types, we need to map it to the new context.
val = MapToNewContext(val, context);
}
ConstantValueResult result = new ConstantValueResult(type, val);
// Retrieve the equivalent type in the new resolve context.
// E.g. if the constant is defined in a .NET 2.0 project, type might be Int32 from mscorlib 2.0.
// However, the calling project might be a .NET 4.0 project, so we need to return Int32 from mscorlib 4.0.
rr = MapToNewContext(rr, new MapTypeIntoNewContext(context));
if (cache != null)
cache.SetShared(this, result);
return result;
}
public IType GetValueType(ITypeResolveContext context)
{
return DoResolve(context).ValueType;
}
public object GetValue(ITypeResolveContext context)
{
return DoResolve(context).Value;
cache.SetShared(this, rr);
return rr;
}
static ResolveResult MapToNewContext(ResolveResult rr, MapTypeIntoNewContext mapping)
{
if (rr is TypeOfResolveResult) {
return new TypeOfResolveResult(
rr.Type.AcceptVisitor(mapping),
((TypeOfResolveResult)rr).ReferencedType.AcceptVisitor(mapping));
} else if (rr is ArrayCreateResolveResult) {
ArrayCreateResolveResult acrr = (ArrayCreateResolveResult)rr;
return new ArrayCreateResolveResult(
acrr.Type.AcceptVisitor(mapping),
MapToNewContext(acrr.SizeArguments, mapping),
MapToNewContext(acrr.InitializerElements, mapping));
} else if (rr.IsCompileTimeConstant) {
return new ConstantResolveResult(
rr.Type.AcceptVisitor(mapping),
rr.ConstantValue
);
} else {
return new ErrorResolveResult(rr.Type.AcceptVisitor(mapping));
}
}
static object MapToNewContext(object val, ITypeResolveContext context)
static ResolveResult[] MapToNewContext(ResolveResult[] input, MapTypeIntoNewContext mapping)
{
IType type = val as IType;
if (type != null) {
return type.AcceptVisitor(new MapTypeIntoNewContext(context));
}
object[] arr = val as object[];
if (arr != null) {
object[] newArr = new object[arr.Length];
bool modified = false;
for (int i = 0; i < arr.Length; i++) {
newArr[i] = MapToNewContext(arr[i], context);
modified |= arr[i] != newArr[i];
}
if (modified)
return newArr;
if (input == null)
return null;
ResolveResult[] output = new ResolveResult[input.Length];
for (int i = 0; i < input.Length; i++) {
output[i] = MapToNewContext(input[i], mapping);
}
return val;
return output;
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
@ -170,21 +154,19 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver.ConstantValues @@ -170,21 +154,19 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver.ConstantValues
}
}
public IType GetValueType(ITypeResolveContext context)
{
return baseValue.GetValueType(context);
}
public object GetValue(ITypeResolveContext context)
public ResolveResult Resolve(ITypeResolveContext context)
{
object val = baseValue.GetValue(context);
if (val == null)
return null;
TypeCode typeCode = Type.GetTypeCode(val.GetType());
if (!(typeCode >= TypeCode.SByte && typeCode <= TypeCode.UInt64))
return null;
long intVal = (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, val, false);
return CSharpPrimitiveCast.Cast(typeCode, unchecked(intVal + incrementAmount), false);
ResolveResult rr = baseValue.Resolve(context);
if (rr.IsCompileTimeConstant && rr.ConstantValue != null) {
object val = rr.ConstantValue;
TypeCode typeCode = Type.GetTypeCode(val.GetType());
if (typeCode >= TypeCode.SByte && typeCode <= TypeCode.UInt64) {
long intVal = (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, val, false);
object newVal = CSharpPrimitiveCast.Cast(typeCode, unchecked(intVal + incrementAmount), false);
return new ConstantResolveResult(rr.Type, newVal);
}
}
return new ErrorResolveResult(rr.Type);
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
@ -672,9 +654,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver.ConstantValues @@ -672,9 +654,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver.ConstantValues
elements[i] = arrayElements[i].Resolve(resolver);
}
if (elementType != null) {
return resolver.ResolveArrayCreation(elementType.Resolve(resolver.Context), 1, null, elements, true);
return resolver.ResolveArrayCreation(elementType.Resolve(resolver.Context), 1, null, elements);
} else {
return resolver.ResolveArrayCreation(null, 1, null, elements, true);
return resolver.ResolveArrayCreation(null, 1, null, elements);
}
}

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

@ -60,7 +60,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -60,7 +60,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (field != null) {
isConstant = field.IsConst;
if (isConstant)
constantValue = field.ConstantValue.GetValue(context);
constantValue = field.ConstantValue.Resolve(context).ConstantValue;
}
}

51
ICSharpCode.NRefactory/CSharp/Resolver/OperatorResolveResult.cs

@ -147,60 +147,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -147,60 +147,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
readonly object[] constantArray;
public ArrayCreateResolveResult(IType arrayType, ResolveResult[] sizeArguments, ResolveResult[] initializerElements,
bool allowArrayConstants)
public ArrayCreateResolveResult(IType arrayType, ResolveResult[] sizeArguments, ResolveResult[] initializerElements)
: base(arrayType)
{
this.SizeArguments = sizeArguments;
this.InitializerElements = initializerElements;
if (allowArrayConstants) {
this.constantArray = MakeConstantArray(sizeArguments, initializerElements);
}
}
static object[] MakeConstantArray(ResolveResult[] sizeArguments, ResolveResult[] initializerElements)
{
if (initializerElements == null)
return null;
for (int i = 0; i < initializerElements.Length; i++) {
if (!initializerElements[i].IsCompileTimeConstant)
return null;
}
if (sizeArguments != null && sizeArguments.Length > 0) {
if (sizeArguments.Length > 1) {
// 2D-arrays can't be constant
return null;
}
if (!sizeArguments[0].IsCompileTimeConstant)
return null;
int expectedSize;
try {
expectedSize = (int)CSharpPrimitiveCast.Cast(TypeCode.Int32, sizeArguments[0].ConstantValue, true);
} catch (InvalidCastException) {
return null;
} catch (OverflowException) {
return null;
}
if (expectedSize != initializerElements.Length)
return null;
}
object[] constants = new object[initializerElements.Length];
for (int i = 0; i < initializerElements.Length; i++) {
constants[i] = initializerElements[i].ConstantValue;
}
return constants;
}
public override object ConstantValue {
get { return constantArray; }
}
public override bool IsCompileTimeConstant {
get { return constantArray != null; }
}
public override IEnumerable<ResolveResult> GetChildResults()

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

@ -607,7 +607,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -607,7 +607,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
string identifier = variableInitializer.Name;
foreach (IVariable v in resolver.LocalVariables) {
if (v.Name == identifier) {
object constantValue = v.IsConst ? v.ConstantValue.GetValue(resolver.Context) : null;
object constantValue = v.IsConst ? v.ConstantValue.Resolve(resolver.Context).ConstantValue : null;
result = new LocalResolveResult(v, v.Type.Resolve(resolver.Context), constantValue);
break;
}
@ -936,18 +936,23 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -936,18 +936,23 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
int dimensions = arrayCreateExpression.Arguments.Count;
ResolveResult[] sizeArguments;
IEnumerable<ArraySpecifier> additionalArraySpecifiers;
if (dimensions == 0) {
dimensions = 1;
sizeArguments = null;
} else {
if (arrayCreateExpression.Arguments.All(e => e is EmptyExpression)) {
sizeArguments = null;
var firstSpecifier = arrayCreateExpression.AdditionalArraySpecifiers.FirstOrDefault();
if (firstSpecifier != null) {
dimensions = firstSpecifier.Dimensions;
additionalArraySpecifiers = arrayCreateExpression.AdditionalArraySpecifiers.Skip(1);
} else {
sizeArguments = new ResolveResult[dimensions];
int pos = 0;
foreach (var node in arrayCreateExpression.Arguments)
sizeArguments[pos++] = Resolve(node);
dimensions = 0;
additionalArraySpecifiers = arrayCreateExpression.AdditionalArraySpecifiers;
}
sizeArguments = null;
} else {
sizeArguments = new ResolveResult[dimensions];
int pos = 0;
foreach (var node in arrayCreateExpression.Arguments)
sizeArguments[pos++] = Resolve(node);
additionalArraySpecifiers = arrayCreateExpression.AdditionalArraySpecifiers;
}
List<Expression> initializerElements;
@ -971,7 +976,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -971,7 +976,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
acrr = resolver.ResolveArrayCreation(null, dimensions, sizeArguments, initializerElementResults);
} else {
IType elementType = ResolveType(arrayCreateExpression.Type);
foreach (var spec in arrayCreateExpression.AdditionalArraySpecifiers.Reverse()) {
foreach (var spec in additionalArraySpecifiers.Reverse()) {
elementType = new ArrayType(elementType, spec.Dimensions);
}
acrr = resolver.ResolveArrayCreation(elementType, dimensions, sizeArguments, initializerElementResults);

44
ICSharpCode.NRefactory/CSharp/Resolver/TypeOfResolveResult.cs

@ -0,0 +1,44 @@ @@ -0,0 +1,44 @@
// 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 ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.NRefactory.CSharp.Resolver
{
/// <summary>
/// Represents the 'typeof'.
/// </summary>
public class TypeOfResolveResult : ResolveResult
{
readonly IType referencedType;
public TypeOfResolveResult(IType systemType, IType referencedType)
: base(systemType)
{
this.referencedType = referencedType;
}
/// <summary>
/// The type referenced by the 'typeof'.
/// </summary>
public IType ReferencedType {
get { return referencedType; }
}
}
}

1
ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj

@ -115,6 +115,7 @@ @@ -115,6 +115,7 @@
<Compile Include="CSharp\Resolver\MapTypeIntoNewContext.cs" />
<Compile Include="CSharp\Resolver\ResolveAtLocation.cs" />
<Compile Include="CSharp\Resolver\SimpleNameLookupMode.cs" />
<Compile Include="CSharp\Resolver\TypeOfResolveResult.cs" />
<Compile Include="Documentation\IDStringProvider.cs" />
<Compile Include="PatternMatching\BacktrackingInfo.cs" />
<Compile Include="PatternMatching\Choice.cs" />

5
ICSharpCode.NRefactory/TypeSystem/IAttribute.cs

@ -19,6 +19,7 @@ @@ -19,6 +19,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using ICSharpCode.NRefactory.CSharp.Resolver;
namespace ICSharpCode.NRefactory.TypeSystem
{
@ -44,12 +45,12 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -44,12 +45,12 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// <summary>
/// Gets the positional arguments passed to the attribute.
/// </summary>
IList<IConstantValue> GetPositionalArguments(ITypeResolveContext context);
IList<ResolveResult> GetPositionalArguments(ITypeResolveContext context);
/// <summary>
/// Gets the named arguments passed to the attribute.
/// </summary>
IList<KeyValuePair<string, IConstantValue>> GetNamedArguments(ITypeResolveContext context);
IList<KeyValuePair<string, ResolveResult>> GetNamedArguments(ITypeResolveContext context);
/// <summary>
/// Resolves the constructor method used for this attribute invocation.

32
ICSharpCode.NRefactory/TypeSystem/IConstantValue.cs

@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
using System;
using System.Diagnostics.Contracts;
using ICSharpCode.NRefactory.CSharp.Resolver;
namespace ICSharpCode.NRefactory.TypeSystem
{
@ -27,40 +28,21 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -27,40 +28,21 @@ namespace ICSharpCode.NRefactory.TypeSystem
public interface IConstantValue : IFreezable
{
/// <summary>
/// Gets the type of the constant value.
/// Resolves the value of this constant.
/// </summary>
IType GetValueType(ITypeResolveContext context);
/// <summary>
/// Gets the .NET value of the constant value.
/// Possible return values are:
/// - null
/// - primitive integers
/// - float/double
/// - bool
/// - string
/// - IType (for typeof-expressions)
/// and arrays of these values. Enum values are returned using the underlying primitive integer.
///
/// TODO: how do we represent errors (value not available?)
/// </summary>
object GetValue(ITypeResolveContext context);
/// <param name="context">Type resolve context where the constant value will be used.</param>
/// <returns>Resolve result representing the constant value.</returns>
ResolveResult Resolve(ITypeResolveContext context);
}
#if WITH_CONTRACTS
[ContractClassFor(typeof(IConstantValue))]
abstract class IConstantValueContract : IFreezableContract, IConstantValue
{
IType IConstantValue.GetValueType(ITypeResolveContext context)
{
Contract.Requires(context != null);
Contract.Ensures(Contract.Result<IType>() != null);
return null;
}
object IConstantValue.GetValue(ITypeResolveContext context)
ResolveResult IConstantValue.Resolve(ITypeResolveContext context)
{
Contract.Requires(context != null);
Contract.Ensures(Contract.Result<ResolveResult>() != null);
return null;
}
}

9
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultAttribute.cs

@ -21,6 +21,7 @@ using System.Collections.Generic; @@ -21,6 +21,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using ICSharpCode.NRefactory.CSharp.Resolver;
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{
@ -84,9 +85,9 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -84,9 +85,9 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
}
}
IList<IConstantValue> IAttribute.GetPositionalArguments(ITypeResolveContext context)
public IList<ResolveResult> GetPositionalArguments(ITypeResolveContext context)
{
return this.PositionalArguments;
return this.PositionalArguments.Select(a => a.Resolve(context)).ToList();
}
public IList<KeyValuePair<string, IConstantValue>> NamedArguments {
@ -97,9 +98,9 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -97,9 +98,9 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
}
}
IList<KeyValuePair<string, IConstantValue>> IAttribute.GetNamedArguments(ITypeResolveContext context)
public IList<KeyValuePair<string, ResolveResult>> GetNamedArguments(ITypeResolveContext context)
{
return this.NamedArguments;
return this.NamedArguments.Select(p => new KeyValuePair<string, ResolveResult>(p.Key, p.Value.Resolve(context))).ToList();
}
public IMethod ResolveConstructor(ITypeResolveContext context)

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

@ -105,14 +105,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -105,14 +105,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
}
}
public object GetDefaultValue(ITypeResolveContext context)
{
if (defaultValue == null)
throw new InvalidOperationException();
else
return defaultValue.GetValue(context);
}
public DomRegion Region {
get { return region; }
set {

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

@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE.
using System;
using ICSharpCode.NRefactory.CSharp.Resolver;
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{
@ -37,17 +38,13 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -37,17 +38,13 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
this.value = value;
}
public IType GetValueType(ITypeResolveContext context)
public ResolveResult Resolve(ITypeResolveContext context)
{
return type.Resolve(context);
}
public object GetValue(ITypeResolveContext context)
{
if (value is ITypeReference)
return ((ITypeReference)value).Resolve(context);
else
return value;
if (value is ITypeReference) {
return new TypeOfResolveResult(type.Resolve(context), ((ITypeReference)value).Resolve(context));
} else {
return new ConstantResolveResult(type.Resolve(context), value);
}
}
public override string ToString()

Loading…
Cancel
Save