Browse Source

Simplify ImplementInterfaceAction by using the TypeSystemAstBuilder.

newNRvisualizers
Daniel Grunwald 13 years ago
parent
commit
56114fe865
  1. 195
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ImplementInterfaceAction.cs
  2. 23
      ICSharpCode.NRefactory.CSharp/Refactoring/RefactoringContext.cs
  3. 68
      ICSharpCode.NRefactory.CSharp/Refactoring/TypeSystemAstBuilder.cs

195
ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ImplementInterfaceAction.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
//
//
// ImplementInterfaceAction.cs
//
// Author:
@ -68,7 +68,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -68,7 +68,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
foreach (var member in toImplement) {
if (!nodes.ContainsKey(member.Item1.DeclaringType))
nodes [member.Item1.DeclaringType] = new List<AstNode>();
nodes [member.Item1.DeclaringType].Add(GenerateMemberImplementation(context, member));
nodes [member.Item1.DeclaringType].Add(GenerateMemberImplementation(context, member.Item1, member.Item2));
}
foreach (var kv in nodes) {
@ -89,188 +89,21 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -89,188 +89,21 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
}
}
static AstNode GenerateMemberImplementation(RefactoringContext context, Tuple<IMember, bool> member)
{
switch (member.Item1.EntityType) {
case EntityType.Property:
return GenerateProperty(context, (IProperty)member.Item1, member.Item2);
case EntityType.Indexer:
return GenerateIndexer(context, (IProperty)member.Item1, member.Item2);
case EntityType.Event:
return GenerateEvent(context, (IEvent)member.Item1, member.Item2);
case EntityType.Method:
return GenerateMethod(context, (IMethod)member.Item1, member.Item2);
default:
throw new ArgumentOutOfRangeException();
}
}
static AstNode GenerateEvent(RefactoringContext context, IEvent evt, bool explicitImplementation)
static EntityDeclaration GenerateMemberImplementation(RefactoringContext context, IMember member, bool explicitImplementation)
{
if (!explicitImplementation) {
return new EventDeclaration() {
Modifiers = Modifiers.Public,
Name = evt.Name,
ReturnType = context.CreateShortType (evt.ReturnType)
};
}
return new CustomEventDeclaration() {
Name = evt.Name,
ReturnType = context.CreateShortType (evt.ReturnType),
PrivateImplementationType = context.CreateShortType(evt.DeclaringType),
AddAccessor = new Accessor {
Body = new BlockStatement() {
new ThrowStatement(new ObjectCreateExpression(context.CreateShortType("System", "NotImplementedException")))
}
},
RemoveAccessor = new Accessor {
Body = new BlockStatement() {
new ThrowStatement(new ObjectCreateExpression(context.CreateShortType("System", "NotImplementedException")))
}
}
};
}
static AstNode GenerateProperty(RefactoringContext context, IProperty property, bool explicitImplementation)
{
var result = new PropertyDeclaration() {
Name = property.Name,
ReturnType = context.CreateShortType (property.ReturnType)
};
if (!explicitImplementation) {
result.Modifiers = Modifiers.Public;
} else {
result.PrivateImplementationType = context.CreateShortType(property.DeclaringType);
}
if (property.CanGet) {
if (property.DeclaringType.Kind != TypeKind.Interface) {
result.Getter = new Accessor() {
Body = new BlockStatement () {
new ThrowStatement(new ObjectCreateExpression(context.CreateShortType("System", "NotImplementedException")))
}
};
} else {
result.Getter = new Accessor();
}
}
if (property.CanSet) {
if (property.DeclaringType.Kind != TypeKind.Interface) {
result.Setter = new Accessor() {
Body = new BlockStatement () {
new ThrowStatement(new ObjectCreateExpression(context.CreateShortType("System", "NotImplementedException")))
}
};
} else {
result.Setter = new Accessor();
}
}
return result;
}
static AstNode GenerateIndexer(RefactoringContext context, IProperty indexer, bool explicitImplementation)
{
var result = new IndexerDeclaration() {
ReturnType = context.CreateShortType (indexer.ReturnType)
};
if (!explicitImplementation) {
result.Modifiers = Modifiers.Public;
var builder = context.CreateTypeSytemAstBuilder();
builder.GenerateBody = true;
builder.ShowConstantValues = !explicitImplementation;
builder.ShowTypeParameterConstraints = !explicitImplementation;
builder.UseCustomEvents = explicitImplementation;
var decl = builder.ConvertEntity(member);
if (explicitImplementation) {
decl.Modifiers = Modifiers.None;
decl.AddChild(builder.ConvertType(member.DeclaringType), EntityDeclaration.PrivateImplementationTypeRole);
} else {
result.PrivateImplementationType = context.CreateShortType(indexer.DeclaringType);
decl.Modifiers = Modifiers.Public;
}
foreach (var p in indexer.Parameters) {
ParameterModifier modifier;
if (p.IsOut) {
modifier = ParameterModifier.Out;
} else if (p.IsRef) {
modifier = ParameterModifier.Ref;
} else if (p.IsParams) {
modifier = ParameterModifier.Params;
} else {
modifier = ParameterModifier.None;
}
result.Parameters.Add(new ParameterDeclaration(context.CreateShortType(p.Type), p.Name, modifier));
}
if (indexer.CanGet) {
result.Getter = new Accessor() {
Body = new BlockStatement () {
new ThrowStatement(new ObjectCreateExpression(context.CreateShortType("System", "NotImplementedException")))
}
};
}
if (indexer.CanSet) {
result.Setter = new Accessor() {
Body = new BlockStatement () {
new ThrowStatement(new ObjectCreateExpression(context.CreateShortType("System", "NotImplementedException")))
}
};
}
return result;
}
static AstNode GenerateMethod(RefactoringContext context, IMethod method, bool explicitImplementation)
{
var result = new MethodDeclaration() {
Name = method.Name,
ReturnType = context.CreateShortType (method.ReturnType),
Body = new BlockStatement() {
new ThrowStatement(new ObjectCreateExpression(context.CreateShortType("System", "NotImplementedException")))
}
};
if (!explicitImplementation) {
result.Modifiers = Modifiers.Public;
} else {
result.PrivateImplementationType = context.CreateShortType(method.DeclaringType);
}
foreach (var typeParam in method.TypeParameters) {
result.TypeParameters.Add(new TypeParameterDeclaration(typeParam.Name));
var constraint = new Constraint() {
TypeParameter = new SimpleType(typeParam.Name)
};
if (typeParam.HasDefaultConstructorConstraint) {
constraint.BaseTypes.Add(new PrimitiveType("new"));
} else if (typeParam.HasReferenceTypeConstraint) {
constraint.BaseTypes.Add(new PrimitiveType("class"));
} else if (typeParam.HasValueTypeConstraint) {
constraint.BaseTypes.Add(new PrimitiveType("struct"));
}
foreach (var type in typeParam.DirectBaseTypes) {
if (type.FullName == "System.Object")
continue;
if (type.FullName == "System.ValueType")
continue;
constraint.BaseTypes.Add(context.CreateShortType(type));
}
if (constraint.BaseTypes.Count == 0)
continue;
result.Constraints.Add(constraint);
}
foreach (var p in method.Parameters) {
ParameterModifier modifier;
if (p.IsOut) {
modifier = ParameterModifier.Out;
} else if (p.IsRef) {
modifier = ParameterModifier.Ref;
} else if (p.IsParams) {
modifier = ParameterModifier.Params;
} else {
modifier = ParameterModifier.None;
}
result.Parameters.Add(new ParameterDeclaration(context.CreateShortType(p.Type), p.Name, modifier));
}
return result;
return decl;
}
public static List<Tuple<IMember, bool>> CollectMembersToImplement(ITypeDefinition implementingType, IType interfaceType, bool explicitly)

23
ICSharpCode.NRefactory.CSharp/Refactoring/RefactoringContext.cs

@ -44,24 +44,23 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -44,24 +44,23 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
}
public abstract TextLocation Location { get; }
public virtual AstType CreateShortType (IType fullType)
public TypeSystemAstBuilder CreateTypeSytemAstBuilder()
{
var csResolver = Resolver.GetResolverStateBefore(GetNode());
var builder = new TypeSystemAstBuilder(csResolver);
return new TypeSystemAstBuilder(csResolver);
}
public virtual AstType CreateShortType (IType fullType)
{
var builder = CreateTypeSytemAstBuilder();
return builder.ConvertType(fullType);
}
public AstType CreateShortType(string ns, string name, int typeParameterCount = 0)
public virtual AstType CreateShortType(string ns, string name, int typeParameterCount = 0)
{
foreach (var asm in Compilation.Assemblies) {
var def = asm.GetTypeDefinition(ns, name, typeParameterCount);
if (def != null) {
return CreateShortType(def);
}
}
return new MemberType(new SimpleType(ns), name);
var builder = CreateTypeSytemAstBuilder();
return builder.ConvertType(ns, name, typeParameterCount);
}
public virtual IEnumerable<AstNode> GetSelectedNodes()

68
ICSharpCode.NRefactory.CSharp/Refactoring/TypeSystemAstBuilder.cs

@ -111,6 +111,18 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -111,6 +111,18 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
/// The default value is <c>false</c>.
/// </summary>
public bool AlwaysUseShortTypeNames { get; set; }
/// <summary>
/// Controls whether to generate a body that throws a <c>System.NotImplementedException</c>.
/// The default value is <c>false</c>.
/// </summary>
public bool GenerateBody { get; set; }
/// <summary>
/// Controls whether to generate custom events.
/// The default value is <c>false</c>.
/// </summary>
public bool UseCustomEvents { get; set; }
#endregion
#region Convert Type
@ -124,6 +136,19 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -124,6 +136,19 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
return astType;
}
public AstType ConvertType(string ns, string name, int typeParameterCount = 0)
{
if (resolver != null) {
foreach (var asm in resolver.Compilation.Assemblies) {
var def = asm.GetTypeDefinition(ns, name, typeParameterCount);
if (def != null) {
return ConvertType(def);
}
}
}
return new MemberType(new SimpleType(ns), name);
}
AstType ConvertTypeHelper(IType type)
{
TypeWithElementType typeWithElementType = type as TypeWithElementType;
@ -557,12 +582,24 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -557,12 +582,24 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
return decl;
}
BlockStatement GenerateBodyBlock()
{
if (GenerateBody) {
return new BlockStatement {
new ThrowStatement(new ObjectCreateExpression(ConvertType("System", "NotImplementedException")))
};
} else {
return BlockStatement.Null;
}
}
Accessor ConvertAccessor(IMethod accessor)
{
if (accessor == null)
return Accessor.Null;
Accessor decl = new Accessor();
decl.Modifiers = ModifierFromAccessibility(accessor.Accessibility);
decl.Body = GenerateBodyBlock();
return decl;
}
@ -590,13 +627,23 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -590,13 +627,23 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
return decl;
}
EventDeclaration ConvertEvent(IEvent ev)
EntityDeclaration ConvertEvent(IEvent ev)
{
EventDeclaration decl = new EventDeclaration();
decl.Modifiers = GetMemberModifiers(ev);
decl.ReturnType = ConvertType(ev.ReturnType);
decl.Variables.Add(new VariableInitializer(ev.Name));
return decl;
if (this.UseCustomEvents) {
CustomEventDeclaration decl = new CustomEventDeclaration();
decl.Modifiers = GetMemberModifiers(ev);
decl.ReturnType = ConvertType(ev.ReturnType);
decl.Name = ev.Name;
decl.AddAccessor = ConvertAccessor(ev.AddAccessor);
decl.RemoveAccessor = ConvertAccessor(ev.RemoveAccessor);
return decl;
} else {
EventDeclaration decl = new EventDeclaration();
decl.Modifiers = GetMemberModifiers(ev);
decl.ReturnType = ConvertType(ev.ReturnType);
decl.Variables.Add(new VariableInitializer(ev.Name));
return decl;
}
}
MethodDeclaration ConvertMethod(IMethod method)
@ -625,6 +672,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -625,6 +672,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
decl.Constraints.Add(constraint);
}
}
decl.Body = GenerateBodyBlock();
return decl;
}
@ -641,6 +689,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -641,6 +689,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
foreach (IParameter p in op.Parameters) {
decl.Parameters.Add(ConvertParameter(p));
}
decl.Body = GenerateBodyBlock();
return decl;
}
@ -652,6 +701,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -652,6 +701,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
foreach (IParameter p in ctor.Parameters) {
decl.Parameters.Add(ConvertParameter(p));
}
decl.Body = GenerateBodyBlock();
return decl;
}
@ -659,6 +709,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -659,6 +709,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
DestructorDeclaration decl = new DestructorDeclaration();
decl.Name = dtor.DeclaringTypeDefinition.Name;
decl.Body = GenerateBodyBlock();
return decl;
}
#endregion
@ -687,12 +738,13 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -687,12 +738,13 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
Modifiers GetMemberModifiers(IMember member)
{
Modifiers m = ModifierFromAccessibility(member.Accessibility);
bool isInterfaceMember = member.DeclaringType.Kind == TypeKind.Interface;
Modifiers m = isInterfaceMember ? Modifiers.None : ModifierFromAccessibility(member.Accessibility);
if (this.ShowModifiers) {
if (member.IsStatic) {
m |= Modifiers.Static;
} else {
if (member.IsAbstract)
if (member.IsAbstract && !isInterfaceMember)
m |= Modifiers.Abstract;
if (member.IsOverride)
m |= Modifiers.Override;

Loading…
Cancel
Save