diff options
Diffstat (limited to 'main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration')
15 files changed, 974 insertions, 808 deletions
diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/AbstractGenerateAction.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/AbstractGenerateAction.cs index 12fcc3a87d..13234fff9e 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/AbstractGenerateAction.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/AbstractGenerateAction.cs @@ -31,18 +31,22 @@ using Gtk; using System.Collections.Generic; using MonoDevelop.Refactoring; using MonoDevelop.Ide; -using ICSharpCode.NRefactory.TypeSystem; using MonoDevelop.Ide.TypeSystem; using MonoDevelop.Components; +using Microsoft.CodeAnalysis; +using MonoDevelop.Ide.Editor; +using MonoDevelop.Core.Text; +using MonoDevelop.CSharp.Completion; +using MonoDevelop.CSharp.Formatting; namespace MonoDevelop.CodeGeneration { - public abstract class AbstractGenerateAction : IGenerateAction + abstract class AbstractGenerateAction : IGenerateAction { readonly TreeStore store = new TreeStore (typeof(bool), typeof(Xwt.Drawing.Image), typeof(string), typeof(object)); readonly CodeGenerationOptions options; - public CodeGenerationOptions Options { + internal CodeGenerationOptions Options { get { return options; } @@ -76,23 +80,18 @@ namespace MonoDevelop.CodeGeneration column.Expand = true; treeView.AppendColumn (column); - Ambience ambience = AmbienceService.GetAmbienceForFile (options.Document.FileName); foreach (object obj in GetValidMembers ()) { - var member = obj as IEntity; + var member = obj as ISymbol; if (member != null) { - Store.AppendValues (false, ImageService.GetIcon (member.GetStockIcon (), IconSize.Menu), ambience.GetString (member, OutputFlags.ClassBrowserEntries), member); + Store.AppendValues (false, ImageService.GetIcon (member.GetStockIcon (), IconSize.Menu), member.ToDisplayString (Ambience.LabelFormat), member); continue; } - var tuple = obj as Tuple<IMember, bool>; + var tuple = obj as Tuple<ISymbol, bool>; if (tuple != null) { - Store.AppendValues (false, ImageService.GetIcon (tuple.Item1.GetStockIcon (), IconSize.Menu), ambience.GetString (tuple.Item1, OutputFlags.ClassBrowserEntries), tuple); + Store.AppendValues (false, ImageService.GetIcon (tuple.Item1.GetStockIcon (), IconSize.Menu), tuple.Item1.ToDisplayString (Ambience.LabelFormat), tuple); continue; } - - var variable = obj as IVariable; - if (variable != null) - Store.AppendValues (false, ImageService.GetIcon (variable.GetStockIcon (), IconSize.Menu), variable.Name, variable); } treeView.Model = store; @@ -118,10 +117,9 @@ namespace MonoDevelop.CodeGeneration static string AddIndent (string text, string indent) { - var doc = new Mono.TextEditor.TextDocument (); - doc.Text = text; + var doc = TextEditorFactory.CreateNewReadonlyDocument (new StringTextSource (text), ""); var result = new StringBuilder (); - foreach (var line in doc.Lines) { + foreach (var line in doc.GetLines ()) { result.Append (indent); result.Append (doc.GetTextAt (line.SegmentIncludingDelimiter)); } @@ -141,7 +139,7 @@ namespace MonoDevelop.CodeGeneration } while (store.IterNext (ref iter)); var output = new StringBuilder (); - string indent = RefactoringOptions.GetIndent (options.Document, (IEntity)options.EnclosingMember ?? options.EnclosingType) + "\t"; + string indent = options.Editor.GetVirtualIndentationString (options.Editor.CaretLine); foreach (string nodeText in GenerateCode (includedMembers)) { if (output.Length > 0) { output.AppendLine (); @@ -151,8 +149,14 @@ namespace MonoDevelop.CodeGeneration } if (output.Length > 0) { - var data = options.Document.Editor; - data.InsertAtCaret (output.ToString ().TrimStart ()); + var data = options.Editor; + data.EnsureCaretIsNotVirtual (); + int offset = data.CaretOffset; + var text = output.ToString ().TrimStart (); + using (var undo = data.OpenUndoGroup ()) { + data.InsertAtCaret (text); + OnTheFlyFormatter.Format (data, options.DocumentContext, offset, offset + text.Length); + } } } } diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/CodeGenerationOptions.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/CodeGenerationOptions.cs index 3ec0f395d3..658891bb9b 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/CodeGenerationOptions.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/CodeGenerationOptions.cs @@ -26,148 +26,154 @@ using System.Linq; using MonoDevelop.Ide.Gui; using MonoDevelop.Ide; -using ICSharpCode.NRefactory.TypeSystem; -using ICSharpCode.NRefactory.CSharp; -using ICSharpCode.NRefactory.CSharp.TypeSystem; using MonoDevelop.Ide.TypeSystem; using MonoDevelop.Core; -using ICSharpCode.NRefactory.CSharp.Resolver; using System; using System.Threading; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Text; +using Microsoft.CodeAnalysis.Simplification; +using MonoDevelop.Ide.Editor; +using Microsoft.CodeAnalysis.Options; +using MonoDevelop.Ide.Gui.Content; +using Microsoft.CodeAnalysis.Formatting; +using System.Diagnostics; +using ICSharpCode.NRefactory6.CSharp; namespace MonoDevelop.CodeGeneration { - public class CodeGenerationOptions + sealed class CodeGenerationOptions { - public Document Document { + readonly int offset; + + public TextEditor Editor + { get; private set; } - - public ITypeDefinition EnclosingType { + + public DocumentContext DocumentContext + { get; private set; } - - public IUnresolvedTypeDefinition EnclosingPart { + + public ITypeSymbol EnclosingType + { get; private set; } - - public IMember EnclosingMember { + + public SyntaxNode EnclosingMemberSyntax + { get; private set; } - - public string MimeType { - get { - return DesktopService.GetMimeTypeForUri (Document.FileName); - } + + public TypeDeclarationSyntax EnclosingPart + { + get; + private set; } - - public CSharpFormattingOptions FormattingOptions { - get { - var doc = Document; - var policyParent = doc.Project != null ? doc.Project.Policies : null; - var types = DesktopService.GetMimeTypeInheritanceChain (doc.Editor.MimeType); - var codePolicy = policyParent != null ? policyParent.Get<MonoDevelop.CSharp.Formatting.CSharpFormattingPolicy> (types) : MonoDevelop.Projects.Policies.PolicyService.GetDefaultPolicy<MonoDevelop.CSharp.Formatting.CSharpFormattingPolicy> (types); - return codePolicy.CreateOptions (); - } + + public ISymbol EnclosingMember + { + get; + private set; } - - static AstNode FirstExpressionChild (AstNode parent) + + public string MimeType { - AstNode node = parent.FirstChild; - if (node == null) - return null; - while (node != null && !(node is Expression || node is Statement)) { - node = node.NextSibling; + get + { + return DesktopService.GetMimeTypeForUri (DocumentContext.Name); } - return node; } - - static AstNode NextExpression (AstNode parent) + + public OptionSet FormattingOptions { - AstNode node = parent.GetNextNode (); - if (node == null) - return null; - while (node != null && !(node is Expression || node is Statement)) { - node = node.GetNextNode (); + get + { + var doc = DocumentContext; + var policyParent = doc.Project != null ? doc.Project.Policies : null; + var types = DesktopService.GetMimeTypeInheritanceChain (Editor.MimeType); + var codePolicy = policyParent != null ? policyParent.Get<MonoDevelop.CSharp.Formatting.CSharpFormattingPolicy> (types) : MonoDevelop.Projects.Policies.PolicyService.GetDefaultPolicy<MonoDevelop.CSharp.Formatting.CSharpFormattingPolicy> (types); + var textPolicy = policyParent != null ? policyParent.Get<TextStylePolicy> (types) : MonoDevelop.Projects.Policies.PolicyService.GetDefaultPolicy<TextStylePolicy> (types); + return codePolicy.CreateOptions (textPolicy); } - return node; } - - readonly Lazy<CSharpResolver> currentState; - public CSharpResolver CurrentState { - get { - return currentState.Value; - } + + public SemanticModel CurrentState + { + get; + private set; } - - public CodeGenerationOptions () + + internal CodeGenerationOptions (TextEditor editor, DocumentContext ctx) { - currentState = new Lazy<CSharpResolver> (() => { - var parsedDocument = Document.ParsedDocument; - if (parsedDocument == null) - return null; - var unit = parsedDocument.GetAst<SyntaxTree> ().Clone (); - var file = parsedDocument.ParsedFile as CSharpUnresolvedFile; - - var resolvedNode = unit.GetNodeAt<BlockStatement> (Document.Editor.Caret.Location); - if (resolvedNode == null) - return null; - - var expr = new IdentifierExpression ("foo"); - resolvedNode.Add (expr); - - var ctx = file.GetTypeResolveContext (Document.Compilation, Document.Editor.Caret.Location); - - var resolver = new CSharpResolver (ctx); - - var astResolver = new CSharpAstResolver (resolver, unit, file); - astResolver.ApplyNavigator (new NodeListResolveVisitorNavigator (expr), CancellationToken.None); - astResolver.Resolve (expr); - return astResolver.GetResolverStateBefore (expr); - }); + Editor = editor; + DocumentContext = ctx; + if (ctx.ParsedDocument != null) + CurrentState = ctx.ParsedDocument.GetAst<SemanticModel> (); + offset = editor.CaretOffset; + var tree = CurrentState.SyntaxTree; + EnclosingPart = tree.GetContainingTypeDeclaration (offset, default(CancellationToken)); + if (EnclosingPart != null) { + EnclosingType = CurrentState.GetDeclaredSymbol (EnclosingPart) as ITypeSymbol; + + foreach (var member in EnclosingPart.Members) { + if (member.Span.Contains (offset)) { + EnclosingMemberSyntax = member; + break; + } + + } + if (EnclosingMemberSyntax != null) + EnclosingMember = CurrentState.GetDeclaredSymbol (EnclosingMemberSyntax); + } } - - public AstType CreateShortType (IType fullType) + + public string CreateShortType (ITypeSymbol fullType) { - var parsedFile = Document.ParsedDocument.ParsedFile as CSharpUnresolvedFile; - - var compilation = Document.Compilation; - fullType = compilation.Import (fullType); - var csResolver = parsedFile.GetResolver (compilation, Document.Editor.Caret.Location); - - var builder = new ICSharpCode.NRefactory.CSharp.Refactoring.TypeSystemAstBuilder (csResolver); - return builder.ConvertType (fullType); + return fullType.ToMinimalDisplayString (CurrentState, offset); } - - public CodeGenerator CreateCodeGenerator () + + public static CodeGenerationOptions CreateCodeGenerationOptions (TextEditor document, DocumentContext ctx) { - var result = CodeGenerator.CreateGenerator (Document); - if (result == null) - LoggingService.LogError ("Generator can't be generated for : " + Document.Editor.MimeType); - return result; + return new CodeGenerationOptions (document, ctx); } - - public static CodeGenerationOptions CreateCodeGenerationOptions (Document document) + + public async Task<string> OutputNode (SyntaxNode node, CancellationToken cancellationToken = default(CancellationToken)) { - document.UpdateParseDocument (); - var options = new CodeGenerationOptions { - Document = document - }; - if (document.ParsedDocument != null && document.ParsedDocument.ParsedFile != null) { - options.EnclosingPart = document.ParsedDocument.ParsedFile.GetInnermostTypeDefinition (document.Editor.Caret.Location); - var project = document.Project; - if (options.EnclosingPart != null && project != null) - options.EnclosingType = options.EnclosingPart.Resolve (project).GetDefinition (); - if (options.EnclosingType != null) { - options.EnclosingMember = options.EnclosingType.Members.FirstOrDefault (m => !m.IsSynthetic && m.Region.FileName == document.FileName && m.Region.IsInside (document.Editor.Caret.Location)); - } + node = Formatter.Format (node, TypeSystemService.Workspace, FormattingOptions, cancellationToken); + node = node.WithAdditionalAnnotations (Formatter.Annotation, Simplifier.Annotation); + + var text = Editor.Text; + string nodeText = node.ToString (); + text = text.Insert (offset, nodeText); + + + var backgroundDocument = DocumentContext.AnalysisDocument.WithText (SourceText.From (text)); + + var currentRoot = await backgroundDocument.GetSyntaxRootAsync (cancellationToken).ConfigureAwait (false); + + node = currentRoot.FindNode (TextSpan.FromBounds(offset, offset + nodeText.Length)); + + currentRoot = currentRoot.TrackNodes (node); + backgroundDocument = backgroundDocument.WithSyntaxRoot (currentRoot); + backgroundDocument = await Simplifier.ReduceAsync (backgroundDocument, TextSpan.FromBounds (offset, offset + nodeText.Length), FormattingOptions, cancellationToken).ConfigureAwait(false); + backgroundDocument = await Formatter.FormatAsync (backgroundDocument, Formatter.Annotation, FormattingOptions, cancellationToken).ConfigureAwait(false); + + var newRoot = await backgroundDocument.GetSyntaxRootAsync (cancellationToken).ConfigureAwait (false); + + var formattedNode = newRoot.GetCurrentNode (node); + if (formattedNode == null) { + LoggingService.LogError ("Fatal error: Can't find current formatted node in code generator document."); + return nodeText; } - return options; + return formattedNode.ToString (); } - } } diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/CreateConstructorGenerator.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/CreateConstructorGenerator.cs index d48bafe43d..17b56bcf0a 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/CreateConstructorGenerator.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/CreateConstructorGenerator.cs @@ -1,166 +1,209 @@ -// -// CreateConstructorGenerator.cs -// -// Author: -// Mike Krüger <mkrueger@novell.com> -// -// Copyright (c) 2009 Novell, Inc (http://www.novell.com) -// -// 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 Gtk; +//
+// CreateConstructorGenerator.cs
+//
+// Author:
+// Mike Krüger <mkrueger@novell.com>
+//
+// Copyright (c) 2009 Novell, Inc (http://www.novell.com)
+//
+// 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; using System.Collections.Generic; -using ICSharpCode.NRefactory.CSharp; +using System.Text;
+using System.Linq;
using MonoDevelop.Core; -using ICSharpCode.NRefactory.TypeSystem; -using System.Linq; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Simplification; +using ICSharpCode.NRefactory6.CSharp;
+using Gtk;
namespace MonoDevelop.CodeGeneration { class CreateConstructorGenerator : ICodeGenerator { - public string Icon { - get { + public string Icon + { + get + { return "md-newmethod"; } } - - public string Text { - get { + + public string Text + { + get + { return GettextCatalog.GetString ("Constructor"); } } - - public string GenerateDescription { - get { + + public string GenerateDescription + { + get + { return GettextCatalog.GetString ("Select members to be initialized by the constructor."); } } - + public bool IsValid (CodeGenerationOptions options) { var createConstructor = new CreateConstructor (options); return createConstructor.IsValid (); } - + public IGenerateAction InitalizeSelection (CodeGenerationOptions options, TreeView treeView) { var createConstructor = new CreateConstructor (options); createConstructor.Initialize (treeView); return createConstructor; } - +
+ internal static TypeSyntax ConvertType (ITypeSymbol symbol)
+ {
+ // TODO: There needs to be a better way doing that.
+ return SyntaxFactory.ParseTypeName (symbol.ToDisplayString (SymbolDisplayFormat.CSharpErrorMessageFormat));
+ }
+ class CreateConstructor : AbstractGenerateAction { public CreateConstructor (CodeGenerationOptions options) : base (options) { } - + protected override IEnumerable<object> GetValidMembers () { if (Options.EnclosingType == null || Options.EnclosingMember != null) yield break; - var bt = Options.EnclosingType.DirectBaseTypes.FirstOrDefault (t => t.Kind != TypeKind.Interface); + var bt = Options.EnclosingType.BaseType; if (bt != null) { - var ctors = bt.GetConstructors (m => !m.IsSynthetic).ToList (); - foreach (var ctor in ctors) { - if (ctor.Parameters.Count > 0 || ctors.Count > 1) { + var ctors = bt.GetMembers ().OfType<IMethodSymbol> ().Where (m => m.MethodKind == MethodKind.Constructor && !m.IsImplicitlyDeclared).ToList (); + foreach (IMethodSymbol ctor in ctors) { + if (ctor.Parameters.Length > 0 || ctors.Count > 1) { yield return ctor; } - } + } } - foreach (IField field in Options.EnclosingType.Fields) { - if (field.IsSynthetic) + foreach (IFieldSymbol field in Options.EnclosingType.GetMembers ().OfType<IFieldSymbol> ()) { + if (field.IsImplicitlyDeclared) continue; yield return field; } - foreach (IProperty property in Options.EnclosingType.Properties) { - if (property.IsSynthetic) + foreach (IPropertySymbol property in Options.EnclosingType.GetMembers ().OfType<IPropertySymbol> ()) { + if (property.IsImplicitlyDeclared) continue; - if (!property.CanSet) + if (property.SetMethod == null) continue; yield return property; } } - - static string CreateParameterName (IMember member) + + static string CreateParameterName (ISymbol member) { if (char.IsUpper (member.Name[0])) return char.ToLower (member.Name[0]) + member.Name.Substring (1); return member.Name; } - + protected override IEnumerable<string> GenerateCode (List<object> includedMembers) - { + {
bool gotConstructorOverrides = false; - foreach (IMethod m in includedMembers.OfType<IMethod> ().Where (m => m.SymbolKind == SymbolKind.Constructor)) { + foreach (IMethodSymbol m in includedMembers.OfType<IMethodSymbol> ().Where (m => m.MethodKind == MethodKind.Constructor)) { gotConstructorOverrides = true; - var init = new ConstructorInitializer { - ConstructorInitializerType = ConstructorInitializerType.Base - }; - - var overridenConstructor = new ConstructorDeclaration { - Name = Options.EnclosingType.Name, - Modifiers = Modifiers.Public, - Body = new BlockStatement (), - }; - - if (m.Parameters.Count > 0) - overridenConstructor.Initializer = init; - + var parameters = new List<ParameterSyntax> ();
+ var initArgs = new List<ArgumentSyntax> ();
+ var statements = new List<StatementSyntax> ();
foreach (var par in m.Parameters) { - overridenConstructor.Parameters.Add (new ParameterDeclaration (Options.CreateShortType (par.Type), par.Name)); - init.Arguments.Add (new IdentifierExpression(par.Name)); + parameters.Add (SyntaxFactory.Parameter (SyntaxFactory.Identifier (par.Name)).WithType (ConvertType (par.Type)));
+ initArgs.Add (SyntaxFactory.Argument (SyntaxFactory.ParseExpression (par.Name))); } - foreach (var member in includedMembers.OfType<IMember> ()) { - if (member.SymbolKind == SymbolKind.Constructor) + + foreach (ISymbol member in includedMembers) { + if (member.Kind == SymbolKind.Method) continue; - overridenConstructor.Parameters.Add (new ParameterDeclaration (Options.CreateShortType (member.ReturnType), CreateParameterName (member))); + var paramName = CreateParameterName (member); + parameters.Add (SyntaxFactory.Parameter (SyntaxFactory.Identifier (paramName)).WithType (ConvertType (member.GetReturnType ()))); - var memberReference = new MemberReferenceExpression (new ThisReferenceExpression (), member.Name); - var assign = new AssignmentExpression (memberReference, AssignmentOperatorType.Assign, new IdentifierExpression (CreateParameterName (member))); - overridenConstructor.Body.Statements.Add (new ExpressionStatement (assign)); + statements.Add (
+ SyntaxFactory.ExpressionStatement (
+ SyntaxFactory.AssignmentExpression (
+ SyntaxKind.SimpleAssignmentExpression,
+ SyntaxFactory.MemberAccessExpression (
+ SyntaxKind.SimpleMemberAccessExpression,
+ SyntaxFactory.ThisExpression (),
+ SyntaxFactory.IdentifierName (member.Name)
+ ),
+ SyntaxFactory.IdentifierName (paramName)
+ )
+ )
+ ); } - yield return overridenConstructor.ToString (Options.FormattingOptions); + var node = SyntaxFactory.ConstructorDeclaration ( + SyntaxFactory.List<AttributeListSyntax> (), + SyntaxFactory.TokenList (SyntaxFactory.Token (SyntaxKind.PublicKeyword)), + SyntaxFactory.Identifier (Options.EnclosingType.Name), + SyntaxFactory.ParameterList (SyntaxFactory.SeparatedList<ParameterSyntax> (parameters)), + initArgs.Count > 0 ? SyntaxFactory.ConstructorInitializer (SyntaxKind.BaseConstructorInitializer, SyntaxFactory.ArgumentList (SyntaxFactory.SeparatedList<ArgumentSyntax> (initArgs))) : null, + SyntaxFactory.Block (statements.ToArray ()) + );
+ yield return Options.OutputNode (node).Result; } if (gotConstructorOverrides) - yield break; - var constructorDeclaration = new ConstructorDeclaration { - Name = Options.EnclosingType.Name, - Modifiers = Modifiers.Public, - Body = new BlockStatement () - }; - - foreach (IMember member in includedMembers) { - constructorDeclaration.Parameters.Add (new ParameterDeclaration (Options.CreateShortType (member.ReturnType), CreateParameterName (member))); - - var memberReference = new MemberReferenceExpression (new ThisReferenceExpression (), member.Name); - var assign = new AssignmentExpression (memberReference, AssignmentOperatorType.Assign, new IdentifierExpression (CreateParameterName (member))); - constructorDeclaration.Body.Statements.Add (new ExpressionStatement (assign)); + yield break;
+
+ var parameters2 = new List<ParameterSyntax> ();
+ var statements2 = new List<StatementSyntax> (); + foreach (ISymbol member in includedMembers) { + var paramName = CreateParameterName (member);
+ parameters2.Add (SyntaxFactory.Parameter (SyntaxFactory.Identifier (paramName)).WithType (ConvertType (member.GetReturnType ())));
+
+ statements2.Add (
+ SyntaxFactory.ExpressionStatement (
+ SyntaxFactory.AssignmentExpression (
+ SyntaxKind.SimpleAssignmentExpression,
+ SyntaxFactory.MemberAccessExpression (
+ SyntaxKind.SimpleMemberAccessExpression,
+ SyntaxFactory.ThisExpression (),
+ SyntaxFactory.IdentifierName (member.Name)
+ ),
+ SyntaxFactory.IdentifierName (paramName)
+ )
+ )
+ );
} - yield return constructorDeclaration.ToString (Options.FormattingOptions); + var node2 = SyntaxFactory.ConstructorDeclaration (
+ SyntaxFactory.List<AttributeListSyntax> (),
+ SyntaxFactory.TokenList (SyntaxFactory.Token (SyntaxKind.PublicKeyword)),
+ SyntaxFactory.Identifier (Options.EnclosingType.Name),
+ SyntaxFactory.ParameterList (SyntaxFactory.SeparatedList<ParameterSyntax> (parameters2)),
+ null,
+ SyntaxFactory.Block (statements2.ToArray ())
+ );
+ yield return Options.OutputNode (node2).Result; } } } diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/EqualityMembersGenerator.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/EqualityMembersGenerator.cs index 49d89a70e6..d5849c638b 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/EqualityMembersGenerator.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/EqualityMembersGenerator.cs @@ -1,159 +1,160 @@ -// -// EqualityMembersGenerator.cs -// -// Author: -// Mike Krüger <mkrueger@novell.com> -// -// Copyright (c) 2009 Novell, Inc (http://www.novell.com) -// -// 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.Collections.Generic; -using ICSharpCode.NRefactory.CSharp; -using MonoDevelop.Core; -using ICSharpCode.NRefactory.TypeSystem; - -namespace MonoDevelop.CodeGeneration -{ - class EqualityMembersGenerator : ICodeGenerator - { - public string Icon { - get { - return "md-newmethod"; - } - } - - public string Text { - get { - return GettextCatalog.GetString ("Equality members"); - } - } - - public string GenerateDescription { - get { - return GettextCatalog.GetString ("Select members to include in equality."); - } - } - - public bool IsValid (CodeGenerationOptions options) - { - return new CreateEquality (options).IsValid (); - } - - public IGenerateAction InitalizeSelection (CodeGenerationOptions options, Gtk.TreeView treeView) - { - var createEventMethod = new CreateEquality (options); - createEventMethod.Initialize (treeView); - return createEventMethod; - } - - class CreateEquality : AbstractGenerateAction - { - public CreateEquality (CodeGenerationOptions options) : base (options) - { - } - - protected override IEnumerable<object> GetValidMembers () - { - if (Options.EnclosingType == null || Options.EnclosingMember != null) - yield break; - foreach (IField field in Options.EnclosingType.Fields) { - if (field.IsSynthetic) - continue; - yield return field; - } - - foreach (IProperty property in Options.EnclosingType.Properties) { - if (property.IsSynthetic) - continue; - if (property.CanGet) - yield return property; - } - } - - protected override IEnumerable<string> GenerateCode (List<object> includedMembers) - { - // Genereate Equals - var methodDeclaration = new MethodDeclaration (); - methodDeclaration.Name = "Equals"; - - methodDeclaration.ReturnType = new PrimitiveType ("bool"); - methodDeclaration.Modifiers = Modifiers.Public | Modifiers.Override; - methodDeclaration.Body = new BlockStatement (); - methodDeclaration.Parameters.Add (new ParameterDeclaration (new PrimitiveType ("object"), "obj")); - var paramId = new IdentifierExpression ("obj"); - var ifStatement = new IfElseStatement (); - ifStatement.Condition = new BinaryOperatorExpression (paramId, BinaryOperatorType.Equality, new PrimitiveExpression (null)); - ifStatement.TrueStatement = new ReturnStatement (new PrimitiveExpression (false)); - methodDeclaration.Body.Statements.Add (ifStatement); - - ifStatement = new IfElseStatement (); - var arguments = new List<Expression> (); - arguments.Add (new ThisReferenceExpression ()); - arguments.Add (paramId.Clone ()); - ifStatement.Condition = new InvocationExpression (new IdentifierExpression ("ReferenceEquals"), arguments); - ifStatement.TrueStatement = new ReturnStatement (new PrimitiveExpression (true)); - methodDeclaration.Body.Statements.Add (ifStatement); - - ifStatement = new IfElseStatement (); - ifStatement.Condition = new BinaryOperatorExpression (new InvocationExpression (new MemberReferenceExpression (paramId.Clone (), "GetType")), BinaryOperatorType.InEquality, new TypeOfExpression (new SimpleType (Options.EnclosingType.Name))); - ifStatement.TrueStatement = new ReturnStatement (new PrimitiveExpression (false)); - methodDeclaration.Body.Statements.Add (ifStatement); - - var varType = new SimpleType (Options.EnclosingType.Name); - var varDecl = new VariableDeclarationStatement (varType, "other", new CastExpression (varType.Clone (), paramId.Clone ())); - methodDeclaration.Body.Statements.Add (varDecl); - - var otherId = new IdentifierExpression ("other"); - Expression binOp = null; - foreach (IMember member in includedMembers) { - Expression right = new BinaryOperatorExpression (new IdentifierExpression (member.Name), BinaryOperatorType.Equality, new MemberReferenceExpression (otherId.Clone (), member.Name)); - binOp = binOp == null ? right : new BinaryOperatorExpression (binOp, BinaryOperatorType.ConditionalAnd, right); - } - - methodDeclaration.Body.Statements.Add (new ReturnStatement (binOp)); - yield return methodDeclaration.ToString (Options.FormattingOptions); - - methodDeclaration = new MethodDeclaration (); - methodDeclaration.Name = "GetHashCode"; - - methodDeclaration.ReturnType = new PrimitiveType ("int"); - methodDeclaration.Modifiers = Modifiers.Public | Modifiers.Override; - methodDeclaration.Body = new BlockStatement (); - - binOp = null; - foreach (IMember member in includedMembers) { - Expression right; - right = new InvocationExpression (new MemberReferenceExpression (new IdentifierExpression (member.Name), "GetHashCode")); - - IType type = member.ReturnType; - if (type != null && type.Kind != TypeKind.Struct && type.Kind != TypeKind.Enum) - right = new ParenthesizedExpression (new ConditionalExpression (new BinaryOperatorExpression (new IdentifierExpression (member.Name), BinaryOperatorType.InEquality, new PrimitiveExpression (null)), right, new PrimitiveExpression (0))); - - binOp = binOp == null ? right : new BinaryOperatorExpression (binOp, BinaryOperatorType.ExclusiveOr, right); - } - var uncheckedBlock = new BlockStatement (); - uncheckedBlock.Statements.Add (new ReturnStatement (binOp)); - - methodDeclaration.Body.Statements.Add (new UncheckedStatement (uncheckedBlock)); - yield return methodDeclaration.ToString (Options.FormattingOptions); - } - } - } -} +//// +//// EqualityMembersGenerator.cs +//// +//// Author: +//// Mike Krüger <mkrueger@novell.com> +//// +//// Copyright (c) 2009 Novell, Inc (http://www.novell.com) +//// +//// 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.Collections.Generic; +//using MonoDevelop.Core; +//using Microsoft.CodeAnalysis; +//using ICSharpCode.NRefactory.CSharp; +//using ICSharpCode.NRefactory6.CSharp; +// +//namespace MonoDevelop.CodeGeneration +//{ +// class EqualityMembersGenerator : ICodeGenerator +// { +// public string Icon { +// get { +// return "md-newmethod"; +// } +// } +// +// public string Text { +// get { +// return GettextCatalog.GetString ("Equality members"); +// } +// } +// +// public string GenerateDescription { +// get { +// return GettextCatalog.GetString ("Select members to include in equality."); +// } +// } +// +// public bool IsValid (CodeGenerationOptions options) +// { +// return new CreateEquality (options).IsValid (); +// } +// +// public IGenerateAction InitalizeSelection (CodeGenerationOptions options, Gtk.TreeView treeView) +// { +// var createEventMethod = new CreateEquality (options); +// createEventMethod.Initialize (treeView); +// return createEventMethod; +// } +// +// class CreateEquality : AbstractGenerateAction +// { +// public CreateEquality (CodeGenerationOptions options) : base (options) +// { +// } +// +// protected override IEnumerable<object> GetValidMembers () +// { +// if (Options.EnclosingType == null || Options.EnclosingMember != null) +// yield break; +// foreach (IFieldSymbol field in Options.EnclosingType.GetMembers ().OfType<IFieldSymbol> ()) { +// if (field.IsImplicitlyDeclared) +// continue; +// yield return field; +// } +// +// foreach (IPropertySymbol property in Options.EnclosingType.GetMembers ().OfType<IPropertySymbol> ()) { +// if (property.IsImplicitlyDeclared) +// continue; +// if (property.GetMethod != null) +// yield return property; +// } +// } +// +// protected override IEnumerable<string> GenerateCode (List<object> includedMembers) +// { +// // Genereate Equals +// var methodDeclaration = new MethodDeclaration (); +// methodDeclaration.Name = "Equals"; +// +// methodDeclaration.ReturnType = new PrimitiveType ("bool"); +// methodDeclaration.Modifiers = Modifiers.Public | Modifiers.Override; +// methodDeclaration.Body = new BlockStatement (); +// methodDeclaration.Parameters.Add (new ParameterDeclaration (new PrimitiveType ("object"), "obj")); +// var paramId = new IdentifierExpression ("obj"); +// var ifStatement = new IfElseStatement (); +// ifStatement.Condition = new BinaryOperatorExpression (paramId, BinaryOperatorType.Equality, new PrimitiveExpression (null)); +// ifStatement.TrueStatement = new ReturnStatement (new PrimitiveExpression (false)); +// methodDeclaration.Body.Statements.Add (ifStatement); +// +// ifStatement = new IfElseStatement (); +// var arguments = new List<Expression> (); +// arguments.Add (new ThisReferenceExpression ()); +// arguments.Add (paramId.Clone ()); +// ifStatement.Condition = new InvocationExpression (new IdentifierExpression ("ReferenceEquals"), arguments); +// ifStatement.TrueStatement = new ReturnStatement (new PrimitiveExpression (true)); +// methodDeclaration.Body.Statements.Add (ifStatement); +// +// ifStatement = new IfElseStatement (); +// ifStatement.Condition = new BinaryOperatorExpression (new InvocationExpression (new MemberReferenceExpression (paramId.Clone (), "GetType")), BinaryOperatorType.InEquality, new TypeOfExpression (new SimpleType (Options.EnclosingType.Name))); +// ifStatement.TrueStatement = new ReturnStatement (new PrimitiveExpression (false)); +// methodDeclaration.Body.Statements.Add (ifStatement); +// +// var varType = new SimpleType (Options.EnclosingType.Name); +// var varDecl = new VariableDeclarationStatement (varType, "other", new CastExpression (varType.Clone (), paramId.Clone ())); +// methodDeclaration.Body.Statements.Add (varDecl); +// +// var otherId = new IdentifierExpression ("other"); +// Expression binOp = null; +// foreach (ISymbol member in includedMembers) { +// Expression right = new BinaryOperatorExpression (new IdentifierExpression (member.Name), BinaryOperatorType.Equality, new MemberReferenceExpression (otherId.Clone (), member.Name)); +// binOp = binOp == null ? right : new BinaryOperatorExpression (binOp, BinaryOperatorType.ConditionalAnd, right); +// } +// +// methodDeclaration.Body.Statements.Add (new ReturnStatement (binOp)); +// yield return methodDeclaration.ToString (); +// +// methodDeclaration = new MethodDeclaration (); +// methodDeclaration.Name = "GetHashCode"; +// +// methodDeclaration.ReturnType = new PrimitiveType ("int"); +// methodDeclaration.Modifiers = Modifiers.Public | Modifiers.Override; +// methodDeclaration.Body = new BlockStatement (); +// +// binOp = null; +// foreach (ISymbol member in includedMembers) { +// Expression right; +// right = new InvocationExpression (new MemberReferenceExpression (new IdentifierExpression (member.Name), "GetHashCode")); +// +// var type = member.GetReturnType (); +// if (type != null && type.TypeKind != TypeKind.Struct && type.TypeKind != TypeKind.Enum) +// right = new ParenthesizedExpression (new ConditionalExpression (new BinaryOperatorExpression (new IdentifierExpression (member.Name), BinaryOperatorType.InEquality, new PrimitiveExpression (null)), right, new PrimitiveExpression (0))); +// +// binOp = binOp == null ? right : new BinaryOperatorExpression (binOp, BinaryOperatorType.ExclusiveOr, right); +// } +// var uncheckedBlock = new BlockStatement (); +// uncheckedBlock.Statements.Add (new ReturnStatement (binOp)); +// +// methodDeclaration.Body.Statements.Add (new UncheckedStatement (uncheckedBlock)); +// yield return methodDeclaration.ToString (); +// } +// } +// } +//} 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 diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/GenerateCodeWindow.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/GenerateCodeWindow.cs index a96cc7cc11..c6a67ccadc 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/GenerateCodeWindow.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/GenerateCodeWindow.cs @@ -31,7 +31,7 @@ using MonoDevelop.Ide.Gui; using MonoDevelop.Refactoring; using System.Collections.Generic; using MonoDevelop.Ide; -using Mono.TextEditor.PopupWindow; +using MonoDevelop.Ide.Editor; namespace MonoDevelop.CodeGeneration { @@ -174,9 +174,9 @@ namespace MonoDevelop.CodeGeneration } } - public static void ShowIfValid (Document document, MonoDevelop.Ide.CodeCompletion.CodeCompletionContext completionContext) + public static void ShowIfValid (TextEditor editor, DocumentContext context, MonoDevelop.Ide.CodeCompletion.CodeCompletionContext completionContext) { - var options = CodeGenerationOptions.CreateCodeGenerationOptions (document); + var options = CodeGenerationOptions.CreateCodeGenerationOptions (editor, context); var validGenerators = new List<ICodeGenerator> (); foreach (var generator in CodeGenerationService.CodeGenerators) { diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/ICodeGenerator.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/ICodeGenerator.cs index b70422665b..f0d64d40ba 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/ICodeGenerator.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/ICodeGenerator.cs @@ -31,7 +31,7 @@ using Mono.Addins; namespace MonoDevelop.CodeGeneration { - public interface ICodeGenerator + internal interface ICodeGenerator { string Icon { get; @@ -50,14 +50,14 @@ namespace MonoDevelop.CodeGeneration IGenerateAction InitalizeSelection (CodeGenerationOptions options, Gtk.TreeView treeView); } - public interface IGenerateAction + interface IGenerateAction { void GenerateCode (); } static class CodeGenerationService { - static List<ICodeGenerator> codeGenerators = new List<ICodeGenerator>(); + static readonly List<ICodeGenerator> codeGenerators = new List<ICodeGenerator>(); static CodeGenerationService () { diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/ImplementInterfaceMembersGenerator.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/ImplementInterfaceMembersGenerator.cs index 7646b4002f..caf0bbe4e9 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/ImplementInterfaceMembersGenerator.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/ImplementInterfaceMembersGenerator.cs @@ -1,101 +1,100 @@ +//// +//// ImplementInterfaceMembersGenerator.cs +//// +//// Author: +//// Mike Krüger <mkrueger@xamarin.com> +//// +//// Copyright (c) 2012 Xamarin Inc. (http://xamarin.com) +//// +//// 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 Gtk; +//using System.Collections.Generic; +//using MonoDevelop.Core; +//using MonoDevelop.Refactoring; +//using ICSharpCode.NRefactory.CSharp; +//using ICSharpCode.NRefactory.TypeSystem; +//using MonoDevelop.Ide.TypeSystem; +//using System; // -// ImplementInterfaceMembersGenerator.cs +//namespace MonoDevelop.CodeGeneration +//{ +// class ImplementInterfaceMembersGenerator : ICodeGenerator +// { +// public string Icon { +// get { +// return "md-method"; +// } +// } +// +// public string Text { +// get { +// return GettextCatalog.GetString ("Implement interface members"); +// } +// } +// +// public string GenerateDescription { +// get { +// return GettextCatalog.GetString ("Select members to be implemented."); +// } +// } +// +// public bool IsValid (CodeGenerationOptions options) +// { +// return new OverrideMethods (options).IsValid (); +// } +// +// public IGenerateAction InitalizeSelection (CodeGenerationOptions options, Gtk.TreeView treeView) +// { +// OverrideMethods overrideMethods = new OverrideMethods (options); +// overrideMethods.Initialize (treeView); +// return overrideMethods; +// } +// +// class OverrideMethods : AbstractGenerateAction +// { +// public OverrideMethods (CodeGenerationOptions options) : base (options) +// { +// } +// +// protected override IEnumerable<object> GetValidMembers () +// { +// var type = Options.EnclosingType; +// if (type == null || Options.EnclosingMember != null) +// yield break; // -// Author: -// Mike Krüger <mkrueger@xamarin.com> +// foreach (var baseType in Options.EnclosingType.Interfaces) { +// bool ifm; +//// foreach (var t in ICSharpCode.NRefactory.CSharp.Refactoring.ImplementInterfaceAction.CollectMembersToImplement (type, baseType, false, out ifm)) { +//// yield return t; +//// } +// } +// } +// +// protected override IEnumerable<string> GenerateCode (List<object> includedMembers) +// { +// var generator = Options.CreateCodeGenerator (); +// generator.AutoIndent = false; +// foreach (Tuple<IMember, bool> member in includedMembers) +// yield return ""; +// // yield return generator.CreateMemberImplementation (Options.EnclosingType, Options.EnclosingPart, member.Item1, member.Item2).Code; +// } +// } +// } +//} // -// Copyright (c) 2012 Xamarin Inc. (http://xamarin.com) -// -// 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 Gtk; -using System.Collections.Generic; -using MonoDevelop.Core; -using MonoDevelop.Refactoring; -using ICSharpCode.NRefactory.CSharp; -using ICSharpCode.NRefactory.TypeSystem; -using MonoDevelop.Ide.TypeSystem; -using System; - -namespace MonoDevelop.CodeGeneration -{ - class ImplementInterfaceMembersGenerator : ICodeGenerator - { - public string Icon { - get { - return "md-method"; - } - } - - public string Text { - get { - return GettextCatalog.GetString ("Implement interface members"); - } - } - - public string GenerateDescription { - get { - return GettextCatalog.GetString ("Select members to be implemented."); - } - } - - public bool IsValid (CodeGenerationOptions options) - { - return new OverrideMethods (options).IsValid (); - } - - public IGenerateAction InitalizeSelection (CodeGenerationOptions options, Gtk.TreeView treeView) - { - OverrideMethods overrideMethods = new OverrideMethods (options); - overrideMethods.Initialize (treeView); - return overrideMethods; - } - - class OverrideMethods : AbstractGenerateAction - { - public OverrideMethods (CodeGenerationOptions options) : base (options) - { - } - - protected override IEnumerable<object> GetValidMembers () - { - var type = Options.EnclosingType; - if (type == null || Options.EnclosingMember != null) - yield break; - - foreach (var baseType in Options.EnclosingType.DirectBaseTypes) { - if (baseType.Kind != TypeKind.Interface) - continue; - bool ifm; - foreach (var t in ICSharpCode.NRefactory.CSharp.Refactoring.ImplementInterfaceAction.CollectMembersToImplement (type, baseType, false, out ifm)) { - yield return t; - } - } - } - - protected override IEnumerable<string> GenerateCode (List<object> includedMembers) - { - var generator = Options.CreateCodeGenerator (); - generator.AutoIndent = false; - foreach (Tuple<IMember, bool> member in includedMembers) - yield return generator.CreateMemberImplementation (Options.EnclosingType, Options.EnclosingPart, member.Item1, member.Item2).Code; - } - } - } -} - diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/OverrideMembersGenerator.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/OverrideMembersGenerator.cs index 57b241976a..1999cf900f 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/OverrideMembersGenerator.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/OverrideMembersGenerator.cs @@ -28,9 +28,12 @@ using Gtk; using System.Collections.Generic; using MonoDevelop.Core; using MonoDevelop.Refactoring; -using ICSharpCode.NRefactory.CSharp; -using ICSharpCode.NRefactory.TypeSystem; using MonoDevelop.Ide.TypeSystem; +using ICSharpCode.NRefactory6.CSharp; +using System.Linq; +using System.Threading; +using Microsoft.CodeAnalysis; +using MonoDevelop.CSharp.Refactoring; namespace MonoDevelop.CodeGeneration { @@ -41,62 +44,105 @@ namespace MonoDevelop.CodeGeneration return "md-method"; } } - + public string Text { get { return GettextCatalog.GetString ("Override members"); } } - + public string GenerateDescription { get { return GettextCatalog.GetString ("Select members to be overridden."); } } - + public bool IsValid (CodeGenerationOptions options) { return new OverrideMethods (options).IsValid (); } - + public IGenerateAction InitalizeSelection (CodeGenerationOptions options, Gtk.TreeView treeView) { OverrideMethods overrideMethods = new OverrideMethods (options); overrideMethods.Initialize (treeView); return overrideMethods; } - + class OverrideMethods : AbstractGenerateAction { public OverrideMethods (CodeGenerationOptions options) : base (options) { } - + protected override IEnumerable<object> GetValidMembers () { - var type = Options.EnclosingType; - if (type == null || Options.EnclosingMember != null) - yield break; - HashSet<string> memberName = new HashSet<string> (); - foreach (var member in Options.EnclosingType.GetMembers ()) { - if (member.IsSynthetic) - continue; - if (member.IsOverridable) { - string id = AmbienceService.DefaultAmbience.GetString (member, OutputFlags.ClassBrowserEntries); - if (memberName.Contains (id)) - continue; - memberName.Add (id); - yield return member; + var encType = Options.EnclosingType as INamedTypeSymbol; + if (encType == null || Options.EnclosingMember != null) + return Enumerable.Empty<object> (); + + + var result = new HashSet<ISymbol> (); + var cancellationToken = default(CancellationToken); + var baseTypes = encType.GetBaseTypes ().Reverse (); + foreach (var type in baseTypes) { + RemoveOverriddenMembers (result, type, cancellationToken); + + AddOverridableMembers (result, encType, type, cancellationToken); + } + RemoveOverriddenMembers (result, encType, cancellationToken); + return result; + } + + static void AddOverridableMembers (HashSet<ISymbol> result, INamedTypeSymbol containingType, INamedTypeSymbol type, CancellationToken cancellationToken) + { + foreach (var member in type.GetMembers()) { + if (IsOverridable (member, containingType)) { + result.Add (member); + } + } + } + + protected static void RemoveOverriddenMembers (HashSet<ISymbol> result, INamedTypeSymbol containingType, CancellationToken cancellationToken) + { + foreach (var member in containingType.GetMembers()) { + var overriddenMember = member.OverriddenMember (); + if (overriddenMember != null) { + result.Remove (overriddenMember); } } } - + + public static bool IsOverridable (ISymbol member, INamedTypeSymbol containingType) + { + if (member.IsAbstract || member.IsVirtual || member.IsOverride) { + if (member.IsSealed) { + return false; + } + + if (!member.IsAccessibleWithin (containingType)) { + return false; + } + + switch (member.Kind) { + case SymbolKind.Event: + return true; + case SymbolKind.Method: + return ((IMethodSymbol)member).MethodKind == MethodKind.Ordinary; + case SymbolKind.Property: + return !((IPropertySymbol)member).IsWithEvents; + } + } + return false; + } + protected override IEnumerable<string> GenerateCode (List<object> includedMembers) { - var generator = Options.CreateCodeGenerator (); - generator.AutoIndent = false; - foreach (IMember member in includedMembers) - yield return generator.CreateMemberImplementation (Options.EnclosingType, Options.EnclosingPart, member, false).Code; + var currentType = Options.EnclosingType as INamedTypeSymbol; + + foreach (ISymbol member in includedMembers) { + yield return CSharpCodeGenerator.CreateOverridenMemberImplementation (Options.DocumentContext, Options.Editor, currentType, currentType.Locations.First (), member, false).Code; + } } } } diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/PartialGenerator.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/PartialGenerator.cs index fbde16fec2..03da34a8f6 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/PartialGenerator.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/PartialGenerator.cs @@ -23,12 +23,14 @@ // 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; + +using System.Linq; using System.Collections.Generic; using Gtk; -using ICSharpCode.NRefactory.TypeSystem; using MonoDevelop.Core; -using MonoDevelop.Ide.TypeSystem; +using System.Threading; +using ICSharpCode.NRefactory6.CSharp; +using MonoDevelop.CSharp.Refactoring; namespace MonoDevelop.CodeGeneration { @@ -76,21 +78,37 @@ namespace MonoDevelop.CodeGeneration if (type == null || Options.EnclosingMember != null) yield break; - foreach (var method in Options.EnclosingType.Methods) { - if (method.IsPartial && method.BodyRegion.IsEmpty) { + foreach (var method in Options.EnclosingType.GetMembers ().OfType<Microsoft.CodeAnalysis.IMethodSymbol> ()) { + if (method.MethodKind != Microsoft.CodeAnalysis.MethodKind.Ordinary) + continue; + if (IsEmptyPartialMethod(method)) { yield return method; } } } + static bool IsEmptyPartialMethod(Microsoft.CodeAnalysis.ISymbol member, CancellationToken cancellationToken = default(CancellationToken)) + { + var method = member as Microsoft.CodeAnalysis.IMethodSymbol; + if (method == null || method.IsDefinedInMetadata ()) + return false; + foreach (var r in method.DeclaringSyntaxReferences) { + var node = r.GetSyntax (cancellationToken) as Microsoft.CodeAnalysis.CSharp.Syntax.MethodDeclarationSyntax; + if (node == null) + continue; + if (node.Body != null || !node.Modifiers.Any(m => m.IsKind (Microsoft.CodeAnalysis.CSharp.SyntaxKind.PartialKeyword))) + return false; + } + + return true; + } + + protected override IEnumerable<string> GenerateCode (List<object> includedMembers) { - var generator = Options.CreateCodeGenerator (); - generator.AutoIndent = false; - foreach (IMethod member in includedMembers) - yield return generator.CreateMemberImplementation (Options.EnclosingType, Options.EnclosingPart, member, false).Code; + foreach (Microsoft.CodeAnalysis.IMethodSymbol member in includedMembers) + yield return CSharpCodeGenerator.CreatePartialMemberImplementation (Options.DocumentContext, Options.Editor, Options.EnclosingType, Options.EnclosingPart.GetLocation (), member, false).Code; } } } } - diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/PropertyGenerator.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/PropertyGenerator.cs index b8829e58e7..c658adc37b 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/PropertyGenerator.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/PropertyGenerator.cs @@ -25,16 +25,15 @@ // THE SOFTWARE. using System; - -using ICSharpCode.NRefactory.CSharp; -using MonoDevelop.Core; -using MonoDevelop.Ide.Gui; -using Gtk; +using System.Linq; using System.Collections.Generic; -using MonoDevelop.Refactoring; using System.Text; -using ICSharpCode.NRefactory.TypeSystem; -using System.Linq; +using MonoDevelop.Core; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Simplification; +using System.Threading.Tasks; namespace MonoDevelop.CodeGeneration { @@ -86,19 +85,19 @@ namespace MonoDevelop.CodeGeneration { if (Options.EnclosingType == null || Options.EnclosingMember != null) yield break; - foreach (IField field in Options.EnclosingType.Fields) { - if (field.IsSynthetic) + foreach (var field in Options.EnclosingType.GetMembers ().OfType<IFieldSymbol> ()) { + if (field.IsImplicitlyDeclared) continue; - var list = Options.EnclosingType.Fields.Where (f => f.Name == CreatePropertyName (field));; + var list = Options.EnclosingType.GetMembers ().OfType<IFieldSymbol> ().Where (f => f.Name == CreatePropertyName (field)); if (!list.Any ()) yield return field; } } - static string CreatePropertyName (IMember member) + static string CreatePropertyName (ISymbol member) { int i = 0; - while (i + 1 < member.Name.Length && member.Name[i] == '_') + while (i + 1 < member.Name.Length && member.Name [i] == '_') i++; if (i + 1 >= member.Name.Length) return char.ToUpper (member.Name [i]).ToString (); @@ -107,10 +106,49 @@ namespace MonoDevelop.CodeGeneration protected override IEnumerable<string> GenerateCode (List<object> includedMembers) { - var generator = Options.CreateCodeGenerator (); - generator.AutoIndent = false; - foreach (IField field in includedMembers) - yield return generator.CreateFieldEncapsulation (Options.EnclosingPart, field, CreatePropertyName (field), Accessibility.Public, ReadOnly); + foreach (IFieldSymbol field in includedMembers) { + var node = SyntaxFactory.PropertyDeclaration ( + CreateConstructorGenerator.ConvertType (field.Type), + CreatePropertyName (field) + ); + + node = node.AddAccessorListAccessors ( + SyntaxFactory.AccessorDeclaration ( + SyntaxKind.GetAccessorDeclaration, + SyntaxFactory.Block ( + SyntaxFactory.ReturnStatement ( + SyntaxFactory.MemberAccessExpression ( + SyntaxKind.SimpleMemberAccessExpression, + SyntaxFactory.ThisExpression (), + SyntaxFactory.IdentifierName (field.Name) + ) + ) + ) + ) + ); + if (!ReadOnly) { + node = node.AddAccessorListAccessors ( + SyntaxFactory.AccessorDeclaration ( + SyntaxKind.SetAccessorDeclaration, + SyntaxFactory.Block ( + SyntaxFactory.ExpressionStatement ( + SyntaxFactory.AssignmentExpression ( + SyntaxKind.SimpleAssignmentExpression, + SyntaxFactory.MemberAccessExpression ( + SyntaxKind.SimpleMemberAccessExpression, + SyntaxFactory.ThisExpression (), + SyntaxFactory.IdentifierName (field.Name) + ), + SyntaxFactory.IdentifierName ("value") + ) + ) + ) + ) + ); + } + yield return Options.OutputNode (node).Result; + } + } } } diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/RaiseEventMethodGenerator.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/RaiseEventMethodGenerator.cs index 76b0f7bd57..56db58f020 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/RaiseEventMethodGenerator.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/RaiseEventMethodGenerator.cs @@ -25,15 +25,17 @@ // THE SOFTWARE. using System; -using ICSharpCode.NRefactory.CSharp; using MonoDevelop.Core; using MonoDevelop.Ide.Gui; using Gtk; using System.Collections.Generic; using MonoDevelop.Refactoring; using System.Text; -using ICSharpCode.NRefactory.TypeSystem; using System.Linq; +using Microsoft.CodeAnalysis; +using ICSharpCode.NRefactory6.CSharp; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; namespace MonoDevelop.CodeGeneration { @@ -77,7 +79,7 @@ namespace MonoDevelop.CodeGeneration { } - static string GetEventMethodName (IMember member) + static string GetEventMethodName (ISymbol member) { return "On" + member.Name; } @@ -86,13 +88,13 @@ namespace MonoDevelop.CodeGeneration { if (Options.EnclosingType == null || Options.EnclosingMember != null) yield break; - foreach (var e in Options.EnclosingType.Events) { - if (e.IsSynthetic) + foreach (IEventSymbol e in Options.EnclosingType.GetMembers ().OfType<IEventSymbol> ()) { + if (e.IsImplicitlyDeclared) continue; - var invokeMethod = e.ReturnType.GetDelegateInvokeMethod (); + var invokeMethod = e.GetReturnType ().GetDelegateInvokeMethod (); if (invokeMethod == null) continue; - if (Options.EnclosingType.GetMethods (m => m.Name == GetEventMethodName (e)).Any ()) + if (Options.EnclosingType.GetMembers ().OfType<IMethodSymbol> ().Any (m => m.Name == GetEventMethodName (e))) continue; yield return e; } @@ -100,40 +102,89 @@ namespace MonoDevelop.CodeGeneration protected override IEnumerable<string> GenerateCode (List<object> includedMembers) { - foreach (IMember member in includedMembers) { - var invokeMethod = member.ReturnType.GetDelegateInvokeMethod (); + foreach (IEventSymbol member in includedMembers) { + var invokeMethod = member.GetReturnType ().GetDelegateInvokeMethod (); if (invokeMethod == null) continue; - var methodDeclaration = new MethodDeclaration () { - Name = GetEventMethodName (member), - ReturnType = new PrimitiveType ("void"), - Modifiers = Modifiers.Protected | Modifiers.Virtual, - Parameters = { - new ParameterDeclaration (Options.CreateShortType (invokeMethod.Parameters [1].Type), invokeMethod.Parameters [1].Name) - }, - Body = new BlockStatement () { - new VariableDeclarationStatement ( - new SimpleType ("var"),//Options.CreateShortType (member.ReturnType), - handlerName, - new MemberReferenceExpression (new ThisReferenceExpression (), member.Name) - ), - new IfElseStatement () { - Condition = new BinaryOperatorExpression (new IdentifierExpression (handlerName), BinaryOperatorType.InEquality, new PrimitiveExpression (null)), - TrueStatement = new ExpressionStatement (new InvocationExpression (new IdentifierExpression (handlerName)) { - Arguments = { - new ThisReferenceExpression (), - new IdentifierExpression (invokeMethod.Parameters [1].Name) - } - }) - } - } - }; + var node = SyntaxFactory.MethodDeclaration ( + SyntaxFactory.PredefinedType (SyntaxFactory.Token (SyntaxKind.VoidKeyword)), + SyntaxFactory.Identifier (GetEventMethodName (member)) + ); + + node = node.WithModifiers (SyntaxFactory.TokenList (SyntaxFactory.Token (SyntaxKind.ProtectedKeyword), SyntaxFactory.Token (SyntaxKind.VirtualKeyword))); + node = node.WithParameterList (SyntaxFactory.ParameterList (SyntaxFactory.SeparatedList<ParameterSyntax> (new [] { + SyntaxFactory.Parameter (SyntaxFactory.Identifier (invokeMethod.Parameters [1].Name)).WithType (SyntaxFactory.ParseTypeName (Options.CreateShortType (invokeMethod.Parameters [1].Type))) + }))); - yield return methodDeclaration.ToString (Options.FormattingOptions); + bool csharp6Style = true; + ; + if (csharp6Style) { + var expressionSyntax = SyntaxFactory.ParseExpression ("foo?.bar") as ConditionalAccessExpressionSyntax; + Console.WriteLine (expressionSyntax.OperatorToken.Kind ()); + Console.WriteLine (expressionSyntax.Expression.GetType ()); + Console.WriteLine (expressionSyntax.WhenNotNull.GetType ()); + node = node.WithBody (SyntaxFactory.Block ( + SyntaxFactory.ExpressionStatement ( + SyntaxFactory.InvocationExpression ( + SyntaxFactory.ConditionalAccessExpression ( + SyntaxFactory.MemberAccessExpression ( + SyntaxKind.SimpleMemberAccessExpression, + SyntaxFactory.ThisExpression (), + SyntaxFactory.IdentifierName (member.Name) + ), + SyntaxFactory.MemberBindingExpression (SyntaxFactory.IdentifierName ("Invoke")) + ), + SyntaxFactory.ArgumentList ( + SyntaxFactory.SeparatedList<ArgumentSyntax> (new [] { + SyntaxFactory.Argument (SyntaxFactory.ThisExpression ()), + SyntaxFactory.Argument (SyntaxFactory.IdentifierName (invokeMethod.Parameters [1].Name)) + }) + ) + ) + ) + )); + } else { + node = node.WithBody (SyntaxFactory.Block ( + SyntaxFactory.LocalDeclarationStatement ( + SyntaxFactory.VariableDeclaration ( + SyntaxFactory.ParseTypeName ("var"), + SyntaxFactory.SeparatedList<VariableDeclaratorSyntax> (new [] { + SyntaxFactory.VariableDeclarator (SyntaxFactory.Identifier (handlerName)).WithInitializer ( + SyntaxFactory.EqualsValueClause ( + SyntaxFactory.MemberAccessExpression ( + SyntaxKind.SimpleMemberAccessExpression, + SyntaxFactory.ThisExpression (), + SyntaxFactory.IdentifierName (member.Name) + ) + ) + ) + }) + ) + ), + SyntaxFactory.IfStatement ( + SyntaxFactory.BinaryExpression ( + SyntaxKind.NotEqualsExpression, + SyntaxFactory.IdentifierName (handlerName), + SyntaxFactory.ParseExpression ("null") + ), + SyntaxFactory.ExpressionStatement ( + SyntaxFactory.InvocationExpression ( + SyntaxFactory.IdentifierName (handlerName), + SyntaxFactory.ArgumentList ( + SyntaxFactory.SeparatedList<ArgumentSyntax> (new [] { + SyntaxFactory.Argument (SyntaxFactory.ThisExpression ()), + SyntaxFactory.Argument (SyntaxFactory.IdentifierName (invokeMethod.Parameters [1].Name)) + }) + ) + ) + ) + ) + )); + } + yield return Options.OutputNode (node).Result; } } } } -} - +}
\ No newline at end of file diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/ReadonlyPropertyGenerator.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/ReadonlyPropertyGenerator.cs index 928ddb1fab..d6b71bcc5f 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/ReadonlyPropertyGenerator.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/ReadonlyPropertyGenerator.cs @@ -25,14 +25,12 @@ // THE SOFTWARE. using System; -using ICSharpCode.NRefactory.CSharp; using MonoDevelop.Core; using MonoDevelop.Ide.Gui; using Gtk; using System.Collections.Generic; using MonoDevelop.Refactoring; using System.Text; -using ICSharpCode.NRefactory.TypeSystem; using System.Linq; namespace MonoDevelop.CodeGeneration @@ -70,4 +68,4 @@ namespace MonoDevelop.CodeGeneration return createProperty; } } -} +}
\ No newline at end of file diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/ToStringGenerator.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/ToStringGenerator.cs index 9d7913d8ae..516a34c15c 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/ToStringGenerator.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/ToStringGenerator.cs @@ -7,7 +7,7 @@ // Copyright (c) 2009 Novell, Inc (http://www.novell.com) // // Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal +// 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 @@ -25,75 +25,79 @@ // THE SOFTWARE. using System; -using MonoDevelop.Components; -using Gtk; -using MonoDevelop.Ide.Gui; using System.Collections.Generic; -using ICSharpCode.NRefactory.CSharp; using System.Text; using MonoDevelop.Core; -using MonoDevelop.Refactoring; -using ICSharpCode.NRefactory.TypeSystem; -using System.Linq; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Simplification; namespace MonoDevelop.CodeGeneration { class ToStringGenerator : ICodeGenerator { - public string Icon { - get { + public string Icon + { + get + { return "md-newmethod"; } } - - public string Text { - get { + + public string Text + { + get + { return GettextCatalog.GetString ("ToString() implementation"); } } - - public string GenerateDescription { - get { + + public string GenerateDescription + { + get + { return GettextCatalog.GetString ("Select members to be outputted."); } } - + public bool IsValid (CodeGenerationOptions options) { return new CreateToString (options).IsValid (); } - + public IGenerateAction InitalizeSelection (CodeGenerationOptions options, Gtk.TreeView treeView) { CreateToString createToString = new CreateToString (options); createToString.Initialize (treeView); return createToString; } - + class CreateToString : AbstractGenerateAction { public CreateToString (CodeGenerationOptions options) : base (options) { } - + protected override IEnumerable<object> GetValidMembers () { if (Options.EnclosingType == null || Options.EnclosingMember != null) yield break; - foreach (IField field in Options.EnclosingType.Fields) { - if (field.IsSynthetic) + + foreach (var field in Options.EnclosingType.GetMembers ().OfType<IFieldSymbol> ()) { + if (field.IsImplicitlyDeclared) continue; yield return field; } - foreach (IProperty property in Options.EnclosingType.Properties) { - if (property.IsSynthetic) + foreach (var property in Options.EnclosingType.GetMembers ().OfType<IPropertySymbol> ()) { + if (property.IsImplicitlyDeclared) continue; - if (property.CanGet) + if (property.GetMethod != null) yield return property; } } - + string GetFormatString (IEnumerable<object> includedMembers) { var format = new StringBuilder (); @@ -101,7 +105,7 @@ namespace MonoDevelop.CodeGeneration format.Append (Options.EnclosingType.Name); format.Append (": "); int i = 0; - foreach (IEntity member in includedMembers) { + foreach (ISymbol member in includedMembers) { if (i > 0) format.Append (", "); format.Append (member.Name); @@ -112,22 +116,37 @@ namespace MonoDevelop.CodeGeneration format.Append ("]"); return format.ToString (); } - + protected override IEnumerable<string> GenerateCode (List<object> includedMembers) { - yield return new MethodDeclaration () { - Name = "ToString", - ReturnType = new PrimitiveType ("string"), - Modifiers = Modifiers.Public | Modifiers.Override, - Body = new BlockStatement () { - new ReturnStatement ( - new InvocationExpression ( - new MemberReferenceExpression (new TypeReferenceExpression (new PrimitiveType ("string")), "Format"), - new Expression [] { new PrimitiveExpression (GetFormatString (includedMembers)) }.Concat (includedMembers.Select (member => new IdentifierExpression (((IEntity)member).Name))) + List<ArgumentSyntax> arguments = new List<ArgumentSyntax> (); + arguments.Add (SyntaxFactory.Argument (SyntaxFactory.LiteralExpression (SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal (GetFormatString (includedMembers))))); + foreach (ISymbol member in includedMembers) { + arguments.Add (SyntaxFactory.Argument (SyntaxFactory.IdentifierName (member.Name))); + } + var node = SyntaxFactory.MethodDeclaration ( + SyntaxFactory.List<AttributeListSyntax>(), + SyntaxFactory.TokenList (SyntaxFactory.Token (SyntaxKind.PublicKeyword), SyntaxFactory.Token (SyntaxKind.OverrideKeyword)), + SyntaxFactory.ParseTypeName ("string"), + null, + SyntaxFactory.Identifier ("ToString"), + null, + SyntaxFactory.ParameterList (), + SyntaxFactory.List<TypeParameterConstraintClauseSyntax>(), + SyntaxFactory.Block ( + SyntaxFactory.ReturnStatement ( + SyntaxFactory.InvocationExpression ( + SyntaxFactory.MemberAccessExpression ( + SyntaxKind.SimpleMemberAccessExpression, + SyntaxFactory.ParseExpression ("string"), + SyntaxFactory.IdentifierName ("Format") + ), + SyntaxFactory.ArgumentList (SyntaxFactory.SeparatedList<ArgumentSyntax> (arguments)) ) ) - } - }.ToString (Options.FormattingOptions); + ), + null); + yield return Options.OutputNode (node).Result; } } } diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/WriteLineGenerator.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/WriteLineGenerator.cs index 3a47fe1d5e..f150e59a13 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/WriteLineGenerator.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/WriteLineGenerator.cs @@ -25,15 +25,13 @@ // THE SOFTWARE. using System; -using MonoDevelop.Components; -using Gtk; -using MonoDevelop.Ide.Gui; using System.Collections.Generic; -using ICSharpCode.NRefactory.CSharp; using System.Text; using MonoDevelop.Core; -using MonoDevelop.Refactoring; -using ICSharpCode.NRefactory.TypeSystem; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Simplification; namespace MonoDevelop.CodeGeneration { @@ -77,52 +75,56 @@ namespace MonoDevelop.CodeGeneration protected override IEnumerable<object> GetValidMembers () { - if (Options == null || Options.EnclosingType == null || Options.EnclosingMember == null || Options.Document == null) + if (Options == null || Options.EnclosingType == null) yield break; - var editor = Options.Document.Editor; + if (Options.EnclosingMember == null) + yield break; + if (Options.DocumentContext == null) + yield break; + var editor = Options.Editor; if (editor == null) yield break; - // add local variables var state = Options.CurrentState; if (state != null) { - foreach (var v in state.LocalVariables) + foreach (var v in state.LookupSymbols (editor.CaretOffset).OfType<ILocalSymbol> ()) yield return v; } - + // add parameters - if (Options.EnclosingMember is IParameterizedMember) { - foreach (IParameter param in ((IParameterizedMember)Options.EnclosingMember).Parameters) + if (Options.EnclosingMember is IMethodSymbol) { + foreach (var param in ((IMethodSymbol)Options.EnclosingMember).Parameters) yield return param; } - + if (Options.EnclosingMember is IPropertySymbol) { + foreach (var param in ((IPropertySymbol)Options.EnclosingMember).Parameters) + yield return param; + } + // add type members - foreach (IField field in Options.EnclosingType.Fields) { - if (field.IsSynthetic) + foreach (IFieldSymbol field in Options.EnclosingType.GetMembers ().OfType<IFieldSymbol> ()) { + if (field.IsImplicitlyDeclared) continue; yield return field; } - foreach (IProperty property in Options.EnclosingType.Properties) { - if (property.IsSynthetic) + foreach (IPropertySymbol property in Options.EnclosingType.GetMembers ().OfType<IPropertySymbol> ()) { + if (property.IsImplicitlyDeclared) continue; - if (property.CanGet) + if (property.GetMethod != null) yield return property; } } static string GetName (object m) { - var e = m as IEntity; - if (e != null) - return e.Name; - return ((IVariable)m).Name; + return ((ISymbol)m).Name; } protected override IEnumerable<string> GenerateCode (List<object> includedMembers) { - StringBuilder format = new StringBuilder (); + var format = new StringBuilder (); int i = 0; foreach (var member in includedMembers) { if (i > 0) @@ -132,14 +134,26 @@ namespace MonoDevelop.CodeGeneration format.Append (i++); format.Append ("}"); } - - var consoleType = typeof (Console).ToTypeReference ().Resolve (Options.Document.Compilation.TypeResolveContext); - var invocationExpression = new InvocationExpression (new MemberReferenceExpression (new TypeReferenceExpression (Options.CreateShortType (consoleType)), "WriteLine")); - invocationExpression.Arguments.Add (new PrimitiveExpression (format.ToString ())); - foreach (var member in includedMembers) { - invocationExpression.Arguments.Add (new IdentifierExpression (GetName (member))); - } - yield return new ExpressionStatement (invocationExpression).ToString (Options.FormattingOptions); + + var arguments = new List<ArgumentSyntax> (); + arguments.Add (SyntaxFactory.Argument (SyntaxFactory.LiteralExpression (SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal (format.ToString ())))); + var node = + SyntaxFactory.ExpressionStatement ( + SyntaxFactory.InvocationExpression ( + SyntaxFactory.MemberAccessExpression (SyntaxKind.SimpleMemberAccessExpression, + SyntaxFactory.MemberAccessExpression (SyntaxKind.SimpleMemberAccessExpression, + SyntaxFactory.IdentifierName ("System"), + SyntaxFactory.IdentifierName ("Console") + ), + SyntaxFactory.IdentifierName ("WriteLine") + ), + SyntaxFactory.ArgumentList ( + SyntaxFactory.SeparatedList<ArgumentSyntax> (arguments) + ) + ) + ); + + yield return Options.OutputNode (node).Result; } } } |