Browse Source

Add ID string provider + a few resolver bugfixes

newNRvisualizers
Daniel Grunwald 15 years ago
parent
commit
a9a6e1680d
  1. 23
      ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/AttributeSectionTests.cs
  2. 26
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/ArrayCreationTests.cs
  3. 2
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/ObjectCreationTests.cs
  4. 306
      ICSharpCode.NRefactory.Tests/Documentation/IDStringTests.cs
  5. 2
      ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj
  6. 14
      ICSharpCode.NRefactory/CSharp/Resolver/MemberLookup.cs
  7. 68
      ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs
  8. 260
      ICSharpCode.NRefactory/Documentation/IDStringProvider.cs
  9. 11
      ICSharpCode.NRefactory/Documentation/XmlDocumentationProvider.cs
  10. 1
      ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj
  11. 6
      ICSharpCode.NRefactory/TypeSystem/ArrayType.cs
  12. 4
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeDefinition.cs
  13. 4
      ICSharpCode.NRefactory/TypeSystem/Implementation/GetClassTypeReference.cs
  14. 12
      ICSharpCode.NRefactory/TypeSystem/Implementation/NestedTypeReference.cs
  15. 6
      ICSharpCode.NRefactory/TypeSystem/Implementation/SimpleProjectContent.cs
  16. 4
      ICSharpCode.NRefactory/TypeSystem/ParameterizedType.cs

23
ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/AttributeSectionTests.cs

@ -138,5 +138,28 @@ public class Form1 {
} }
// TODO: Tests for other contexts where attributes can appear // TODO: Tests for other contexts where attributes can appear
[Test, Ignore("Parser doesn't support named arguments in attributes")]
public void AttributeWithNamedArguments()
{
ParseUtilCSharp.AssertTypeMember(
@"[A(0, a:1, b=2)] class Test {}",
new TypeDeclaration {
Name = "Test",
Attributes = {
new AttributeSection {
Attributes = {
new Attribute {
Type = new SimpleType("A"),
Arguments = {
new PrimitiveExpression(0),
new NamedArgumentExpression { Identifier = "a", Expression = new PrimitiveExpression(1) },
new AssignmentExpression(new IdentifierExpression("b"), new PrimitiveExpression(2))
}
}
}
}
}});
}
} }
} }

26
ICSharpCode.NRefactory.Tests/CSharp/Resolver/ArrayCreationTests.cs

@ -59,5 +59,31 @@ class A {
var result = Resolve(program); var result = Resolve(program);
Assert.AreEqual("System.Int64[]", result.Type.ReflectionName); Assert.AreEqual("System.Int64[]", result.Type.ReflectionName);
} }
[Test]
public void InferredType2D()
{
string program = @"using System.Collections.Generic;
class A {
static void Main() {
var a = $new [,] { { 1 }, { 1L } }$;
}
}
";
var result = Resolve(program);
Assert.AreEqual("System.Int64[,]", result.Type.ReflectionName);
}
[Test]
public void ArrayInitializerExpression()
{
string program = @"using System.Collections.Generic;
class A {
int[] a = ${ 1 }$;
}
";
var result = Resolve(program);
Assert.AreEqual("System.Int32[]", result.Type.ReflectionName);
}
} }
} }

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

@ -100,7 +100,7 @@ class A {
Assert.AreEqual(0, m.Parameters.Count); Assert.AreEqual(0, m.Parameters.Count);
} }
[Test, Ignore("Not implemented")] [Test, Ignore("Parser returns incorrect positions")]
public void ChainedConstructorCall() public void ChainedConstructorCall()
{ {
string program = @"using System; string program = @"using System;

306
ICSharpCode.NRefactory.Tests/Documentation/IDStringTests.cs

@ -0,0 +1,306 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT license (for details please see \doc\license.txt)
using System;
using System.IO;
using System.Linq;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using NUnit.Framework;
namespace ICSharpCode.NRefactory.Documentation
{
[TestFixture]
public class IDStringTests
{
class IDStringTestProjectContent : SimpleProjectContent, IDocumentationProvider
{
public string GetDocumentation(IEntity entity)
{
// Note: there's no mscorlib in the context.
// These tests only use primitive types from mscorlib, so the full name is known
// without resolving them.
return IDStringProvider.GetIDString(entity, this);
}
}
IDStringTestProjectContent pc;
void Init(string program)
{
pc = new IDStringTestProjectContent();
CSharpParser parser = new CSharpParser();
TypeSystemConvertVisitor cv = new TypeSystemConvertVisitor(pc, "program.cs");
parser.Parse(new StringReader(program)).AcceptVisitor(cv, null);
pc.UpdateProjectContent(null, cv.ParsedFile);
}
ITypeDefinition GetTypeDefinition(string nameSpace, string name, int typeParameterCount = 0)
{
return pc.GetTypeDefinition(nameSpace, name, typeParameterCount, StringComparer.Ordinal);
}
[Test]
public void TypeDefinitions()
{
string program = @"
enum Color { Red, Blue, Green }
namespace Acme
{
interface IProcess {}
struct ValueType {}
class Widget: IProcess
{
public class NestedClass {}
public interface IMenuItem {}
public delegate void Del(int i);
public enum Direction { North, South, East, West }
}
class MyList<T>
{
class Helper<U,V> {}
}
}";
Init(program);
Assert.AreEqual("T:Color", GetTypeDefinition(string.Empty, "Color").Documentation);
Assert.AreEqual("T:Acme.IProcess", GetTypeDefinition("Acme", "IProcess").Documentation);
Assert.AreEqual("T:Acme.ValueType", GetTypeDefinition("Acme", "ValueType").Documentation);
ITypeDefinition widget = GetTypeDefinition("Acme", "Widget");
Assert.AreEqual("T:Acme.Widget", widget.Documentation);
Assert.AreEqual("T:Acme.Widget.NestedClass", widget.NestedTypes.Single(t => t.Name == "NestedClass").Documentation);
Assert.AreEqual("T:Acme.Widget.IMenuItem", widget.NestedTypes.Single(t => t.Name == "IMenuItem").Documentation);
Assert.AreEqual("T:Acme.Widget.Del", widget.NestedTypes.Single(t => t.Name == "Del").Documentation);
Assert.AreEqual("T:Acme.Widget.Direction", widget.NestedTypes.Single(t => t.Name == "Direction").Documentation);
Assert.AreEqual("T:Acme.MyList`1", GetTypeDefinition("Acme", "MyList", 1).Documentation);
Assert.AreEqual("T:Acme.MyList`1.Helper`2", GetTypeDefinition("Acme", "MyList", 1).NestedTypes.Single().Documentation);
}
[Test]
public void Fields()
{
string program = @"
namespace Acme
{
class Widget : IProcess
{
public class NestedClass
{
private int value;
}
private string message;
private const double PI = 3.14159;
private unsafe float **ppValues;
}
}";
Init(program);
ITypeDefinition widget = GetTypeDefinition("Acme", "Widget");
Assert.AreEqual("F:Acme.Widget.NestedClass.value", widget.NestedTypes.Single().Fields.Single().Documentation);
Assert.AreEqual("F:Acme.Widget.message", widget.Fields.Single(f => f.Name == "message").Documentation);
Assert.AreEqual("F:Acme.Widget.PI", widget.Fields.Single(f => f.Name == "PI").Documentation);
Assert.AreEqual("F:Acme.Widget.ppValues", widget.Fields.Single(f => f.Name == "ppValues").Documentation);
}
[Test]
public void Constructors()
{
string program = @"
namespace Acme
{
class Widget: IProcess
{
static Widget() {}
public Widget() {}
public Widget(string s) {}
}
}";
Init(program);
ITypeDefinition widget = GetTypeDefinition("Acme", "Widget");
Assert.AreEqual("M:Acme.Widget.#cctor", widget.Methods.Single(m => m.IsStatic).Documentation);
Assert.AreEqual("M:Acme.Widget.#ctor", widget.Methods.Single(m => !m.IsStatic && m.Parameters.Count == 0).Documentation);
Assert.AreEqual("M:Acme.Widget.#ctor(System.String)", widget.Methods.Single(m => m.Parameters.Count == 1).Documentation);
}
[Test]
public void Destructor()
{
string program = @"
namespace Acme
{
class Widget: IProcess
{
~Widget() { }
}
}";
Init(program);
ITypeDefinition widget = GetTypeDefinition("Acme", "Widget");
Assert.AreEqual("M:Acme.Widget.Finalize", widget.Methods.Single().Documentation);
}
[Test]
public void Methods()
{
string program = @"
enum Color {}
namespace Acme
{
struct ValueType { }
class Widget: IProcess
{
public class NestedClass
{
public void M(int i) {}
}
public static void M0() {...}
public void M1(char c, out float f, ref ValueType v) {...}
public void M2(short[] x1, int[,] x2, long[][] x3) {...}
public void M3(long[][] x3, Widget[][,,] x4) {...}
public unsafe void M4(char *pc, Color **pf) {...}
public unsafe void M5(void *pv, double *[][,] pd) {...}
public void M6(int? i, params object[] args) {...}
}
class MyList<T>
{
public void Test(T t) { }
}
class UseList
{
public void Process(MyList<Color> list) { }
public MyList<T> GetValues<T>(T inputValue) { return null; }
}
}";
Init(program);
ITypeDefinition widget = GetTypeDefinition("Acme", "Widget");
Assert.AreEqual("M:Acme.Widget.NestedClass.M(System.Int32)", widget.NestedTypes.Single().Methods.Single().Documentation);
Assert.AreEqual("M:Acme.Widget.M0", widget.Methods.Single(m => m.Name == "M0").Documentation);
Assert.AreEqual("M:Acme.Widget.M1(System.Char,System.Single@,Acme.ValueType@)",
widget.Methods.Single(m => m.Name == "M1").Documentation);
Assert.AreEqual("M:Acme.Widget.M2(System.Int16[],System.Int32[0:,0:],System.Int64[][])",
widget.Methods.Single(m => m.Name == "M2").Documentation);
Assert.AreEqual("M:Acme.Widget.M3(System.Int64[][],Acme.Widget[0:,0:,0:][])",
widget.Methods.Single(m => m.Name == "M3").Documentation);
Assert.AreEqual("M:Acme.Widget.M4(System.Char*,Color**)",
widget.Methods.Single(m => m.Name == "M4").Documentation);
Assert.AreEqual("M:Acme.Widget.M5(System.Void*,System.Double*[0:,0:][])",
widget.Methods.Single(m => m.Name == "M5").Documentation);
Assert.AreEqual("M:Acme.Widget.M6(System.Nullable{System.Int32},System.Object[])",
widget.Methods.Single(m => m.Name == "M6").Documentation);
Assert.AreEqual("M:Acme.MyList`1.Test(`0)",
GetTypeDefinition("Acme", "MyList", 1).Methods.Single().Documentation);
Assert.AreEqual("M:Acme.UseList.Process(Acme.MyList{Color})",
GetTypeDefinition("Acme", "UseList").Methods.Single(m => m.Name == "Process").Documentation);
Assert.AreEqual("M:Acme.UseList.GetValues``1(``0)",
GetTypeDefinition("Acme", "UseList").Methods.Single(m => m.Name == "GetValues").Documentation);
}
[Test]
public void NestedGenerics()
{
Init("class A<X> { class B<Y> { void M(A<Y>.B<X> a) { } } }");
ITypeDefinition b = GetTypeDefinition("", "A", 1).NestedTypes.Single();
Assert.AreEqual("T:A`1.B`1", b.Documentation);
Assert.AreEqual("M:A`1.B`1.M(A{`1}.B{`0})", b.Methods.Single().Documentation);
}
[Test]
public void Properties()
{
string program = @"
namespace Acme
{
class Widget: IProcess
{
public int Width { get {...} set {...} }
public int this[int i] { get {...} set {...} }
public int this[string s, int i] { get {...} set {...} }
}
}";
Init(program);
ITypeDefinition widget = GetTypeDefinition("Acme", "Widget");
Assert.AreEqual("P:Acme.Widget.Width", widget.Properties.Single(p => p.Parameters.Count == 0).Documentation);
Assert.AreEqual("P:Acme.Widget.Item(System.Int32)",
widget.Properties.Single(p => p.Parameters.Count == 1).Documentation);
Assert.AreEqual("P:Acme.Widget.Item(System.String,System.Int32)",
widget.Properties.Single(p => p.Parameters.Count == 2).Documentation);
}
[Test]
public void Event()
{
string program = @"
namespace Acme
{
class Widget: IProcess
{
public event Del AnEvent;
}
}";
Init(program);
ITypeDefinition widget = GetTypeDefinition("Acme", "Widget");
Assert.AreEqual("E:Acme.Widget.AnEvent", widget.Events.Single().Documentation);
}
[Test]
public void UnaryOperator()
{
string program = @"
namespace Acme
{
class Widget: IProcess
{
public static Widget operator+(Widget x) { }
}
}";
Init(program);
ITypeDefinition widget = GetTypeDefinition("Acme", "Widget");
Assert.AreEqual("M:Acme.Widget.op_UnaryPlus(Acme.Widget)", widget.Methods.Single().Documentation);
}
[Test]
public void BinaryOperator()
{
string program = @"
namespace Acme
{
class Widget: IProcess
{
public static Widget operator+(Widget x1, Widget x2) { }
}
}";
Init(program);
ITypeDefinition widget = GetTypeDefinition("Acme", "Widget");
Assert.AreEqual("M:Acme.Widget.op_Addition(Acme.Widget,Acme.Widget)", widget.Methods.Single().Documentation);
}
[Test]
public void ConversionOperator()
{
string program = @"
namespace Acme
{
class Widget: IProcess
{
public static explicit operator int(Widget x) { }
public static implicit operator long(Widget x) { }
}
}";
Init(program);
ITypeDefinition widget = GetTypeDefinition("Acme", "Widget");
Assert.AreEqual("M:Acme.Widget.op_Explicit(Acme.Widget)~System.Int32", widget.Methods.First().Documentation);
Assert.AreEqual("M:Acme.Widget.op_Implicit(Acme.Widget)~System.Int64", widget.Methods.Last().Documentation);
}
}
}

2
ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj

@ -135,6 +135,7 @@
<Compile Include="CSharp\Resolver\ResolverTestBase.cs" /> <Compile Include="CSharp\Resolver\ResolverTestBase.cs" />
<Compile Include="CSharp\Resolver\UnaryOperatorTests.cs" /> <Compile Include="CSharp\Resolver\UnaryOperatorTests.cs" />
<Compile Include="CSharp\Resolver\UnsafeCodeTests.cs" /> <Compile Include="CSharp\Resolver\UnsafeCodeTests.cs" />
<Compile Include="Documentation\IDStringTests.cs" />
<Compile Include="FormattingTests\TestBraceStlye.cs" /> <Compile Include="FormattingTests\TestBraceStlye.cs" />
<Compile Include="FormattingTests\TestFormattingBugs.cs" /> <Compile Include="FormattingTests\TestFormattingBugs.cs" />
<Compile Include="FormattingTests\TestSpacingVisitor.cs" /> <Compile Include="FormattingTests\TestSpacingVisitor.cs" />
@ -168,6 +169,7 @@
<Folder Include="CSharp\Parser\" /> <Folder Include="CSharp\Parser\" />
<Folder Include="CSharp\Parser\" /> <Folder Include="CSharp\Parser\" />
<Folder Include="CSharp\Parser\" /> <Folder Include="CSharp\Parser\" />
<Folder Include="Documentation" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project> </Project>

14
ICSharpCode.NRefactory/CSharp/Resolver/MemberLookup.cs

@ -70,7 +70,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
// check for members of outer classes (private members of outer classes can be accessed) // check for members of outer classes (private members of outer classes can be accessed)
var lookupTypeDefinition = currentTypeDefinition; var lookupTypeDefinition = currentTypeDefinition;
while (lookupTypeDefinition != null) { while (lookupTypeDefinition != null) {
if (entity.DeclaringTypeDefinition.Equals (lookupTypeDefinition)) if (entity.DeclaringTypeDefinition.Equals (lookupTypeDefinition))
return true; return true;
lookupTypeDefinition = lookupTypeDefinition.DeclaringTypeDefinition; lookupTypeDefinition = lookupTypeDefinition.DeclaringTypeDefinition;
} }
@ -144,10 +144,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResolveResult CreateTypeResolveResult(IType returnedType, bool isAmbiguous, IList<IType> typeArguments, bool parameterizeResultType) ResolveResult CreateTypeResolveResult(IType returnedType, bool isAmbiguous, IList<IType> typeArguments, bool parameterizeResultType)
{ {
if (parameterizeResultType && typeArguments.Count > 0) { if (parameterizeResultType && typeArguments.Count > 0) {
// parameterize the type if necessary // Complete the partial parameterization
ITypeDefinition returnedTypeDef = returnedType as ITypeDefinition; ParameterizedType pt = returnedType as ParameterizedType;
if (returnedTypeDef != null) if (pt != null) {
returnedType = new ParameterizedType(returnedTypeDef, typeArguments); IType[] newTypeArguments = new IType[pt.TypeParameterCount];
pt.TypeArguments.CopyTo(newTypeArguments, 0);
typeArguments.CopyTo(newTypeArguments, newTypeArguments.Length - typeArguments.Count);
returnedType = new ParameterizedType(pt.GetDefinition(), newTypeArguments);
}
} }
if (isAmbiguous) if (isAmbiguous)
return new AmbiguousTypeResolveResult(returnedType); return new AmbiguousTypeResolveResult(returnedType);

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

@ -610,35 +610,35 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public override ResolveResult VisitArrayCreateExpression(ArrayCreateExpression arrayCreateExpression, object data) public override ResolveResult VisitArrayCreateExpression(ArrayCreateExpression arrayCreateExpression, object data)
{ {
Scan(arrayCreateExpression.Initializer); ScanChildren(arrayCreateExpression);
if (resolverEnabled) { if (!resolverEnabled) {
IType arrType; return null;
if (arrayCreateExpression.Type.IsNull) { }
var elements = new List<ResolveResult>(); IType arrType;
foreach (var init in arrayCreateExpression.Initializer.Elements) { if (arrayCreateExpression.Type.IsNull) {
var rr = Resolve(init); var elements = new List<ResolveResult>();
if (!rr.IsError) foreach (var init in arrayCreateExpression.Initializer.Elements) {
elements.Add(rr); var rr = Resolve(init);
} if (!rr.IsError)
TypeInference typeInference = new TypeInference(resolver.Context, new Conversions(resolver.Context)); elements.Add(rr);
bool success; }
IType elementType = typeInference.GetBestCommonType(elements, out success); TypeInference typeInference = new TypeInference(resolver.Context, new Conversions(resolver.Context));
arrType = new ArrayType(elementType, 1); bool success;
IType elementType = typeInference.GetBestCommonType(elements, out success);
arrType = new ArrayType(elementType, 1);
} else {
arrType = ResolveType(arrayCreateExpression.Type);
foreach (var spec in arrayCreateExpression.AdditionalArraySpecifiers.Reverse()) {
arrType = new ArrayType(arrType, spec.Dimensions);
}
// HACK: find a better way to represent this in the AST
if (arrayCreateExpression.Arguments.Count == 0) {
arrType = new ArrayType(arrType, 1);
} else { } else {
arrType = ResolveType(arrayCreateExpression.Type); arrType = new ArrayType(arrType, arrayCreateExpression.Arguments.Count);
foreach (var spec in arrayCreateExpression.AdditionalArraySpecifiers.Reverse()) {
arrType = new ArrayType(arrType, spec.Dimensions);
}
// HACK: find a better way to represent this in the AST
if (arrayCreateExpression.Arguments.Count == 0) {
arrType = new ArrayType(arrType, 1);
} else {
arrType = new ArrayType(arrType, arrayCreateExpression.Arguments.Count);
}
} }
return new ResolveResult (arrType);
} }
return null; return new ResolveResult (arrType);
} }
public override ResolveResult VisitAsExpression(AsExpression asExpression, object data) public override ResolveResult VisitAsExpression(AsExpression asExpression, object data)
@ -1450,14 +1450,26 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public override ResolveResult VisitConstructorInitializer(ConstructorInitializer constructorInitializer, object data) public override ResolveResult VisitConstructorInitializer(ConstructorInitializer constructorInitializer, object data)
{ {
ScanChildren(constructorInitializer); if (!resolverEnabled) {
return null; ScanChildren(constructorInitializer);
return null;
}
ResolveResult target;
if (constructorInitializer.ConstructorInitializerType == ConstructorInitializerType.Base) {
target = resolver.ResolveBaseReference();
} else {
target = resolver.ResolveThisReference();
}
string[] argumentNames;
ResolveResult[] arguments = GetArguments(constructorInitializer.Arguments, out argumentNames);
return resolver.ResolveObjectCreation(target.Type, arguments, argumentNames);
} }
public override ResolveResult VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression, object data) public override ResolveResult VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression, object data)
{ {
// TODO: array initializers are valid expressions if the parent node is a variable/field declaration // TODO: array initializers are valid expressions if the parent node is a variable/field declaration
// that explicitly defines an array type // that explicitly defines an array type
ScanChildren(arrayInitializerExpression);
return errorResult; return errorResult;
} }

260
ICSharpCode.NRefactory/Documentation/IDStringProvider.cs

@ -0,0 +1,260 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT license (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Text;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
namespace ICSharpCode.NRefactory.Documentation
{
/// <summary>
/// Provides ID strings for entities. (C# 4.0 spec, §A.3.1)
/// ID strings are used to identify members in XML documentation files.
/// </summary>
public static class IDStringProvider
{
/// <summary>
/// Gets the ID string (C# 4.0 spec, §A.3.1) for the specified entity.
/// </summary>
/// <remarks>
/// The type resolve context is optional and is not needed for entities loaded from assemblies:
/// This method can get the ID string for any type reference produced by the CecilLoader without
/// having to resolve the type reference.
/// </remarks>
public static string GetIDString(IEntity entity, ITypeResolveContext context = null)
{
StringBuilder b = new StringBuilder();
switch (entity.EntityType) {
case EntityType.TypeDefinition:
b.Append("T:");
AppendTypeName(b, (ITypeDefinition)entity);
return b.ToString();
case EntityType.Field:
b.Append("F:");
break;
case EntityType.Property:
case EntityType.Indexer:
b.Append("P:");
break;
case EntityType.Event:
b.Append("E:");
break;
default:
b.Append("M:");
break;
}
IMember member = (IMember)entity;
AppendTypeName(b, member.DeclaringType);
b.Append('.');
b.Append(member.Name.Replace('.', '#'));
IMethod method = member as IMethod;
if (method != null && method.TypeParameters.Count > 0) {
b.Append("``");
b.Append(method.TypeParameters.Count);
}
IParameterizedMember parameterizedMember = member as IParameterizedMember;
if (parameterizedMember != null && parameterizedMember.Parameters.Count > 0) {
b.Append('(');
var parameters = parameterizedMember.Parameters;
for (int i = 0; i < parameters.Count; i++) {
if (i > 0) b.Append(',');
AppendTypeName(b, parameters[i].Type, context);
}
b.Append(')');
}
if (member.EntityType == EntityType.Operator && (member.Name == "op_Implicit" || member.Name == "op_Explicit")) {
b.Append('~');
AppendTypeName(b, member.ReturnType, context);
}
return b.ToString();
}
public static string GetTypeName(IType type)
{
if (type == null)
throw new ArgumentNullException("type");
StringBuilder b = new StringBuilder();
AppendTypeName(b, type);
return b.ToString();
}
static void AppendTypeName(StringBuilder b, IType type)
{
switch (type.Kind) {
case TypeKind.Dynamic:
b.Append("System.Object");
break;
case TypeKind.TypeParameter:
ITypeParameter tp = (ITypeParameter)type;
b.Append('`');
if (tp.OwnerType == EntityType.Method)
b.Append('`');
b.Append(tp.Index);
break;
case TypeKind.Array:
ArrayType array = (ArrayType)type;
AppendTypeName(b, array.ElementType);
b.Append('[');
if (array.Dimensions > 1) {
for (int i = 0; i < array.Dimensions; i++) {
if (i > 0) b.Append(',');
b.Append("0:");
}
}
b.Append(']');
break;
case TypeKind.Pointer:
AppendTypeName(b, ((PointerType)type).ElementType);
b.Append('*');
break;
case TypeKind.ByReference:
AppendTypeName(b, ((ByReferenceType)type).ElementType);
b.Append('@');
break;
default:
IType declType = type.DeclaringType;
if (declType != null) {
AppendTypeName(b, declType);
b.Append('.');
b.Append(type.Name);
AppendTypeParameters(b, type, declType.TypeParameterCount);
} else {
b.Append(type.FullName);
AppendTypeParameters(b, type, 0);
}
break;
}
}
static void AppendTypeParameters(StringBuilder b, IType type, int outerTypeParameterCount)
{
int tpc = type.TypeParameterCount - outerTypeParameterCount;
if (tpc > 0) {
ParameterizedType pt = type as ParameterizedType;
if (pt != null) {
b.Append('{');
var ta = pt.TypeArguments;
for (int i = outerTypeParameterCount; i < ta.Count; i++) {
if (i > outerTypeParameterCount) b.Append(',');
AppendTypeName(b, ta[i]);
}
b.Append('}');
} else {
b.Append('`');
b.Append(tpc);
}
}
}
static void AppendTypeName(StringBuilder b, ITypeReference type, ITypeResolveContext context)
{
IType resolvedType = type as IType;
if (resolvedType != null) {
AppendTypeName(b, resolvedType);
return;
}
GetClassTypeReference gctr = type as GetClassTypeReference;
if (gctr != null) {
if (!string.IsNullOrEmpty(gctr.Namespace)) {
b.Append(gctr.Namespace);
b.Append('.');
}
b.Append(gctr.Name);
if (gctr.TypeParameterCount > 0) {
b.Append('`');
b.Append(gctr.TypeParameterCount);
}
return;
}
NestedTypeReference ntr = type as NestedTypeReference;
if (ntr != null) {
AppendTypeName(b, ntr.DeclaringTypeReference, context);
b.Append('.');
b.Append(ntr.Name);
if (ntr.AdditionalTypeParameterCount > 0) {
b.Append('`');
b.Append(ntr.AdditionalTypeParameterCount);
}
return;
}
ParameterizedTypeReference pt = type as ParameterizedTypeReference;
if (pt != null && IsGetClassTypeReference(pt.GenericType)) {
AppendParameterizedTypeName(b, pt.GenericType, pt.TypeArguments, context);
return;
}
ArrayTypeReference array = type as ArrayTypeReference;
if (array != null) {
AppendTypeName(b, array.ElementType, context);
b.Append('[');
if (array.Dimensions > 1) {
for (int i = 0; i < array.Dimensions; i++) {
if (i > 0) b.Append(',');
b.Append("0:");
}
}
b.Append(']');
return;
}
PointerTypeReference ptr = type as PointerTypeReference;
if (ptr != null) {
AppendTypeName(b, ptr.ElementType, context);
b.Append('*');
return;
}
ByReferenceTypeReference brtr = type as ByReferenceTypeReference;
if (brtr != null) {
AppendTypeName(b, brtr.ElementType, context);
b.Append('@');
return;
}
if (context == null)
b.Append('?');
else
AppendTypeName(b, type.Resolve(context));
}
static bool IsGetClassTypeReference(ITypeReference type)
{
NestedTypeReference ntr;
while ((ntr = type as NestedTypeReference) != null)
type = ntr.DeclaringTypeReference;
return type is GetClassTypeReference;
}
static int AppendParameterizedTypeName(StringBuilder b, ITypeReference type, IList<ITypeReference> typeArguments, ITypeResolveContext context)
{
GetClassTypeReference gctr = type as GetClassTypeReference;
if (gctr != null) {
if (!string.IsNullOrEmpty(gctr.Namespace)) {
b.Append(gctr.Namespace);
b.Append('.');
}
b.Append(gctr.Name);
if (gctr.TypeParameterCount > 0) {
b.Append('{');
for (int i = 0; i < gctr.TypeParameterCount && i < typeArguments.Count; i++) {
if (i > 0) b.Append(',');
AppendTypeName(b, typeArguments[i], context);
}
b.Append('}');
}
return gctr.TypeParameterCount;
} else {
NestedTypeReference ntr = (NestedTypeReference)type;
int outerTpc = AppendParameterizedTypeName(b, ntr.DeclaringTypeReference, typeArguments, context);
b.Append('.');
if (ntr.AdditionalTypeParameterCount > 0) {
b.Append('{');
for (int i = 0; i < ntr.AdditionalTypeParameterCount && i + outerTpc < typeArguments.Count; i++) {
if (i > 0) b.Append(',');
AppendTypeName(b, typeArguments[i + outerTpc], context);
}
b.Append('}');
}
return outerTpc + ntr.AdditionalTypeParameterCount;
}
}
}
}

11
ICSharpCode.NRefactory/Documentation/XmlDocumentationProvider.cs

@ -305,7 +305,7 @@ namespace ICSharpCode.NRefactory.Documentation
/// <inheritdoc/> /// <inheritdoc/>
public string GetDocumentation(IEntity entity) public string GetDocumentation(IEntity entity)
{ {
return GetDocumentation(GetDocumentationKey(entity)); return GetDocumentation(IDStringProvider.GetIDString(entity));
} }
/// <summary> /// <summary>
@ -365,14 +365,5 @@ namespace ICSharpCode.NRefactory.Documentation
} }
} }
#endregion #endregion
#region GetDocumentationKey
public static string GetDocumentationKey(IEntity entity)
{
if (entity == null)
throw new ArgumentNullException("entity");
throw new NotImplementedException();
}
#endregion
} }
} }

1
ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj

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

6
ICSharpCode.NRefactory/TypeSystem/ArrayType.cs

@ -21,9 +21,9 @@ namespace ICSharpCode.NRefactory.TypeSystem
this.dimensions = dimensions; this.dimensions = dimensions;
} }
public override TypeKind Kind { public override TypeKind Kind {
get { return TypeKind.Array; } get { return TypeKind.Array; }
} }
public int Dimensions { public int Dimensions {
get { return dimensions; } get { return dimensions; }

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

@ -391,12 +391,12 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
return new ITypeDefinition[] { this }; return new ITypeDefinition[] { this };
} }
public ITypeDefinition GetDefinition() ITypeDefinition IType.GetDefinition()
{ {
return this; return this;
} }
public IType Resolve(ITypeResolveContext context) IType ITypeReference.Resolve(ITypeResolveContext context)
{ {
if (context == null) if (context == null)
throw new ArgumentNullException("context"); throw new ArgumentNullException("context");

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

@ -42,6 +42,10 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
this.typeParameterCount = typeParameterCount; this.typeParameterCount = typeParameterCount;
} }
public string Namespace { get { return nameSpace; } }
public string Name { get { return name; } }
public int TypeParameterCount { get { return typeParameterCount; } }
/* /*
sealed class CachedResult sealed class CachedResult
{ {

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

@ -35,6 +35,18 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
this.additionalTypeParameterCount = additionalTypeParameterCount; this.additionalTypeParameterCount = additionalTypeParameterCount;
} }
public ITypeReference DeclaringTypeReference {
get { return declaringTypeRef; }
}
public string Name {
get { return name; }
}
public int AdditionalTypeParameterCount {
get { return additionalTypeParameterCount; }
}
public IType Resolve(ITypeResolveContext context) public IType Resolve(ITypeResolveContext context)
{ {
ITypeDefinition declaringType = declaringTypeRef.Resolve(context) as ITypeDefinition; ITypeDefinition declaringType = declaringTypeRef.Resolve(context) as ITypeDefinition;

6
ICSharpCode.NRefactory/TypeSystem/Implementation/SimpleProjectContent.cs

@ -19,12 +19,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
/// Compared with <see cref="TypeStorage"/>, this class adds support for the IProjectContent interface, /// Compared with <see cref="TypeStorage"/>, this class adds support for the IProjectContent interface,
/// for partial classes, and for multi-threading. /// for partial classes, and for multi-threading.
/// </remarks> /// </remarks>
public sealed class SimpleProjectContent : AbstractAnnotatable, IProjectContent public class SimpleProjectContent : AbstractAnnotatable, IProjectContent
{ {
// This class is sealed by design:
// the synchronization story doesn't mix well with someone trying to extend this class.
// If you wanted to derive from this: use delegation, not inheritance.
readonly TypeStorage types = new TypeStorage(); readonly TypeStorage types = new TypeStorage();
readonly ReaderWriterLockSlim readerWriterLock = new ReaderWriterLockSlim(); readonly ReaderWriterLockSlim readerWriterLock = new ReaderWriterLockSlim();
readonly Dictionary<string, IParsedFile> fileDict = new Dictionary<string, IParsedFile>(Platform.FileNameComparer); readonly Dictionary<string, IParsedFile> fileDict = new Dictionary<string, IParsedFile>(Platform.FileNameComparer);

4
ICSharpCode.NRefactory/TypeSystem/ParameterizedType.cs

@ -90,7 +90,9 @@ namespace ICSharpCode.NRefactory.TypeSystem
public IType DeclaringType { public IType DeclaringType {
get { get {
ITypeDefinition declaringTypeDef = genericType.DeclaringTypeDefinition; ITypeDefinition declaringTypeDef = genericType.DeclaringTypeDefinition;
if (declaringTypeDef != null && declaringTypeDef.TypeParameterCount > 0) { if (declaringTypeDef != null && declaringTypeDef.TypeParameterCount > 0
&& declaringTypeDef.TypeParameterCount <= genericType.TypeParameterCount)
{
IType[] newTypeArgs = new IType[declaringTypeDef.TypeParameterCount]; IType[] newTypeArgs = new IType[declaringTypeDef.TypeParameterCount];
Array.Copy(this.typeArguments, 0, newTypeArgs, 0, newTypeArgs.Length); Array.Copy(this.typeArguments, 0, newTypeArgs, 0, newTypeArgs.Length);
return new ParameterizedType(declaringTypeDef, newTypeArgs); return new ParameterizedType(declaringTypeDef, newTypeArgs);

Loading…
Cancel
Save