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 @@ -50,7 +50,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList | ConversionFlags.UseFullyQualifiedMemberNames;
else
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);
}

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

@ -275,7 +275,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -275,7 +275,7 @@ namespace ICSharpCode.SharpDevelop.Project
/// <remarks>
/// This property must not return null.
/// 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.
/// 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 @@ -21,9 +21,9 @@ namespace ICSharpCode.SharpDevelop
public ConversionFlags ConversionFlags { get; set; }
#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();
switch (e.EntityType) {
@ -33,7 +33,7 @@ namespace ICSharpCode.SharpDevelop @@ -33,7 +33,7 @@ namespace ICSharpCode.SharpDevelop
ConvertTypeDeclaration((ITypeDefinition)e, ctx, writer);
break;
case EntityType.Field:
ConvertField((IField)e, ctx, writer);
break;
case EntityType.Property:
@ -64,6 +64,20 @@ namespace ICSharpCode.SharpDevelop @@ -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)
{
TypeSystemAstBuilder astBuilder = new TypeSystemAstBuilder(ctx);
@ -88,7 +102,7 @@ namespace ICSharpCode.SharpDevelop @@ -88,7 +102,7 @@ namespace ICSharpCode.SharpDevelop
default:
throw new Exception("Invalid value for ClassType");
}
writer.Write(" ");
writer.Write(' ');
}
WriteTypeDeclarationName(typeDef, ctx, writer);
}
@ -109,6 +123,15 @@ namespace ICSharpCode.SharpDevelop @@ -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)
{
node.AcceptVisitor(CreatePrinter(writer), null);
@ -124,15 +147,15 @@ namespace ICSharpCode.SharpDevelop @@ -124,15 +147,15 @@ namespace ICSharpCode.SharpDevelop
foreach (var m in CSharpModifierToken.AllModifiers) {
if ((modifiers & m) == m) {
writer.Write(CSharpModifierToken.GetModifierName(m));
writer.Write(" ");
writer.Write(' ');
}
}
}
#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);
AstNode astNode = astBuilder.ConvertVariable(v);
CSharpFormattingOptions formatting = new CSharpFormattingOptions();
@ -154,6 +177,16 @@ namespace ICSharpCode.SharpDevelop @@ -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)
{
return "[" + attribute + "]";

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

@ -69,9 +69,10 @@ namespace ICSharpCode.SharpDevelop @@ -69,9 +69,10 @@ namespace ICSharpCode.SharpDevelop
set;
}
string ConvertEntity(IEntity e);
string ConvertEntity(IEntity e, ITypeResolveContext context);
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 WrapComment(string comment);

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

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

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

@ -65,7 +65,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -65,7 +65,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring
protected ContextActionViewModel MakeGoToClassAction(ITypeDefinition @class, ObservableCollection<ContextActionViewModel> childActions)
{
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,
Comment = string.Format("(in {0})", @class.Namespace),
ChildActions = childActions

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

@ -3,8 +3,10 @@ @@ -3,8 +3,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.Core;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using ICSharpCode.SharpDevelop.Parser;
using NUnit.Framework;
@ -14,21 +16,27 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -14,21 +16,27 @@ namespace ICSharpCode.SharpDevelop.Tests
public class CSharpAmbienceTests
{
IProjectContent mscorlib;
IProjectContent myLib;
CompositeTypeResolveContext compositeContext;
CSharpAmbience ambience;
[SetUp]
public void Setup()
public CSharpAmbienceTests()
{
ambience = new CSharpAmbience();
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]
public void GenericType()
{
var typeDef = mscorlib.GetTypeDefinition(typeof(Dictionary<,>));
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);
}
@ -38,7 +46,7 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -38,7 +46,7 @@ namespace ICSharpCode.SharpDevelop.Tests
{
var typeDef = mscorlib.GetTypeDefinition(typeof(Dictionary<,>));
ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList;
string result = ambience.ConvertEntity(typeDef);
string result = ambience.ConvertEntity(typeDef, mscorlib);
Assert.AreEqual("Dictionary<TKey, TValue>", result);
}
@ -48,7 +56,7 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -48,7 +56,7 @@ namespace ICSharpCode.SharpDevelop.Tests
{
var typeDef = mscorlib.GetTypeDefinition(typeof(Object));
ambience.ConversionFlags = ConversionFlags.UseFullyQualifiedMemberNames | ConversionFlags.ShowTypeParameterList;
string result = ambience.ConvertEntity(typeDef);
string result = ambience.ConvertEntity(typeDef, mscorlib);
Assert.AreEqual("System.Object", result);
}
@ -58,7 +66,7 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -58,7 +66,7 @@ namespace ICSharpCode.SharpDevelop.Tests
{
var typeDef = mscorlib.GetTypeDefinition(typeof(Object));
ambience.ConversionFlags = ConversionFlags.All & ~(ConversionFlags.UseFullyQualifiedMemberNames);
string result = ambience.ConvertEntity(typeDef);
string result = ambience.ConvertEntity(typeDef, mscorlib);
Assert.AreEqual("public class Object", result);
}
@ -68,7 +76,7 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -68,7 +76,7 @@ namespace ICSharpCode.SharpDevelop.Tests
{
var typeDef = mscorlib.GetTypeDefinition(typeof(Object));
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);
}
@ -78,7 +86,7 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -78,7 +86,7 @@ namespace ICSharpCode.SharpDevelop.Tests
{
var typeDef = mscorlib.GetTypeDefinition(typeof(List<>));
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);
}
@ -88,7 +96,7 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -88,7 +96,7 @@ namespace ICSharpCode.SharpDevelop.Tests
{
var typeDef = mscorlib.GetTypeDefinition(typeof(Object));
ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList;
string result = ambience.ConvertEntity(typeDef);
string result = ambience.ConvertEntity(typeDef, mscorlib);
Assert.AreEqual("Object", result);
}
@ -98,7 +106,7 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -98,7 +106,7 @@ namespace ICSharpCode.SharpDevelop.Tests
{
var typeDef = mscorlib.GetTypeDefinition(typeof(List<>.Enumerator));
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);
}
@ -108,9 +116,55 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -108,9 +116,55 @@ namespace ICSharpCode.SharpDevelop.Tests
{
var typeDef = mscorlib.GetTypeDefinition(typeof(List<>.Enumerator));
ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList;
string result = ambience.ConvertEntity(typeDef);
string result = ambience.ConvertEntity(typeDef, mscorlib);
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