Browse Source

Introduce a named unknown type (this allows TypeSystemAstBuilder to work better when there are resolve errors).

newNRvisualizers
Daniel Grunwald 14 years ago
parent
commit
f11eed9d15
  1. 8
      ICSharpCode.NRefactory.CSharp/Resolver/CSharpResolver.cs
  2. 2
      ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs
  3. 38
      ICSharpCode.NRefactory.Tests/Documentation/IDStringTests.cs
  4. 1
      ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj
  5. 17
      ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractResolvedEntity.cs
  6. 8
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs
  7. 3
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedTypeDefinition.cs
  8. 2
      ICSharpCode.NRefactory/TypeSystem/Implementation/GetClassTypeReference.cs
  9. 2
      ICSharpCode.NRefactory/TypeSystem/Implementation/KnownTypeCache.cs
  10. 2
      ICSharpCode.NRefactory/TypeSystem/Implementation/NestedTypeReference.cs
  11. 105
      ICSharpCode.NRefactory/TypeSystem/Implementation/UnknownType.cs

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

@ -1297,7 +1297,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1297,7 +1297,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
INamespace childNamespace = n.GetChildNamespace(identifier);
if (childNamespace != null) {
if (u.HasAlias(identifier))
return new AmbiguousTypeResolveResult(SpecialType.UnknownType);
return new AmbiguousTypeResolveResult(new UnknownType(null, identifier));
return new NamespaceResolveResult(childNamespace);
}
}
@ -1644,7 +1644,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1644,7 +1644,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} else {
// argument might be a lambda or delegate type, so we have to try to guess the delegate type
IType type = arguments[i].Type;
if (SpecialType.NullType.Equals(type) || SpecialType.UnknownType.Equals(type)) {
if (type.Kind == TypeKind.Null || type.Kind == TypeKind.Unknown) {
list.Add(new DefaultParameter(compilation.FindType(KnownTypeCode.Object), argumentNames[i]));
} else {
list.Add(new DefaultParameter(type, argumentNames[i]));
@ -1672,7 +1672,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1672,7 +1672,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (vrr != null)
return MakeParameterName(vrr.Variable.Name);
if (rr.Type != SpecialType.UnknownType && !string.IsNullOrEmpty(rr.Type.Name)) {
if (rr.Type.Kind != TypeKind.Unknown && !string.IsNullOrEmpty(rr.Type.Name)) {
return MakeParameterName(rr.Type.Name);
} else {
return "parameter";
@ -1903,7 +1903,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1903,7 +1903,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
bool HasType(ResolveResult r)
{
return !(SpecialType.UnknownType.Equals(r.Type) || SpecialType.NullType.Equals(r.Type));
return r.Type.Kind != TypeKind.Unknown && r.Type.Kind != TypeKind.Null;
}
#endregion

2
ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs

@ -892,7 +892,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -892,7 +892,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
{
KnownTypeCode typeCode = GetTypeCodeForPrimitiveType(keyword);
if (typeCode == KnownTypeCode.None)
return SpecialType.UnknownType;
return new UnknownType(null, keyword);
else
return KnownTypeReference.Get(typeCode);
}

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

@ -30,32 +30,36 @@ namespace ICSharpCode.NRefactory.Documentation @@ -30,32 +30,36 @@ namespace ICSharpCode.NRefactory.Documentation
[TestFixture]
public class IDStringTests
{
/*
class IDStringTestProjectContent : SimpleProjectContent, IDocumentationProvider
class IDStringTestProjectContent : DefaultUnresolvedAssembly, IDocumentationProvider
{
public IDStringTestProjectContent() : base("Test") {}
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);
return IDStringProvider.GetIDString(entity);
}
}
IDStringTestProjectContent pc;
ICompilation compilation;
void Init(string program)
{
pc = new IDStringTestProjectContent();
var cu = new CSharpParser().Parse(new StringReader(program));
var parsedFile = new TypeSystemConvertVisitor(pc, "program.cs").Convert(cu);
pc.UpdateProjectContent(null, parsedFile);
var cu = new CSharpParser().Parse(new StringReader(program), "program.cs");
foreach (var type in cu.ToTypeSystem().TopLevelTypeDefinitions) {
pc.AddTypeDefinition(type);
}
compilation = new SimpleCompilation(pc, CecilLoaderTests.Mscorlib);
}
ITypeDefinition GetTypeDefinition(string nameSpace, string name, int typeParameterCount = 0)
{
return pc.GetTypeDefinition(nameSpace, name, typeParameterCount, StringComparer.Ordinal);
return compilation.MainAssembly.GetTypeDefinition(nameSpace, name, typeParameterCount);
}
[Test]
@ -156,7 +160,7 @@ namespace Acme @@ -156,7 +160,7 @@ namespace Acme
}";
Init(program);
ITypeDefinition widget = GetTypeDefinition("Acme", "Widget");
Assert.AreEqual("M:Acme.Widget.Finalize", widget.Methods.Single().Documentation);
Assert.AreEqual("M:Acme.Widget.Finalize", widget.Methods.Single(m => m.EntityType == EntityType.Destructor).Documentation);
}
[Test]
@ -196,7 +200,7 @@ namespace Acme @@ -196,7 +200,7 @@ namespace Acme
}";
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.NestedClass.M(System.Int32)", widget.NestedTypes.Single().Methods.Single(m => m.EntityType == EntityType.Method).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);
@ -212,7 +216,7 @@ namespace Acme @@ -212,7 +216,7 @@ namespace Acme
widget.Methods.Single(m => m.Name == "M6").Documentation);
Assert.AreEqual("M:Acme.MyList`1.Test(`0)",
GetTypeDefinition("Acme", "MyList", 1).Methods.Single().Documentation);
GetTypeDefinition("Acme", "MyList", 1).Methods.Single(m => m.Name == "Test").Documentation);
Assert.AreEqual("M:Acme.UseList.Process(Acme.MyList{Color})",
GetTypeDefinition("Acme", "UseList").Methods.Single(m => m.Name == "Process").Documentation);
@ -226,7 +230,7 @@ namespace Acme @@ -226,7 +230,7 @@ namespace Acme
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);
Assert.AreEqual("M:A`1.B`1.M(A{`1}.B{`0})", b.Methods.Single(m => m.EntityType == EntityType.Method).Documentation);
}
[Test]
@ -282,7 +286,7 @@ namespace Acme @@ -282,7 +286,7 @@ namespace Acme
}";
Init(program);
ITypeDefinition widget = GetTypeDefinition("Acme", "Widget");
Assert.AreEqual("M:Acme.Widget.op_UnaryPlus(Acme.Widget)", widget.Methods.Single().Documentation);
Assert.AreEqual("M:Acme.Widget.op_UnaryPlus(Acme.Widget)", widget.Methods.Single(m => m.EntityType == EntityType.Operator).Documentation);
}
[Test]
@ -298,7 +302,7 @@ namespace Acme @@ -298,7 +302,7 @@ namespace Acme
}";
Init(program);
ITypeDefinition widget = GetTypeDefinition("Acme", "Widget");
Assert.AreEqual("M:Acme.Widget.op_Addition(Acme.Widget,Acme.Widget)", widget.Methods.Single().Documentation);
Assert.AreEqual("M:Acme.Widget.op_Addition(Acme.Widget,Acme.Widget)", widget.Methods.Single(m => m.EntityType == EntityType.Operator).Documentation);
}
[Test]
@ -315,14 +319,14 @@ namespace Acme @@ -315,14 +319,14 @@ namespace Acme
}";
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);
Assert.AreEqual("M:Acme.Widget.op_Explicit(Acme.Widget)~System.Int32", widget.Methods.First(m => m.EntityType == EntityType.Operator).Documentation);
Assert.AreEqual("M:Acme.Widget.op_Implicit(Acme.Widget)~System.Int64", widget.Methods.Last(m => m.EntityType == EntityType.Operator).Documentation);
}
[Test]
public void CorlibIDStrings()
{
var list = CecilLoaderTests.Mscorlib.GetTypeDefinition(typeof(List<>));
var list = new SimpleCompilation(CecilLoaderTests.Mscorlib).FindType(typeof(List<>)).GetDefinition();
Assert.AreEqual("T:System.Collections.Generic.List`1",
IDStringProvider.GetIDString(list));
Assert.AreEqual("M:System.Collections.Generic.List`1.Add(`0)",
@ -331,6 +335,6 @@ namespace Acme @@ -331,6 +335,6 @@ namespace Acme
IDStringProvider.GetIDString(list.Methods.Single(m => m.Name == "AddRange")));
Assert.AreEqual("M:System.Collections.Generic.List`1.ConvertAll``1(System.Converter{`0,``0})",
IDStringProvider.GetIDString(list.Methods.Single(m => m.Name == "ConvertAll")));
}*/
}
}
}

1
ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj

@ -168,6 +168,7 @@ @@ -168,6 +168,7 @@
<Compile Include="TypeSystem\Implementation\TypeParameterReference.cs" />
<Compile Include="TypeSystem\Implementation\TypeParameterSubstitution.cs" />
<Compile Include="TypeSystem\Implementation\TypeWithElementType.cs" />
<Compile Include="TypeSystem\Implementation\UnknownType.cs" />
<Compile Include="TypeSystem\Implementation\VoidTypeDefinition.cs" />
<Compile Include="TypeSystem\INamedElement.cs" />
<Compile Include="TypeSystem\INamespace.cs" />

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

@ -67,7 +67,22 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -67,7 +67,22 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public IList<IAttribute> Attributes { get; private set; }
public virtual string Documentation {
get { return string.Empty; }
get {
IDocumentationProvider provider = FindDocumentation(parentContext);
if (provider != null)
return provider.GetDocumentation(this);
else
return null;
}
}
internal static IDocumentationProvider FindDocumentation(ITypeResolveContext context)
{
IAssembly asm = context.CurrentAssembly;
if (asm != null)
return asm.UnresolvedAssembly as IDocumentationProvider;
else
return null;
}
public bool IsStatic { get { return unresolved.IsStatic; } }

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

@ -368,9 +368,13 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -368,9 +368,13 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
get { return parentContext.CurrentAssembly; }
}
public string Documentation {
public virtual string Documentation {
get {
throw new NotImplementedException();
IDocumentationProvider provider = AbstractResolvedEntity.FindDocumentation(parentContext);
if (provider != null)
return provider.GetDocumentation(this);
else
return null;
}
}

3
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedTypeDefinition.cs

@ -158,7 +158,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -158,7 +158,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
throw new ArgumentNullException("context");
if (context.CurrentAssembly == null)
throw new ArgumentException("An ITypeDefinition cannot be resolved in a context without a current assembly.");
return context.CurrentAssembly.GetTypeDefinition(this) ?? (IType)SpecialType.UnknownType;
return context.CurrentAssembly.GetTypeDefinition(this)
?? (IType)new UnknownType(this.Namespace, this.Name, this.TypeParameters.Count);
}
public virtual ITypeResolveContext CreateResolveContext(ITypeResolveContext parentContext)

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

@ -64,7 +64,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -64,7 +64,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
if (asm != null) {
type = asm.GetTypeDefinition(nameSpace, name, typeParameterCount);
}
return type ?? SpecialType.UnknownType;
return type ?? new UnknownType(nameSpace, name, typeParameterCount);
}
public override string ToString()

2
ICSharpCode.NRefactory/TypeSystem/Implementation/KnownTypeCache.cs

@ -59,7 +59,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -59,7 +59,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
if (typeDef != null)
return typeDef;
else
return SpecialType.UnknownType;
return new UnknownType(typeRef.Namespace, typeRef.Name, typeRef.TypeParameterCount);
}
}
}

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

@ -73,7 +73,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -73,7 +73,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
return type;
}
}
return SpecialType.UnknownType;
return new UnknownType(null, name, additionalTypeParameterCount);
}
public override string ToString()

105
ICSharpCode.NRefactory/TypeSystem/Implementation/UnknownType.cs

@ -0,0 +1,105 @@ @@ -0,0 +1,105 @@
// 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;
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{
/// <summary>
/// An unknown type where (part) of the name is known.
/// </summary>
[Serializable]
public class UnknownType : AbstractType, ITypeReference
{
readonly string namespaceName;
readonly string name;
readonly int typeParameterCount;
/// <summary>
/// Creates a new unknown type.
/// </summary>
/// <param name="namespaceName">Namespace name, if known. Can be null if unknown.</param>
/// <param name="name">Name of the type, must not be null.</param>
/// <param name="typeParameterCount">Type parameter count, zero if unknown.</param>
public UnknownType(string namespaceName, string name, int typeParameterCount = 0)
{
if (name == null)
throw new ArgumentNullException("name");
this.namespaceName = namespaceName;
this.name = name;
this.typeParameterCount = typeParameterCount;
}
public override TypeKind Kind {
get { return TypeKind.Unknown; }
}
public override ITypeReference ToTypeReference()
{
return this;
}
IType ITypeReference.Resolve(ITypeResolveContext context)
{
if (context == null)
throw new ArgumentNullException("context");
return this;
}
public override string Name {
get { return name; }
}
public override string Namespace {
get { return namespaceName ?? string.Empty; }
}
public override string ReflectionName {
get { return "?"; }
}
public override bool? IsReferenceType {
get { return null; }
}
public override int GetHashCode()
{
int hashCode = 0;
unchecked {
if (namespaceName != null)
hashCode += 1000000007 * namespaceName.GetHashCode();
hashCode += 1000000009 * name.GetHashCode();
hashCode += 1000000021 * typeParameterCount.GetHashCode();
}
return hashCode;
}
public override bool Equals(IType other)
{
UnknownType o = other as UnknownType;
if (o == null)
return false;
return this.namespaceName == o.namespaceName && this.name == o.name && this.typeParameterCount == o.typeParameterCount;
}
public override string ToString()
{
return "[UnknownType " + this.FullName + "]";
}
}
}
Loading…
Cancel
Save