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

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

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

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

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

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

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

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

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

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

@ -3,8 +3,8 @@ @@ -3,8 +3,8 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using ICSharpCode.NRefactory.CSharp.Resolver;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
@ -74,23 +74,18 @@ namespace ICSharpCode.NRefactory.CSharp @@ -74,23 +74,18 @@ namespace ICSharpCode.NRefactory.CSharp
public override IEntity VisitUsingDeclaration(UsingDeclaration usingDeclaration, object data)
{
ITypeOrNamespaceReference r = null;
/*foreach (Identifier identifier in usingDeclaration.NameIdentifier.NameParts) {
if (r == null) {
// 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);
ITypeOrNamespaceReference u = ConvertType(usingDeclaration.Import, true) as ITypeOrNamespaceReference;
if (u != null)
usingScope.Usings.Add(u);
return null;
}
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
@ -275,7 +270,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -275,7 +270,7 @@ namespace ICSharpCode.NRefactory.CSharp
field.ReturnType = currentTypeDefinition;
field.Accessibility = Accessibility.Public;
field.IsStatic = true;
if (enumMemberDeclaration.Initializer != null) {
if (!enumMemberDeclaration.Initializer.IsNull) {
field.ConstantValue = ConvertConstantValue(currentTypeDefinition, enumMemberDeclaration.Initializer);
} else {
throw new NotImplementedException();
@ -304,7 +299,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -304,7 +299,7 @@ namespace ICSharpCode.NRefactory.CSharp
m.IsExtensionMethod = methodDeclaration.IsExtensionMethod;
ConvertParameters(m.Parameters, methodDeclaration.Parameters);
if (methodDeclaration.PrivateImplementationType != null) {
if (!methodDeclaration.PrivateImplementationType.IsNull) {
m.Accessibility = Accessibility.None;
m.InterfaceImplementations.Add(ConvertInterfaceImplementation(methodDeclaration.PrivateImplementationType, m.Name));
}
@ -349,7 +344,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -349,7 +344,7 @@ namespace ICSharpCode.NRefactory.CSharp
DefaultMethod ctor = new DefaultMethod(currentTypeDefinition, isStatic ? ".cctor" : ".ctor");
ctor.EntityType = EntityType.Constructor;
ctor.Region = MakeRegion(constructorDeclaration);
if (constructorDeclaration.Initializer != null) {
if (!constructorDeclaration.Initializer.IsNull) {
ctor.BodyRegion = MakeRegion(constructorDeclaration.Initializer.StartLocation, constructorDeclaration.EndLocation);
} else {
ctor.BodyRegion = MakeRegion(constructorDeclaration.Body);
@ -403,7 +398,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -403,7 +398,7 @@ namespace ICSharpCode.NRefactory.CSharp
ApplyModifiers(p, propertyDeclaration.Modifiers);
p.ReturnType = ConvertType(propertyDeclaration.ReturnType);
ConvertAttributes(p.Attributes, propertyDeclaration.Attributes);
if (propertyDeclaration.PrivateImplementationType != null) {
if (!propertyDeclaration.PrivateImplementationType.IsNull) {
p.Accessibility = Accessibility.None;
p.InterfaceImplementations.Add(ConvertInterfaceImplementation(propertyDeclaration.PrivateImplementationType, p.Name));
}
@ -441,7 +436,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -441,7 +436,7 @@ namespace ICSharpCode.NRefactory.CSharp
e.ReturnType = ConvertType(eventDeclaration.ReturnType);
ConvertAttributes(e.Attributes, eventDeclaration.Attributes);
if (eventDeclaration.PrivateImplementationType != null) {
if (!eventDeclaration.PrivateImplementationType.IsNull) {
e.Accessibility = Accessibility.None;
e.InterfaceImplementations.Add(ConvertInterfaceImplementation(eventDeclaration.PrivateImplementationType, e.Name));
}
@ -505,21 +500,96 @@ namespace ICSharpCode.NRefactory.CSharp @@ -505,21 +500,96 @@ namespace ICSharpCode.NRefactory.CSharp
#region Types
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;
if (f != null) {
switch (f.Keyword) {
return ConvertType(node, currentTypeDefinition, currentMethod, usingScope, isInUsingDeclaration);
}
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":
return TypeCode.String.ToTypeReference();
case "int":
return TypeCode.Int32.ToTypeReference();
case "uint":
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":
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;
}
#endregion

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

@ -945,10 +945,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -945,10 +945,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (initializerExpression != null && IsVar(type)) {
return new VarTypeReference(this, resolver.Clone(), initializerExpression, isForEach);
} 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)
{
return returnType is IdentifierExpression && ((IdentifierExpression)returnType).Identifier == "var";
@ -1055,12 +1060,26 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1055,12 +1060,26 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#region Type References
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)
{
return null;
ScanChildren(composedType);
return new TypeResolveResult(MakeTypeReference(composedType).Resolve(resolver.Context));
}
#endregion

Loading…
Cancel
Save