diff options
author | Lluis Sanchez Gual <lluis@xamarin.com> | 2015-04-20 19:07:51 +0300 |
---|---|---|
committer | Lluis Sanchez Gual <lluis@xamarin.com> | 2015-04-20 19:07:51 +0300 |
commit | 95408b1a41b31b645f3a8c3323ab7d3ca4bff26b (patch) | |
tree | f8f137cddcb9a40499d303be95722fd2c6081bce /main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/ExportCodeGenerator.cs | |
parent | b70e4e04b4e41b8ec28d7e4b220b401ecf467e7a (diff) | |
parent | de043d330a8bf5855d4d983c804cd36727cb2406 (diff) |
Merge remote-tracking branch 'origin/roslyn' into new-project-model
Diffstat (limited to 'main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/ExportCodeGenerator.cs')
-rw-r--r-- | main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/ExportCodeGenerator.cs | 261 |
1 files changed, 95 insertions, 166 deletions
diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/ExportCodeGenerator.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/ExportCodeGenerator.cs index 4eb780329e..cf89feae3b 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/ExportCodeGenerator.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/ExportCodeGenerator.cs @@ -25,20 +25,19 @@ // THE SOFTWARE. using Gtk; using System.Collections.Generic; -using ICSharpCode.NRefactory.CSharp; using MonoDevelop.Core; -using ICSharpCode.NRefactory.TypeSystem; using System.Linq; -using ICSharpCode.NRefactory.CSharp.Refactoring; -using MonoDevelop.CSharp.Refactoring.CodeActions; using MonoDevelop.CodeGeneration; using MonoDevelop.CSharp.Completion; +using Microsoft.CodeAnalysis; +using MonoDevelop.CSharp.Refactoring; +using ICSharpCode.NRefactory6.CSharp; namespace MonoDevelop.CodeGeneration { abstract class BaseExportCodeGenerator : ICodeGenerator { - public abstract bool IsValidMember (IMember member); + public abstract bool IsValidMember (ISymbol member); #region ICodeGenerator implementation @@ -70,106 +69,90 @@ namespace MonoDevelop.CodeGeneration #endregion - public static bool HasProtocolAttribute (IType type, out string name) - { - foreach (var attrs in type.GetDefinition ().GetAttributes ()) { - if (attrs.AttributeType.Name == "ProtocolAttribute" && MonoCSharpCompletionEngine.IsFoundationNamespace (attrs.AttributeType.Namespace)) { - foreach (var na in attrs.NamedArguments) { - if (na.Key.Name != "Name") - continue; - name = na.Value.ConstantValue as string; - if (name != null) - return true; - } - } - } - name = null; - return false; - } - - public static Attribute GenerateExportAttribute (RefactoringContext ctx, IMember member) - { - if (member == null) - return null; - - bool useMonoTouchNamespace = false; - var exportAttribute = member.GetAttribute (new FullTypeName (new TopLevelTypeName ("Foundation", "ExportAttribute"))); - if (exportAttribute == null) { - useMonoTouchNamespace = true; - exportAttribute = member.GetAttribute (new FullTypeName (new TopLevelTypeName ("MonoTouch.Foundation", "ExportAttribute"))); - } - - if (exportAttribute == null || exportAttribute.PositionalArguments.Count == 0) - return null; - var astType = useMonoTouchNamespace - ? CreateMonoTouchExportAttributeAst (ctx) - : CreateUnifiedExportAttributeAst (ctx); - - var attr = new Attribute { - Type = astType, - }; - - attr.Arguments.Add (new PrimitiveExpression (exportAttribute.PositionalArguments [0].ConstantValue)); - return attr; - } - - static AstType CreateUnifiedExportAttributeAst (RefactoringContext ctx) - { - var astType = ctx.CreateShortType ("Foundation", "ExportAttribute"); - if (astType is SimpleType) { - astType = new SimpleType ("Export"); - } else { - astType = new MemberType (new SimpleType ("Foundation"), "Export"); - } - return astType; - } - - static AstType CreateMonoTouchExportAttributeAst (RefactoringContext ctx) - { - var astType = ctx.CreateShortType ("MonoTouch.Foundation", "ExportAttribute"); - if (astType is SimpleType) { - astType = new SimpleType ("Export"); - } else { - astType = new MemberType (new MemberType (new SimpleType ("MonoTouch"), "Foundation"), "Export"); - } - return astType; - } - - static IMember GetProtocolMember (RefactoringContext ctx, IType protocolType, IMember member) - { - foreach (var m in protocolType.GetMembers (m => m.SymbolKind == member.SymbolKind && m.Name == member.Name)) { - if (!SignatureComparer.Ordinal.Equals (m, member)) - return null; - var prop = m as IProperty; - if (prop != null) { - if (prop.CanGet && GenerateExportAttribute (ctx, prop.Getter) != null || - prop.CanSet && GenerateExportAttribute (ctx, prop.Setter) != null) - return m; - } else { - if (GenerateExportAttribute (ctx, m) != null) - return m; - } - } - return null; - } - - static string GetProtocol (IMember member) +// public static Attribute GenerateExportAttribute (RefactoringContext ctx, IMember member) +// { +// if (member == null) +// return null; +// +// bool useMonoTouchNamespace = false; +// var exportAttribute = member.GetAttribute (new FullTypeName (new TopLevelTypeName ("Foundation", "ExportAttribute"))); +// if (exportAttribute == null) { +// useMonoTouchNamespace = true; +// exportAttribute = member.GetAttribute (new FullTypeName (new TopLevelTypeName ("MonoTouch.Foundation", "ExportAttribute"))); +// } +// +// if (exportAttribute == null || exportAttribute.PositionalArguments.Count == 0) +// return null; +// +// var astType = useMonoTouchNamespace +// ? CreateMonoTouchExportAttributeAst (ctx) +// : CreateUnifiedExportAttributeAst (ctx); +// +// var attr = new Attribute { +// Type = astType, +// }; +// +// attr.Arguments.Add (new PrimitiveExpression (exportAttribute.PositionalArguments [0].ConstantValue)); +// return attr; +// } +// +// static AstType CreateUnifiedExportAttributeAst (RefactoringContext ctx) +// { +// var astType = ctx.CreateShortType ("Foundation", "ExportAttribute"); +// if (astType is SimpleType) { +// astType = new SimpleType ("Export"); +// } else { +// astType = new MemberType (new SimpleType ("Foundation"), "Export"); +// } +// return astType; +// } +// +// static AstType CreateMonoTouchExportAttributeAst (RefactoringContext ctx) +// { +// var astType = ctx.CreateShortType ("MonoTouch.Foundation", "ExportAttribute"); +// if (astType is SimpleType) { +// astType = new SimpleType ("Export"); +// } else { +// astType = new MemberType (new MemberType (new SimpleType ("MonoTouch"), "Foundation"), "Export"); +// } +// return astType; +// } +// +// static IMember GetProtocolMember (RefactoringContext ctx, IType protocolType, IMember member) +// { +// foreach (var m in protocolType.GetMembers (m => m.SymbolKind == member.SymbolKind && m.Name == member.Name)) { +// if (!SignatureComparer.Ordinal.Equals (m, member)) +// return null; +// var prop = m as IProperty; +// if (prop != null) { +// if (prop.CanGet && GenerateExportAttribute (ctx, prop.Getter) != null || +// prop.CanSet && GenerateExportAttribute (ctx, prop.Setter) != null) +// return m; +// } else { +// if (GenerateExportAttribute (ctx, m) != null) +// return m; +// } +// } +// return null; +// } +// + static string GetProtocol (ISymbol member) { - var attr = member.Attributes.FirstOrDefault (a => a.AttributeType.Name == "ExportAttribute" && MonoCSharpCompletionEngine.IsFoundationNamespace (a.AttributeType.Namespace)); - if (attr == null || attr.PositionalArguments.Count == 0) + var attr = member.GetAttributes ().FirstOrDefault (a => a.AttributeClass.Name == "ExportAttribute" && ProtocolMemberContextHandler.IsFoundationNamespace (a.AttributeClass.ContainingNamespace)); + if (attr == null || attr.ConstructorArguments.Length == 0) return null; - return attr.PositionalArguments.First ().ConstantValue.ToString (); + return attr.ConstructorArguments.First ().Value.ToString (); } - public static bool IsImplemented (IType type, IMember protocolMember) + public static bool IsImplemented (ITypeSymbol type, ISymbol protocolMember) { - foreach (var m in type.GetMembers (m => m.SymbolKind == protocolMember.SymbolKind && m.Name == protocolMember.Name)) { - var p = m as IProperty; + foreach (var m in type.GetMembers().Where (m => m.Kind == protocolMember.Kind && m.Name == protocolMember.Name)) { + var p = m as IPropertySymbol; if (p != null) { - if (p.CanGet && ((IProperty)protocolMember).CanGet && GetProtocol (p.Getter) == GetProtocol (((IProperty)protocolMember).Getter)) + if (p.GetMethod != null && ((IPropertySymbol)protocolMember).GetMethod != null && GetProtocol (p.GetMethod) == GetProtocol (((IPropertySymbol)protocolMember).GetMethod)) return true; - if (p.CanSet && ((IProperty)protocolMember).CanSet && GetProtocol (p.Setter) == GetProtocol (((IProperty)protocolMember).Setter)) + if (p.SetMethod != null && ((IPropertySymbol)protocolMember).SetMethod != null && GetProtocol (p.SetMethod) == GetProtocol (((IPropertySymbol)protocolMember).SetMethod)) return true; continue; } @@ -194,32 +177,32 @@ namespace MonoDevelop.CodeGeneration var type = Options.EnclosingType; if (type == null || Options.EnclosingMember != null) yield break; - foreach (var t in type.DirectBaseTypes) { + foreach (var t in type.GetBaseTypes ()) { string name; - if (!HasProtocolAttribute (t, out name)) + if (!ProtocolMemberContextHandler.HasProtocolAttribute (t, out name)) continue; - var protocolType = Options.Document.Compilation.FindType (new FullTypeName (new TopLevelTypeName (t.Namespace, name))); + var protocolType = Options.CurrentState.Compilation.GetTypeByMetadataName (t.ContainingNamespace.GetFullName () + "." + name); if (protocolType == null) break; - foreach (var member in protocolType.GetMethods (null, GetMemberOptions.IgnoreInheritedMembers)) { - if (member.ImplementedInterfaceMembers.Any ()) + foreach (var member in protocolType.GetMembers().OfType<IMethodSymbol>()) { + if (member.ExplicitInterfaceImplementations.Length > 0) continue; if (!cg.IsValidMember (member)) continue; if (IsImplemented (type, member)) continue; - if (member.Attributes.Any (a => a.AttributeType.Name == "ExportAttribute" && MonoCSharpCompletionEngine.IsFoundationNamespace (a.AttributeType.Namespace))) + if (member.GetAttributes ().Any (a => a.AttributeClass.Name == "ExportAttribute" && ProtocolMemberContextHandler.IsFoundationNamespace (a.AttributeClass.ContainingNamespace))) yield return member; } - foreach (var member in protocolType.GetProperties (null, GetMemberOptions.IgnoreInheritedMembers)) { - if (member.ImplementedInterfaceMembers.Any ()) + foreach (var member in protocolType.GetMembers().OfType<IPropertySymbol>()) { + if (member.ExplicitInterfaceImplementations.Length > 0) continue; if (!cg.IsValidMember (member)) continue; if (IsImplemented (type, member)) continue; - if (member.CanGet && member.Getter.Attributes.Any (a => a.AttributeType.Name == "ExportAttribute" && MonoCSharpCompletionEngine.IsFoundationNamespace (a.AttributeType.Namespace)) || - member.CanSet && member.Setter.Attributes.Any (a => a.AttributeType.Name == "ExportAttribute" && MonoCSharpCompletionEngine.IsFoundationNamespace (a.AttributeType.Namespace))) + if (member.GetMethod != null && member.GetMethod.GetAttributes ().Any (a => a.AttributeClass.Name == "ExportAttribute" && ProtocolMemberContextHandler.IsFoundationNamespace (a.AttributeClass.ContainingNamespace)) || + member.SetMethod != null && member.SetMethod.GetAttributes ().Any (a => a.AttributeClass.Name == "ExportAttribute" && ProtocolMemberContextHandler.IsFoundationNamespace (a.AttributeClass.ContainingNamespace))) yield return member; } } @@ -227,63 +210,11 @@ namespace MonoDevelop.CodeGeneration protected override IEnumerable<string> GenerateCode (List<object> includedMembers) { - var generator = Options.CreateCodeGenerator (); - generator.AutoIndent = false; - var ctx = MDRefactoringContext.Create (Options.Document, Options.Document.Editor.Caret.Location).Result; - if (ctx == null) - yield break; - var builder = ctx.CreateTypeSystemAstBuilder (); - - foreach (IMember member in includedMembers) { - yield return GenerateMemberCode (ctx, builder, member); + foreach (ISymbol member in includedMembers) { + yield return CSharpCodeGenerator.CreateProtocolMemberImplementation (Options.DocumentContext, Options.Editor, Options.EnclosingType, Options.EnclosingPart.GetLocation (), member, false).Code; } } } - - internal static string GenerateMemberCode (MDRefactoringContext ctx, TypeSystemAstBuilder builder, IMember member) - { - var method = builder.ConvertEntity (member) as MethodDeclaration; - if (method != null) { - method.Body = new BlockStatement { - new ThrowStatement (new ObjectCreateExpression (ctx.CreateShortType ("System", "NotImplementedException"))) - }; - method.Modifiers &= ~Modifiers.Virtual; - method.Modifiers &= ~Modifiers.Abstract; - method.Attributes.Add (new AttributeSection { - Attributes = { - GenerateExportAttribute (ctx, member) - } - }); - return method.ToString (ctx.FormattingOptions); - } - var property = builder.ConvertEntity (member) as PropertyDeclaration; - if (property == null) - return null; - var p = (IProperty)member; - property.Modifiers &= ~Modifiers.Virtual; - property.Modifiers &= ~Modifiers.Abstract; - if (p.CanGet) { - property.Getter.Body = new BlockStatement { - new ThrowStatement (new ObjectCreateExpression (ctx.CreateShortType ("System", "NotImplementedException"))) - }; - property.Getter.Attributes.Add (new AttributeSection { - Attributes = { - GenerateExportAttribute (ctx, p.Getter) - } - }); - } - if (p.CanSet) { - property.Setter.Body = new BlockStatement { - new ThrowStatement (new ObjectCreateExpression (ctx.CreateShortType ("System", "NotImplementedException"))) - }; - property.Setter.Attributes.Add (new AttributeSection { - Attributes = { - GenerateExportAttribute (ctx, p.Setter) - } - }); - } - return property.ToString (ctx.FormattingOptions); - } } class OptionalProtocolMemberGenerator : BaseExportCodeGenerator @@ -300,7 +231,7 @@ namespace MonoDevelop.CodeGeneration } } - public override bool IsValidMember (IMember member) + public override bool IsValidMember (ISymbol member) { return !member.IsAbstract; } @@ -320,11 +251,9 @@ namespace MonoDevelop.CodeGeneration } } - public override bool IsValidMember (IMember member) + public override bool IsValidMember (ISymbol member) { return member.IsAbstract; } } - -} - +}
\ No newline at end of file |