Browse Source

extend IAmbience to use ITypeResolveContext; add support for fields and add tests

newNRvisualizers
Siegfried Pammer 15 years ago
parent
commit
b8510c56d9
  1. 2
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/QuickClassBrowser.cs
  2. 2
      src/Main/Base/Project/Src/Project/IProject.cs
  3. 47
      src/Main/Base/Project/Src/Services/AmbienceService/CSharpAmbience.cs
  4. 5
      src/Main/Base/Project/Src/Services/AmbienceService/IAmbience.cs
  5. 6
      src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs
  6. 2
      src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsHelper.cs
  7. 76
      src/Main/Base/Test/CSharpAmbienceTests.cs

2
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/QuickClassBrowser.cs

@ -50,7 +50,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList | ConversionFlags.UseFullyQualifiedMemberNames; ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList | ConversionFlags.UseFullyQualifiedMemberNames;
else else
ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList | ConversionFlags.ShowParameterList | ConversionFlags.ShowParameterNames; ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList | ConversionFlags.ShowParameterList | ConversionFlags.ShowParameterNames;
text = ambience.ConvertEntity(entity); text = ambience.ConvertEntity(entity, ParserService.GetProject(entity.ProjectContent).TypeResolveContext);
image = ClassBrowserIconService.GetIcon(entity); image = ClassBrowserIconService.GetIcon(entity);
} }

2
src/Main/Base/Project/Src/Project/IProject.cs

@ -275,7 +275,7 @@ namespace ICSharpCode.SharpDevelop.Project
/// <remarks> /// <remarks>
/// This property must not return null. /// This property must not return null.
/// If no resolve context is available for this project, it should return a dummy context /// If no resolve context is available for this project, it should return a dummy context
/// (e.g. <see cref="ICSharpCode.NRefactory.CSharp.Analysis.MinimalResolveContext/">). /// (e.g. <see cref="ICSharpCode.NRefactory.CSharp.Analysis.MinimalResolveContext"/>).
/// ///
/// This member is thread-safe. /// This member is thread-safe.
/// The resulting type resolve context is thread-safe, but repeated locking on every access might be inefficient. /// The resulting type resolve context is thread-safe, but repeated locking on every access might be inefficient.

47
src/Main/Base/Project/Src/Services/AmbienceService/CSharpAmbience.cs

@ -21,9 +21,9 @@ namespace ICSharpCode.SharpDevelop
public ConversionFlags ConversionFlags { get; set; } public ConversionFlags ConversionFlags { get; set; }
#region ConvertEntity #region ConvertEntity
public string ConvertEntity(IEntity e) public string ConvertEntity(IEntity e, ITypeResolveContext context)
{ {
using (var ctx = ParserService.CurrentTypeResolveContext.Synchronize()) { using (var ctx = context.Synchronize()) {
StringWriter writer = new StringWriter(); StringWriter writer = new StringWriter();
switch (e.EntityType) { switch (e.EntityType) {
@ -33,7 +33,7 @@ namespace ICSharpCode.SharpDevelop
ConvertTypeDeclaration((ITypeDefinition)e, ctx, writer); ConvertTypeDeclaration((ITypeDefinition)e, ctx, writer);
break; break;
case EntityType.Field: case EntityType.Field:
ConvertField((IField)e, ctx, writer);
break; break;
case EntityType.Property: case EntityType.Property:
@ -64,6 +64,20 @@ namespace ICSharpCode.SharpDevelop
} }
} }
void ConvertField(IField field, ISynchronizedTypeResolveContext ctx, StringWriter writer)
{
TypeSystemAstBuilder astBuilder = new TypeSystemAstBuilder(ctx);
astBuilder.ShowModifiers = (ConversionFlags & ConversionFlags.ShowModifiers) == ConversionFlags.ShowModifiers;
astBuilder.ShowAccessibility = (ConversionFlags & ConversionFlags.ShowAccessibility) == ConversionFlags.ShowAccessibility;
FieldDeclaration fieldDecl = (FieldDeclaration)astBuilder.ConvertEntity(field);
PrintModifiers(fieldDecl.Modifiers, writer);
if ((ConversionFlags & ConversionFlags.ShowReturnType) == ConversionFlags.ShowReturnType) {
writer.Write(ConvertType(field.Type, ctx));
writer.Write(' ');
}
WriteFieldDeclarationName(field, ctx, writer);
}
void ConvertTypeDeclaration(ITypeDefinition typeDef, ITypeResolveContext ctx, StringWriter writer) void ConvertTypeDeclaration(ITypeDefinition typeDef, ITypeResolveContext ctx, StringWriter writer)
{ {
TypeSystemAstBuilder astBuilder = new TypeSystemAstBuilder(ctx); TypeSystemAstBuilder astBuilder = new TypeSystemAstBuilder(ctx);
@ -88,7 +102,7 @@ namespace ICSharpCode.SharpDevelop
default: default:
throw new Exception("Invalid value for ClassType"); throw new Exception("Invalid value for ClassType");
} }
writer.Write(" "); writer.Write(' ');
} }
WriteTypeDeclarationName(typeDef, ctx, writer); WriteTypeDeclarationName(typeDef, ctx, writer);
} }
@ -109,6 +123,15 @@ namespace ICSharpCode.SharpDevelop
} }
} }
void WriteFieldDeclarationName(IField field, ITypeResolveContext ctx, StringWriter writer)
{
if ((ConversionFlags & ConversionFlags.UseFullyQualifiedMemberNames) == ConversionFlags.UseFullyQualifiedMemberNames) {
writer.Write(ConvertType(field.DeclaringType));
writer.Write('.');
}
writer.Write(field.Name);
}
void PrintNode(AstNode node, StringWriter writer) void PrintNode(AstNode node, StringWriter writer)
{ {
node.AcceptVisitor(CreatePrinter(writer), null); node.AcceptVisitor(CreatePrinter(writer), null);
@ -124,15 +147,15 @@ namespace ICSharpCode.SharpDevelop
foreach (var m in CSharpModifierToken.AllModifiers) { foreach (var m in CSharpModifierToken.AllModifiers) {
if ((modifiers & m) == m) { if ((modifiers & m) == m) {
writer.Write(CSharpModifierToken.GetModifierName(m)); writer.Write(CSharpModifierToken.GetModifierName(m));
writer.Write(" "); writer.Write(' ');
} }
} }
} }
#endregion #endregion
public string ConvertVariable(IVariable v) public string ConvertVariable(IVariable v, ITypeResolveContext context)
{ {
using (var ctx = ParserService.CurrentTypeResolveContext.Synchronize()) { using (var ctx = context.Synchronize()) {
TypeSystemAstBuilder astBuilder = new TypeSystemAstBuilder(ctx); TypeSystemAstBuilder astBuilder = new TypeSystemAstBuilder(ctx);
AstNode astNode = astBuilder.ConvertVariable(v); AstNode astNode = astBuilder.ConvertVariable(v);
CSharpFormattingOptions formatting = new CSharpFormattingOptions(); CSharpFormattingOptions formatting = new CSharpFormattingOptions();
@ -154,6 +177,16 @@ namespace ICSharpCode.SharpDevelop
} }
} }
public string ConvertType(ITypeReference type, ITypeResolveContext context)
{
TypeSystemAstBuilder astBuilder = new TypeSystemAstBuilder(context);
AstType astType = astBuilder.ConvertTypeReference(type);
CSharpFormattingOptions formatting = new CSharpFormattingOptions();
StringWriter writer = new StringWriter();
astType.AcceptVisitor(new OutputVisitor(writer, formatting), null);
return writer.ToString();
}
public string WrapAttribute(string attribute) public string WrapAttribute(string attribute)
{ {
return "[" + attribute + "]"; return "[" + attribute + "]";

5
src/Main/Base/Project/Src/Services/AmbienceService/IAmbience.cs

@ -69,9 +69,10 @@ namespace ICSharpCode.SharpDevelop
set; set;
} }
string ConvertEntity(IEntity e); string ConvertEntity(IEntity e, ITypeResolveContext context);
string ConvertType(IType type); string ConvertType(IType type);
string ConvertVariable(IVariable variable); string ConvertType(ITypeReference type, ITypeResolveContext context);
string ConvertVariable(IVariable variable, ITypeResolveContext context);
string WrapAttribute(string attribute); string WrapAttribute(string attribute);
string WrapComment(string comment); string WrapComment(string comment);

6
src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs

@ -341,9 +341,11 @@ namespace ICSharpCode.SharpDevelop.Debugging
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();
if (rr.IsParameter) if (rr.IsParameter)
b.Append("parameter "); b.Append("parameter ");
else if (rr.Variable.IsConst)
b.Append("constant ");
else else
b.Append("local variable "); b.Append("local variable ");
b.Append(ambience.ConvertVariable(rr.Variable)); b.Append(ambience.ConvertVariable(rr.Variable, ParserService.CurrentTypeResolveContext));
if (!rr.IsCompileTimeConstant && currentDebugger != null) { if (!rr.IsCompileTimeConstant && currentDebugger != null) {
string currentValue = currentDebugger.GetValueAsString(e, rr); string currentValue = currentDebugger.GetValueAsString(e, rr);
if (currentValue != null) { if (currentValue != null) {
@ -378,7 +380,7 @@ namespace ICSharpCode.SharpDevelop.Debugging
bool tryDisplayValue = false; bool tryDisplayValue = false;
debuggerCanShowValue = false; debuggerCanShowValue = false;
StringBuilder text = new StringBuilder(); StringBuilder text = new StringBuilder();
text.Append(ambience.ConvertEntity(member)); text.Append(ambience.ConvertEntity(member, ParserService.CurrentTypeResolveContext));
tryDisplayValue = ((member is IField && !((IField)member).IsConst) || member is IProperty); tryDisplayValue = ((member is IField && !((IField)member).IsConst) || member is IProperty);
if (tryDisplayValue && currentDebugger != null) { if (tryDisplayValue && currentDebugger != null) {

2
src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsHelper.cs

@ -65,7 +65,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring
protected ContextActionViewModel MakeGoToClassAction(ITypeDefinition @class, ObservableCollection<ContextActionViewModel> childActions) protected ContextActionViewModel MakeGoToClassAction(ITypeDefinition @class, ObservableCollection<ContextActionViewModel> childActions)
{ {
return new ContextActionViewModel { return new ContextActionViewModel {
Action = new GoToClassAction(@class, this.LabelAmbience.ConvertEntity(@class)), Action = new GoToClassAction(@class, this.LabelAmbience.ConvertEntity(@class, ParserService.CurrentTypeResolveContext)),
Image = ClassBrowserIconService.GetIcon(@class).ImageSource, Image = ClassBrowserIconService.GetIcon(@class).ImageSource,
Comment = string.Format("(in {0})", @class.Namespace), Comment = string.Format("(in {0})", @class.Namespace),
ChildActions = childActions ChildActions = childActions

76
src/Main/Base/Test/CSharpAmbienceTests.cs

@ -3,8 +3,10 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using ICSharpCode.Core; using ICSharpCode.Core;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using ICSharpCode.SharpDevelop.Parser; using ICSharpCode.SharpDevelop.Parser;
using NUnit.Framework; using NUnit.Framework;
@ -14,21 +16,27 @@ namespace ICSharpCode.SharpDevelop.Tests
public class CSharpAmbienceTests public class CSharpAmbienceTests
{ {
IProjectContent mscorlib; IProjectContent mscorlib;
IProjectContent myLib;
CompositeTypeResolveContext compositeContext;
CSharpAmbience ambience; CSharpAmbience ambience;
[SetUp] public CSharpAmbienceTests()
public void Setup()
{ {
ambience = new CSharpAmbience(); ambience = new CSharpAmbience();
mscorlib = AssemblyParserService.GetAssembly(FileName.Create(typeof(object).Assembly.Location)); mscorlib = AssemblyParserService.GetAssembly(FileName.Create(typeof(object).Assembly.Location));
var loader = new CecilLoader();
loader.IncludeInternalMembers = true;
myLib = loader.LoadAssemblyFile(typeof(CSharpAmbienceTests).Assembly.Location);
compositeContext = new CompositeTypeResolveContext(new[] { mscorlib, myLib });
} }
#region ITypeDefinition tests
[Test] [Test]
public void GenericType() public void GenericType()
{ {
var typeDef = mscorlib.GetTypeDefinition(typeof(Dictionary<,>)); var typeDef = mscorlib.GetTypeDefinition(typeof(Dictionary<,>));
ambience.ConversionFlags = ConversionFlags.UseFullyQualifiedMemberNames | ConversionFlags.ShowTypeParameterList; ambience.ConversionFlags = ConversionFlags.UseFullyQualifiedMemberNames | ConversionFlags.ShowTypeParameterList;
string result = ambience.ConvertEntity(typeDef); string result = ambience.ConvertEntity(typeDef, mscorlib);
Assert.AreEqual("System.Collections.Generic.Dictionary<TKey, TValue>", result); Assert.AreEqual("System.Collections.Generic.Dictionary<TKey, TValue>", result);
} }
@ -38,7 +46,7 @@ namespace ICSharpCode.SharpDevelop.Tests
{ {
var typeDef = mscorlib.GetTypeDefinition(typeof(Dictionary<,>)); var typeDef = mscorlib.GetTypeDefinition(typeof(Dictionary<,>));
ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList; ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList;
string result = ambience.ConvertEntity(typeDef); string result = ambience.ConvertEntity(typeDef, mscorlib);
Assert.AreEqual("Dictionary<TKey, TValue>", result); Assert.AreEqual("Dictionary<TKey, TValue>", result);
} }
@ -48,7 +56,7 @@ namespace ICSharpCode.SharpDevelop.Tests
{ {
var typeDef = mscorlib.GetTypeDefinition(typeof(Object)); var typeDef = mscorlib.GetTypeDefinition(typeof(Object));
ambience.ConversionFlags = ConversionFlags.UseFullyQualifiedMemberNames | ConversionFlags.ShowTypeParameterList; ambience.ConversionFlags = ConversionFlags.UseFullyQualifiedMemberNames | ConversionFlags.ShowTypeParameterList;
string result = ambience.ConvertEntity(typeDef); string result = ambience.ConvertEntity(typeDef, mscorlib);
Assert.AreEqual("System.Object", result); Assert.AreEqual("System.Object", result);
} }
@ -58,7 +66,7 @@ namespace ICSharpCode.SharpDevelop.Tests
{ {
var typeDef = mscorlib.GetTypeDefinition(typeof(Object)); var typeDef = mscorlib.GetTypeDefinition(typeof(Object));
ambience.ConversionFlags = ConversionFlags.All & ~(ConversionFlags.UseFullyQualifiedMemberNames); ambience.ConversionFlags = ConversionFlags.All & ~(ConversionFlags.UseFullyQualifiedMemberNames);
string result = ambience.ConvertEntity(typeDef); string result = ambience.ConvertEntity(typeDef, mscorlib);
Assert.AreEqual("public class Object", result); Assert.AreEqual("public class Object", result);
} }
@ -68,7 +76,7 @@ namespace ICSharpCode.SharpDevelop.Tests
{ {
var typeDef = mscorlib.GetTypeDefinition(typeof(Object)); var typeDef = mscorlib.GetTypeDefinition(typeof(Object));
ambience.ConversionFlags = ConversionFlags.All & ~(ConversionFlags.UseFullyQualifiedMemberNames | ConversionFlags.ShowModifiers | ConversionFlags.ShowAccessibility); ambience.ConversionFlags = ConversionFlags.All & ~(ConversionFlags.UseFullyQualifiedMemberNames | ConversionFlags.ShowModifiers | ConversionFlags.ShowAccessibility);
string result = ambience.ConvertEntity(typeDef); string result = ambience.ConvertEntity(typeDef, mscorlib);
Assert.AreEqual("class Object", result); Assert.AreEqual("class Object", result);
} }
@ -78,7 +86,7 @@ namespace ICSharpCode.SharpDevelop.Tests
{ {
var typeDef = mscorlib.GetTypeDefinition(typeof(List<>)); var typeDef = mscorlib.GetTypeDefinition(typeof(List<>));
ambience.ConversionFlags = ConversionFlags.All; ambience.ConversionFlags = ConversionFlags.All;
string result = ambience.ConvertEntity(typeDef); string result = ambience.ConvertEntity(typeDef, mscorlib);
Assert.AreEqual("public class System.Collections.Generic.List<T>", result); Assert.AreEqual("public class System.Collections.Generic.List<T>", result);
} }
@ -88,7 +96,7 @@ namespace ICSharpCode.SharpDevelop.Tests
{ {
var typeDef = mscorlib.GetTypeDefinition(typeof(Object)); var typeDef = mscorlib.GetTypeDefinition(typeof(Object));
ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList; ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList;
string result = ambience.ConvertEntity(typeDef); string result = ambience.ConvertEntity(typeDef, mscorlib);
Assert.AreEqual("Object", result); Assert.AreEqual("Object", result);
} }
@ -98,7 +106,7 @@ namespace ICSharpCode.SharpDevelop.Tests
{ {
var typeDef = mscorlib.GetTypeDefinition(typeof(List<>.Enumerator)); var typeDef = mscorlib.GetTypeDefinition(typeof(List<>.Enumerator));
ambience.ConversionFlags = ConversionFlags.UseFullyQualifiedMemberNames | ConversionFlags.ShowTypeParameterList; ambience.ConversionFlags = ConversionFlags.UseFullyQualifiedMemberNames | ConversionFlags.ShowTypeParameterList;
string result = ambience.ConvertEntity(typeDef); string result = ambience.ConvertEntity(typeDef, mscorlib);
Assert.AreEqual("System.Collections.Generic.List<T>.Enumerator", result); Assert.AreEqual("System.Collections.Generic.List<T>.Enumerator", result);
} }
@ -108,9 +116,55 @@ namespace ICSharpCode.SharpDevelop.Tests
{ {
var typeDef = mscorlib.GetTypeDefinition(typeof(List<>.Enumerator)); var typeDef = mscorlib.GetTypeDefinition(typeof(List<>.Enumerator));
ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList; ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList;
string result = ambience.ConvertEntity(typeDef); string result = ambience.ConvertEntity(typeDef, mscorlib);
Assert.AreEqual("List<T>.Enumerator", result); Assert.AreEqual("List<T>.Enumerator", result);
} }
#endregion
#region IField tests
[Test]
public void SimpleField()
{
var field = typeof(CSharpAmbienceTests.MyClass).ToTypeReference().Resolve(myLib)
.GetDefinition().Fields.Single(f => f.Name == "test");
ambience.ConversionFlags = ConversionFlags.All;
string result = ambience.ConvertEntity(field, compositeContext);
Assert.AreEqual("private int ICSharpCode.SharpDevelop.Tests.CSharpAmbienceTests.MyClass.test", result);
}
[Test]
public void SimpleConstField()
{
var field = typeof(CSharpAmbienceTests.MyClass).ToTypeReference().Resolve(myLib)
.GetDefinition().Fields.Single(f => f.Name == "TEST");
ambience.ConversionFlags = ConversionFlags.All;
string result = ambience.ConvertEntity(field, compositeContext);
Assert.AreEqual("private const int ICSharpCode.SharpDevelop.Tests.CSharpAmbienceTests.MyClass.TEST", result);
}
[Test]
public void SimpleFieldWithoutModifiers()
{
var field = typeof(CSharpAmbienceTests.MyClass).ToTypeReference().Resolve(myLib)
.GetDefinition().Fields.Single(f => f.Name == "test");
ambience.ConversionFlags = ConversionFlags.All & ~(ConversionFlags.UseFullyQualifiedMemberNames | ConversionFlags.ShowModifiers | ConversionFlags.ShowAccessibility);
string result = ambience.ConvertEntity(field, compositeContext);
Assert.AreEqual("int test", result);
}
#endregion
#region Test types
#pragma warning disable 169
class MyClass
{
const int TEST = 0;
int test;
}
#endregion
} }
} }

Loading…
Cancel
Save