Browse Source

Fixed several issues in the type system convert visitor.

newNRvisualizers
Daniel Grunwald 15 years ago
parent
commit
fb57f7d545
  1. 17
      ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/TypeOfExpressionTests.cs
  2. 8
      ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/TypeDeclarationTests.cs
  3. 1
      ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.cs
  4. 10
      ICSharpCode.NRefactory.VB/Ast/GlobalScope/TypeDeclaration.cs
  5. 55
      ICSharpCode.NRefactory/CSharp/Parser/TypeSystemConvertVisitor.cs
  6. 26
      ICSharpCode.NRefactory/CSharp/Resolver/CSharpResolver.cs
  7. 56
      ICSharpCode.NRefactory/CSharp/Resolver/ConstantValues.cs

17
ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/TypeOfExpressionTests.cs

@ -118,7 +118,22 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression @@ -118,7 +118,22 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
"typeof(MyType<,>)",
new TypeOfExpression {
Type = type
});
});
}
[Test]
public void NestedArraysTest()
{
ParseUtilCSharp.AssertExpression(
"typeof(int[,][])",
new TypeOfExpression {
Type = new ComposedType {
BaseType = new PrimitiveType("int"),
ArraySpecifiers = {
new ArraySpecifier(2),
new ArraySpecifier(1)
}
}});
}
}
}

8
ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/TypeDeclarationTests.cs

@ -280,5 +280,13 @@ public abstract class MyClass : MyBase, Interface1, My.Test.Interface2 @@ -280,5 +280,13 @@ public abstract class MyClass : MyBase, Interface1, My.Test.Interface2
Assert.AreEqual("Val1", member.Name);
Assert.AreEqual(10, ((PrimitiveExpression)member.Initializer).Value);
}
[Test]
public void EnumWithBaseType()
{
TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>("enum MyEnum : short { }");
Assert.AreEqual("MyEnum", td.Name);
Assert.AreEqual("short", ((PrimitiveType)td.BaseTypes.Single()).Keyword);
}
}
}

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

@ -51,7 +51,6 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -51,7 +51,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
public void SimplePublicClassMethodTest()
{
ITypeDefinition c = testCasePC.GetClass(typeof(SimplePublicClass));
Assert.AreEqual(2, c.Methods.Count);
IMethod method = c.Methods.Single(m => m.Name == "Method");
Assert.AreEqual(typeof(SimplePublicClass).FullName + ".Method", method.FullName);

10
ICSharpCode.NRefactory.VB/Ast/GlobalScope/TypeDeclaration.cs

@ -20,9 +20,11 @@ namespace ICSharpCode.NRefactory.VB.Ast @@ -20,9 +20,11 @@ namespace ICSharpCode.NRefactory.VB.Ast
public ClassType ClassType { get; set; }
public Identifier NameToken {
get { return GetChildByRole(Roles.Identifier); }
set { SetChildByRole(Roles.Identifier, value); }
public string Name {
get { return GetChildByRole(Roles.Identifier).Name; }
set {
SetChildByRole(Roles.Identifier, new Identifier(value, AstLocation.Empty));
}
}
public AstNodeCollection<TypeParameterDeclaration> TypeParameters {
@ -44,7 +46,7 @@ namespace ICSharpCode.NRefactory.VB.Ast @@ -44,7 +46,7 @@ namespace ICSharpCode.NRefactory.VB.Ast
MatchAttributesAndModifiers(t, match) &&
Members.DoMatch(t.Members, match) &&
ClassType == t.ClassType &&
Name.DoMatch(t.Name, match) &&
MatchString(Name, t.Name) &&
TypeParameters.DoMatch(t.TypeParameters, match) &&
InheritsType.DoMatch(t.InheritsType, match) &&
ImplementsTypes.DoMatch(t.ImplementsTypes, match);

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

@ -126,6 +126,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -126,6 +126,7 @@ namespace ICSharpCode.NRefactory.CSharp
DefaultTypeDefinition newType;
if (currentTypeDefinition != null) {
newType = new DefaultTypeDefinition(currentTypeDefinition, name);
newType.TypeParameters.AddRange(currentTypeDefinition.TypeParameters);
currentTypeDefinition.InnerClasses.Add(newType);
} else {
newType = new DefaultTypeDefinition(usingScope.ProjectContent, usingScope.NamespaceName, name);
@ -149,7 +150,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -149,7 +150,7 @@ namespace ICSharpCode.NRefactory.CSharp
else if (td.ClassType == ClassType.Enum || td.ClassType == ClassType.Struct)
td.IsSealed = true; // enums/structs are implicitly sealed
ConvertTypeParameters(td.TypeParameters, typeDeclaration.TypeParameters, typeDeclaration.Constraints);
ConvertTypeParameters(td.TypeParameters, typeDeclaration.TypeParameters, typeDeclaration.Constraints, EntityType.TypeDefinition);
foreach (AstType baseType in typeDeclaration.BaseTypes) {
td.BaseTypes.Add(ConvertType(baseType));
@ -175,7 +176,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -175,7 +176,7 @@ namespace ICSharpCode.NRefactory.CSharp
ApplyModifiers(td, delegateDeclaration.Modifiers);
td.IsSealed = true; // delegates are implicitly sealed
ConvertTypeParameters(td.TypeParameters, delegateDeclaration.TypeParameters, delegateDeclaration.Constraints);
ConvertTypeParameters(td.TypeParameters, delegateDeclaration.TypeParameters, delegateDeclaration.Constraints, EntityType.TypeDefinition);
ITypeReference returnType = ConvertType(delegateDeclaration.ReturnType);
List<IParameter> parameters = new List<IParameter>();
@ -303,7 +304,12 @@ namespace ICSharpCode.NRefactory.CSharp @@ -303,7 +304,12 @@ namespace ICSharpCode.NRefactory.CSharp
if (!enumMemberDeclaration.Initializer.IsNull) {
field.ConstantValue = ConvertConstantValue(currentTypeDefinition, enumMemberDeclaration.Initializer);
} else {
throw new NotImplementedException();
IField prevField = currentTypeDefinition.Fields.LastOrDefault();
if (prevField == null || prevField.ConstantValue == null) {
field.ConstantValue = ConvertConstantValue(currentTypeDefinition, new PrimitiveExpression(0));
} else {
field.ConstantValue = new IncrementConstantValue(prevField.ConstantValue);
}
}
currentTypeDefinition.Fields.Add(field);
@ -320,7 +326,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -320,7 +326,7 @@ namespace ICSharpCode.NRefactory.CSharp
m.BodyRegion = MakeRegion(methodDeclaration.Body);
ConvertTypeParameters(m.TypeParameters, methodDeclaration.TypeParameters, methodDeclaration.Constraints);
ConvertTypeParameters(m.TypeParameters, methodDeclaration.TypeParameters, methodDeclaration.Constraints, EntityType.Method);
m.ReturnType = ConvertType(methodDeclaration.ReturnType);
ConvertAttributes(m.Attributes, methodDeclaration.Attributes.Where(s => s.AttributeTarget != "return"));
ConvertAttributes(m.ReturnTypeAttributes, methodDeclaration.Attributes.Where(s => s.AttributeTarget == "return"));
@ -339,10 +345,41 @@ namespace ICSharpCode.NRefactory.CSharp @@ -339,10 +345,41 @@ namespace ICSharpCode.NRefactory.CSharp
return m;
}
void ConvertTypeParameters(IList<ITypeParameter> output, IEnumerable<TypeParameterDeclaration> typeParameters, IEnumerable<Constraint> constraints)
{
if (typeParameters.Any())
throw new NotImplementedException();
void ConvertTypeParameters(IList<ITypeParameter> output, AstNodeCollection<TypeParameterDeclaration> typeParameters, AstNodeCollection<Constraint> constraints, EntityType ownerType)
{
// output might be non-empty when type parameters were copied from an outer class
int index = output.Count;
List<DefaultTypeParameter> list = new List<DefaultTypeParameter>();
foreach (TypeParameterDeclaration tpDecl in typeParameters) {
DefaultTypeParameter tp = new DefaultTypeParameter(ownerType, index++, tpDecl.Name);
ConvertAttributes(tp.Attributes, tpDecl.Attributes);
tp.Variance = tpDecl.Variance;
list.Add(tp);
output.Add(tp); // tp must be added to list here so that it can be referenced by constraints
}
foreach (Constraint c in constraints) {
foreach (var tp in list) {
if (tp.Name == c.TypeParameter) {
foreach (AstType type in c.BaseTypes) {
PrimitiveType primType = type as PrimitiveType;
if (primType != null) {
if (primType.Keyword == "new") {
tp.HasDefaultConstructorConstraint = true;
continue;
} else if (primType.Keyword == "class") {
tp.HasReferenceTypeConstraint = true;
continue;
} else if (primType.Keyword == "struct") {
tp.HasValueTypeConstraint = true;
continue;
}
}
tp.Constraints.Add(ConvertType(type));
}
break;
}
}
}
}
DefaultExplicitInterfaceImplementation ConvertInterfaceImplementation(AstType interfaceType, string memberName)
@ -627,7 +664,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -627,7 +664,7 @@ namespace ICSharpCode.NRefactory.CSharp
} else {
if (positionalArguments == null)
positionalArguments = new List<IConstantValue>();
positionalArguments.Add(ConvertAttributeArgument(nae.Expression));
positionalArguments.Add(ConvertAttributeArgument(expr));
}
}
}

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

@ -1622,13 +1622,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1622,13 +1622,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
NamespaceResolveResult ns = u.ResolveNamespace(context);
if (ns != null) {
def = context.GetClass(ns.NamespaceName, identifier, k, StringComparer.Ordinal);
if (firstResult == null) {
if (k == 0)
firstResult = def;
else
firstResult = new ParameterizedType(def, typeArguments);
} else {
return new AmbiguousTypeResolveResult(firstResult);
if (def != null) {
if (firstResult == null) {
if (k == 0)
firstResult = def;
else
firstResult = new ParameterizedType(def, typeArguments);
} else {
return new AmbiguousTypeResolveResult(firstResult);
}
}
}
}
@ -1637,10 +1639,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1637,10 +1639,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
// if we didn't find anything: repeat lookup with parent namespace
}
if (typeArguments.Count == 0)
return new UnknownIdentifierResolveResult(identifier);
else
if (typeArguments.Count == 0) {
if (identifier == "dynamic")
return new TypeResolveResult(SharedTypes.Dynamic);
else
return new UnknownIdentifierResolveResult(identifier);
} else {
return ErrorResult;
}
}
/// <summary>

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

@ -107,6 +107,62 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver.ConstantValues @@ -107,6 +107,62 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver.ConstantValues
}
}
/// <summary>
/// Increments an integer <see cref="IConstantValue"/> by a fixed amount without changing the type.
/// </summary>
public sealed class IncrementConstantValue : Immutable, IConstantValue, ISupportsInterning
{
IConstantValue baseValue;
int incrementAmount;
public IncrementConstantValue(IConstantValue baseValue, int incrementAmount = 1)
{
if (baseValue == null)
throw new ArgumentNullException("baseValue");
IncrementConstantValue icv = baseValue as IncrementConstantValue;
if (icv != null) {
this.baseValue = icv.baseValue;
this.incrementAmount = icv.incrementAmount + incrementAmount;
} else {
this.baseValue = baseValue;
this.incrementAmount = incrementAmount;
}
}
public IType GetValueType(ITypeResolveContext context)
{
return baseValue.GetValueType(context);
}
public object GetValue(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);
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
baseValue = provider.Intern(baseValue);
}
int ISupportsInterning.GetHashCodeForInterning()
{
return baseValue.GetHashCode() ^ incrementAmount;
}
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
{
IncrementConstantValue o = other as IncrementConstantValue;
return o != null && baseValue == o.baseValue && incrementAmount == o.incrementAmount;
}
}
public abstract class ConstantExpression
{
public abstract ResolveResult Resolve(CSharpResolver resolver);

Loading…
Cancel
Save