Browse Source

Fixed some bugs; added support for type references to TypeSystemConvertVisitor.

newNRvisualizers
Daniel Grunwald 15 years ago
parent
commit
7e530a90ac
  1. 37
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/SimpleNameLookupTests.cs
  2. 6
      ICSharpCode.NRefactory/CSharp/Dom/ComposedType.cs
  3. 4
      ICSharpCode.NRefactory/CSharp/Dom/TypeMembers/AbstractMember.cs
  4. 7
      ICSharpCode.NRefactory/CSharp/Dom/TypeMembers/EventDeclaration.cs
  5. 7
      ICSharpCode.NRefactory/CSharp/Dom/TypeMembers/OperatorDeclaration.cs
  6. 7
      ICSharpCode.NRefactory/CSharp/Dom/TypeMembers/PropertyDeclaration.cs
  7. 114
      ICSharpCode.NRefactory/CSharp/Parser/TypeSystemConvertVisitor.cs
  8. 25
      ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs

37
ICSharpCode.NRefactory.Tests/CSharp/Resolver/SimpleNameLookupTests.cs

@ -175,5 +175,42 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
Assert.AreEqual("System.String", result.Type.FullName); Assert.AreEqual("System.String", result.Type.FullName);
} }
[Test]
public void UnknownTypeTest()
{
string program = @"class A {
void Method($StringBuilder$ b) {
}
}
";
UnknownIdentifierResolveResult result = Resolve<UnknownIdentifierResolveResult>(program);
Assert.AreEqual("StringBuilder", result.Identifier);
Assert.AreSame(SharedTypes.UnknownType, result.Type);
}
[Test, Ignore("not yet implemented (depends on distuishing types and expressions)")]
public void PropertyNameAmbiguousWithTypeName()
{
string program = @"class A {
public Color Color { get; set; }
void Method() {
$
}
}
class Color { public static readonly Color Empty = null; }
";
TypeResolveResult trr = Resolve<TypeResolveResult>(program.Replace("$", "$Color$ c;"));
Assert.AreEqual("Color", trr.Type.Name);
MemberResolveResult mrr = Resolve<MemberResolveResult>(program.Replace("$", "x = $Color$;"));
Assert.AreEqual("Color", mrr.Member.Name);
Resolve<MemberResolveResult>(program.Replace("$", "$Color$ = Color.Empty;"));
Resolve<TypeResolveResult>(program.Replace("$", "Color = $Color$.Empty;"));
Resolve<MemberResolveResult>(program.Replace("$", "x = $Color$.ToString();"));
}
} }
} }

6
ICSharpCode.NRefactory/CSharp/Dom/ComposedType.cs

@ -74,7 +74,7 @@ namespace ICSharpCode.NRefactory.CSharp
b.Append('*', this.PointerRank); b.Append('*', this.PointerRank);
foreach (var arraySpecifier in this.ArraySpecifiers) { foreach (var arraySpecifier in this.ArraySpecifiers) {
b.Append('['); b.Append('[');
b.Append(',', arraySpecifier.Rank); b.Append(',', arraySpecifier.Dimensions - 1);
b.Append(']'); b.Append(']');
} }
return b.ToString(); return b.ToString();
@ -92,8 +92,8 @@ namespace ICSharpCode.NRefactory.CSharp
get { return (CSharpTokenNode)GetChildByRole (Roles.LBracket); } get { return (CSharpTokenNode)GetChildByRole (Roles.LBracket); }
} }
public int Rank { public int Dimensions {
get { return GetChildrenByRole(Roles.Comma).Count(); } get { return 1 + GetChildrenByRole(Roles.Comma).Count(); }
} }
public CSharpTokenNode RBracket { public CSharpTokenNode RBracket {

4
ICSharpCode.NRefactory/CSharp/Dom/TypeMembers/AbstractMember.cs

@ -1,4 +1,4 @@
// //
// AbstractMember.cs // AbstractMember.cs
// //
// Author: // Author:
@ -28,7 +28,7 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
public abstract class AbstractMember : AbstractMemberBase public abstract class AbstractMember : AbstractMemberBase
{ {
const int PrivateImplementationTypeRole = 100; public const int PrivateImplementationTypeRole = 100;
public DomNode ReturnType { public DomNode ReturnType {
get { get {

7
ICSharpCode.NRefactory/CSharp/Dom/TypeMembers/EventDeclaration.cs

@ -1,4 +1,4 @@
// //
// EventDeclaration.cs // EventDeclaration.cs
// //
// Author: // Author:
@ -28,8 +28,9 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
public class EventDeclaration : AbstractMember public class EventDeclaration : AbstractMember
{ {
public const int EventAddRole = 100; // AbstractMember.PrivateImplementationTypeRole is 100
public const int EventRemoveRole = 101; public const int EventAddRole = 101;
public const int EventRemoveRole = 102;
public CSharpTokenNode LBrace { public CSharpTokenNode LBrace {
get { get {

7
ICSharpCode.NRefactory/CSharp/Dom/TypeMembers/OperatorDeclaration.cs

@ -1,4 +1,4 @@
// //
// OperatorDeclaration.cs // OperatorDeclaration.cs
// //
// Author: // Author:
@ -68,8 +68,9 @@ namespace ICSharpCode.NRefactory.CSharp
public class OperatorDeclaration : AbstractMember public class OperatorDeclaration : AbstractMember
{ {
public const int OperatorKeywordRole = 100; // AbstractMember.PrivateImplementationTypeRole is 100
public const int OperatorTypeRole = 101; public const int OperatorKeywordRole = 101;
public const int OperatorTypeRole = 102;
public OperatorType OperatorType { public OperatorType OperatorType {
get; get;

7
ICSharpCode.NRefactory/CSharp/Dom/TypeMembers/PropertyDeclaration.cs

@ -1,4 +1,4 @@
// //
// PropertyDeclaration.cs // PropertyDeclaration.cs
// //
// Author: // Author:
@ -28,8 +28,9 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
public class PropertyDeclaration : AbstractMember public class PropertyDeclaration : AbstractMember
{ {
public const int PropertyGetRole = 100; // AbstractMember.PrivateImplementationTypeRole is 100
public const int PropertySetRole = 101; public const int PropertyGetRole = 101;
public const int PropertySetRole = 102;
public CSharpTokenNode LBrace { public CSharpTokenNode LBrace {
get { get {

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

@ -3,8 +3,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using ICSharpCode.NRefactory.CSharp.Resolver; using ICSharpCode.NRefactory.CSharp.Resolver;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation; using ICSharpCode.NRefactory.TypeSystem.Implementation;
@ -74,23 +74,18 @@ namespace ICSharpCode.NRefactory.CSharp
public override IEntity VisitUsingDeclaration(UsingDeclaration usingDeclaration, object data) public override IEntity VisitUsingDeclaration(UsingDeclaration usingDeclaration, object data)
{ {
ITypeOrNamespaceReference r = null; ITypeOrNamespaceReference u = ConvertType(usingDeclaration.Import, true) as ITypeOrNamespaceReference;
/*foreach (Identifier identifier in usingDeclaration.NameIdentifier.NameParts) { if (u != null)
if (r == null) { usingScope.Usings.Add(u);
// TODO: alias?
r = new SimpleTypeOrNamespaceReference(identifier.Name, null, currentTypeDefinition, usingScope, true);
} else {
r = new MemberTypeOrNamespaceReference(r, identifier.Name, null, currentTypeDefinition, usingScope);
}
}*/throw new NotImplementedException();
if (r != null)
usingScope.Usings.Add(r);
return null; return null;
} }
public override IEntity VisitUsingAliasDeclaration(UsingAliasDeclaration usingDeclaration, object data) public override IEntity VisitUsingAliasDeclaration(UsingAliasDeclaration usingDeclaration, object data)
{ {
throw new NotImplementedException(); ITypeOrNamespaceReference u = ConvertType(usingDeclaration.Import, true) as ITypeOrNamespaceReference;
if (u != null)
usingScope.UsingAliases.Add(new KeyValuePair<string, ITypeOrNamespaceReference>(usingDeclaration.Alias, u));
return null;
} }
#endregion #endregion
@ -275,7 +270,7 @@ namespace ICSharpCode.NRefactory.CSharp
field.ReturnType = currentTypeDefinition; field.ReturnType = currentTypeDefinition;
field.Accessibility = Accessibility.Public; field.Accessibility = Accessibility.Public;
field.IsStatic = true; field.IsStatic = true;
if (enumMemberDeclaration.Initializer != null) { if (!enumMemberDeclaration.Initializer.IsNull) {
field.ConstantValue = ConvertConstantValue(currentTypeDefinition, enumMemberDeclaration.Initializer); field.ConstantValue = ConvertConstantValue(currentTypeDefinition, enumMemberDeclaration.Initializer);
} else { } else {
throw new NotImplementedException(); throw new NotImplementedException();
@ -304,7 +299,7 @@ namespace ICSharpCode.NRefactory.CSharp
m.IsExtensionMethod = methodDeclaration.IsExtensionMethod; m.IsExtensionMethod = methodDeclaration.IsExtensionMethod;
ConvertParameters(m.Parameters, methodDeclaration.Parameters); ConvertParameters(m.Parameters, methodDeclaration.Parameters);
if (methodDeclaration.PrivateImplementationType != null) { if (!methodDeclaration.PrivateImplementationType.IsNull) {
m.Accessibility = Accessibility.None; m.Accessibility = Accessibility.None;
m.InterfaceImplementations.Add(ConvertInterfaceImplementation(methodDeclaration.PrivateImplementationType, m.Name)); m.InterfaceImplementations.Add(ConvertInterfaceImplementation(methodDeclaration.PrivateImplementationType, m.Name));
} }
@ -349,7 +344,7 @@ namespace ICSharpCode.NRefactory.CSharp
DefaultMethod ctor = new DefaultMethod(currentTypeDefinition, isStatic ? ".cctor" : ".ctor"); DefaultMethod ctor = new DefaultMethod(currentTypeDefinition, isStatic ? ".cctor" : ".ctor");
ctor.EntityType = EntityType.Constructor; ctor.EntityType = EntityType.Constructor;
ctor.Region = MakeRegion(constructorDeclaration); ctor.Region = MakeRegion(constructorDeclaration);
if (constructorDeclaration.Initializer != null) { if (!constructorDeclaration.Initializer.IsNull) {
ctor.BodyRegion = MakeRegion(constructorDeclaration.Initializer.StartLocation, constructorDeclaration.EndLocation); ctor.BodyRegion = MakeRegion(constructorDeclaration.Initializer.StartLocation, constructorDeclaration.EndLocation);
} else { } else {
ctor.BodyRegion = MakeRegion(constructorDeclaration.Body); ctor.BodyRegion = MakeRegion(constructorDeclaration.Body);
@ -403,7 +398,7 @@ namespace ICSharpCode.NRefactory.CSharp
ApplyModifiers(p, propertyDeclaration.Modifiers); ApplyModifiers(p, propertyDeclaration.Modifiers);
p.ReturnType = ConvertType(propertyDeclaration.ReturnType); p.ReturnType = ConvertType(propertyDeclaration.ReturnType);
ConvertAttributes(p.Attributes, propertyDeclaration.Attributes); ConvertAttributes(p.Attributes, propertyDeclaration.Attributes);
if (propertyDeclaration.PrivateImplementationType != null) { if (!propertyDeclaration.PrivateImplementationType.IsNull) {
p.Accessibility = Accessibility.None; p.Accessibility = Accessibility.None;
p.InterfaceImplementations.Add(ConvertInterfaceImplementation(propertyDeclaration.PrivateImplementationType, p.Name)); p.InterfaceImplementations.Add(ConvertInterfaceImplementation(propertyDeclaration.PrivateImplementationType, p.Name));
} }
@ -441,7 +436,7 @@ namespace ICSharpCode.NRefactory.CSharp
e.ReturnType = ConvertType(eventDeclaration.ReturnType); e.ReturnType = ConvertType(eventDeclaration.ReturnType);
ConvertAttributes(e.Attributes, eventDeclaration.Attributes); ConvertAttributes(e.Attributes, eventDeclaration.Attributes);
if (eventDeclaration.PrivateImplementationType != null) { if (!eventDeclaration.PrivateImplementationType.IsNull) {
e.Accessibility = Accessibility.None; e.Accessibility = Accessibility.None;
e.InterfaceImplementations.Add(ConvertInterfaceImplementation(eventDeclaration.PrivateImplementationType, e.Name)); e.InterfaceImplementations.Add(ConvertInterfaceImplementation(eventDeclaration.PrivateImplementationType, e.Name));
} }
@ -505,21 +500,96 @@ namespace ICSharpCode.NRefactory.CSharp
#region Types #region Types
static readonly GetClassTypeReference voidReference = new GetClassTypeReference("System.Void", 0); static readonly GetClassTypeReference voidReference = new GetClassTypeReference("System.Void", 0);
internal static ITypeReference ConvertType(DomNode node) ITypeReference ConvertType(DomNode node, bool isInUsingDeclaration = false)
{ {
PrimitiveType f = node as PrimitiveType; return ConvertType(node, currentTypeDefinition, currentMethod, usingScope, isInUsingDeclaration);
if (f != null) { }
switch (f.Keyword) {
internal static ITypeReference ConvertType(DomNode node, ITypeDefinition parentTypeDefinition, IMethod parentMethodDefinition, UsingScope parentUsingScope, bool isInUsingDeclaration)
{
SimpleType s = node as SimpleType;
if (s != null) {
List<ITypeReference> typeArguments = new List<ITypeReference>();
foreach (var ta in s.TypeArguments) {
typeArguments.Add(ConvertType(ta, parentTypeDefinition, parentMethodDefinition, parentUsingScope, isInUsingDeclaration));
}
if (s.IsQualifiedWithAlias) {
AliasNamespaceReference ar = new AliasNamespaceReference(s.AliasIdentifier.Name, parentUsingScope);
return new MemberTypeOrNamespaceReference(ar, s.Identifier, typeArguments, parentTypeDefinition, parentUsingScope);
} else {
if (typeArguments.Count == 0 && parentMethodDefinition != null) {
// SimpleTypeOrNamespaceReference doesn't support method type parameters,
// so we directly handle them here.
foreach (ITypeParameter tp in parentMethodDefinition.TypeParameters) {
if (tp.Name == s.Identifier)
return tp;
}
}
return new SimpleTypeOrNamespaceReference(s.Identifier, typeArguments, parentTypeDefinition, parentUsingScope, isInUsingDeclaration);
}
}
PrimitiveType p = node as PrimitiveType;
if (p != null) {
switch (p.Keyword) {
case "string": case "string":
return TypeCode.String.ToTypeReference(); return TypeCode.String.ToTypeReference();
case "int": case "int":
return TypeCode.Int32.ToTypeReference(); return TypeCode.Int32.ToTypeReference();
case "uint": case "uint":
return TypeCode.UInt32.ToTypeReference(); return TypeCode.UInt32.ToTypeReference();
case "object":
return TypeCode.Object.ToTypeReference();
case "bool":
return TypeCode.Boolean.ToTypeReference();
case "sbyte":
return TypeCode.SByte.ToTypeReference();
case "byte":
return TypeCode.Byte.ToTypeReference();
case "short":
return TypeCode.Int16.ToTypeReference();
case "ushort":
return TypeCode.UInt16.ToTypeReference();
case "long":
return TypeCode.Int64.ToTypeReference();
case "ulong":
return TypeCode.UInt64.ToTypeReference();
case "float":
return TypeCode.Single.ToTypeReference();
case "double":
return TypeCode.Double.ToTypeReference();
case "decimal":
return TypeCode.Decimal.ToTypeReference();
case "void": case "void":
return voidReference; return voidReference;
default:
return SharedTypes.UnknownType;
}
}
MemberType m = node as MemberType;
if (m != null) {
ITypeOrNamespaceReference t = ConvertType(m.Target, parentTypeDefinition, parentMethodDefinition, parentUsingScope, isInUsingDeclaration) as ITypeOrNamespaceReference;
if (t == null)
return SharedTypes.UnknownType;
List<ITypeReference> typeArguments = new List<ITypeReference>();
foreach (var ta in m.TypeArguments) {
typeArguments.Add(ConvertType(ta, parentTypeDefinition, parentMethodDefinition, parentUsingScope, isInUsingDeclaration));
}
return new MemberTypeOrNamespaceReference(t, m.Identifier, typeArguments, parentTypeDefinition, parentUsingScope);
}
ComposedType c = node as ComposedType;
if (c != null) {
ITypeReference t = ConvertType(c.BaseType, parentTypeDefinition, parentMethodDefinition, parentUsingScope, isInUsingDeclaration);
if (c.HasNullableSpecifier) {
t = NullableType.Create(t);
}
for (int i = 0; i < c.PointerRank; i++) {
t = PointerTypeReference.Create(t);
}
foreach (var a in c.ArraySpecifiers.Reverse()) {
t = ArrayTypeReference.Create(t, a.Dimensions);
} }
} }
Debug.WriteLine("Unknown node used as type: " + node);
return SharedTypes.UnknownType; return SharedTypes.UnknownType;
} }
#endregion #endregion

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

@ -945,10 +945,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (initializerExpression != null && IsVar(type)) { if (initializerExpression != null && IsVar(type)) {
return new VarTypeReference(this, resolver.Clone(), initializerExpression, isForEach); return new VarTypeReference(this, resolver.Clone(), initializerExpression, isForEach);
} else { } else {
return TypeSystemConvertVisitor.ConvertType(type); return MakeTypeReference(type);
} }
} }
ITypeReference MakeTypeReference(DomNode type)
{
return TypeSystemConvertVisitor.ConvertType(type, resolver.CurrentTypeDefinition, resolver.CurrentMember as IMethod, resolver.UsingScope, false);
}
static bool IsVar(DomNode returnType) static bool IsVar(DomNode returnType)
{ {
return returnType is IdentifierExpression && ((IdentifierExpression)returnType).Identifier == "var"; return returnType is IdentifierExpression && ((IdentifierExpression)returnType).Identifier == "var";
@ -1055,12 +1060,26 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#region Type References #region Type References
public override ResolveResult VisitPrimitiveType(PrimitiveType primitiveType, object data) public override ResolveResult VisitPrimitiveType(PrimitiveType primitiveType, object data)
{ {
return null; ScanChildren(primitiveType);
return new TypeResolveResult(MakeTypeReference(primitiveType).Resolve(resolver.Context));
}
public override ResolveResult VisitSimpleType(SimpleType simpleType, object data)
{
ScanChildren(simpleType);
return new TypeResolveResult(MakeTypeReference(simpleType).Resolve(resolver.Context));
}
public override ResolveResult VisitMemberType(MemberType memberType, object data)
{
ScanChildren(memberType);
return new TypeResolveResult(MakeTypeReference(memberType).Resolve(resolver.Context));
} }
public override ResolveResult VisitComposedType(ComposedType composedType, object data) public override ResolveResult VisitComposedType(ComposedType composedType, object data)
{ {
return null; ScanChildren(composedType);
return new TypeResolveResult(MakeTypeReference(composedType).Resolve(resolver.Context));
} }
#endregion #endregion

Loading…
Cancel
Save