| Newsgroups |
gmane.comp.gnome.mono.patches |
| Message-ID |
<00000141932d2694-43a3fee1-e7d4-4484-ae29-cc210e433981-000000@email.amazonses.com> |
Branch: refs/heads/master
Home: https://github.com/mono/monodevelop
Compare: https://github.com/mono/monodevelop/compare/8c9f2f175e78...a4333995eab8
Commit: a4333995eab854b1166426738c410686bed8218e
Author: Mike Krüger <[email protected]> (mkrueger)
Date: 2013-10-07 13:46:34 GMT
URL: https://github.com/mono/monodevelop/commit/a4333995eab854b1166426738c410686bed8218e
[CSharpBinding] Changed protocol support.
Changed paths:
M main/src/addins/CSharpBinding/CSharpBinding.addin.xml
M main/src/addins/CSharpBinding/CSharpBinding.csproj
M main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/ExportCodeGenerator.cs
M main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring/CSharpCodeGenerationService.cs
Added paths:
A main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring.CodeIssues/Issues/MissingRequiredProtocolMemberIssue.cs
Modified: main/src/addins/CSharpBinding/CSharpBinding.addin.xml
===================================================================
@@ -231,7 +231,8 @@
<Class class = "MonoDevelop.CodeGeneration.ReadonlyPropertyGenerator" />
<Class class = "MonoDevelop.CodeGeneration.PropertyGenerator" />
<Class class = "MonoDevelop.CodeGeneration.ImplementInterfaceMembersGenerator" />
- <Class class = "MonoDevelop.CodeGeneration.ExportCodeGenerator" />
+ <Class class = "MonoDevelop.CodeGeneration.RequiredProtocolMemberGenerator" />
+ <Class class = "MonoDevelop.CodeGeneration.OptionalProtocolMemberGenerator" />
<Class class = "MonoDevelop.CodeGeneration.PartialGenerator" />
<Class class = "MonoDevelop.CodeGeneration.OverrideMembersGenerator" />
<Class class = "MonoDevelop.CodeGeneration.ToStringGenerator" />
Modified: main/src/addins/CSharpBinding/CSharpBinding.csproj
===================================================================
@@ -22,8 +22,8 @@
<Execution clr-version="Net_2_0" />
</Execution>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
- <GenerateDocumentation>true</GenerateDocumentation>
<NoWarn>1591;1573</NoWarn>
+ <DocumentationFile>..\..\..\build\AddIns\BackendBindings\MonoDevelop.CSharpBinding.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@@ -37,8 +37,8 @@
</Execution>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<DebugSymbols>true</DebugSymbols>
- <GenerateDocumentation>true</GenerateDocumentation>
<NoWarn>1591;1573</NoWarn>
+ <DocumentationFile>..\..\..\build\AddIns\BackendBindings\MonoDevelop.CSharpBinding.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\core\MonoDevelop.Core\MonoDevelop.Core.csproj">
@@ -324,6 +324,7 @@
<Compile Include="MonoDevelop.CSharp.Refactoring.CodeIssues\Issues\MonoTODOIssue.cs" />
<Compile Include="MonoDevelop.CSharp.Refactoring\CSharpCodeGenerationService.cs" />
<Compile Include="MonoDevelop.CSharp.CodeGeneration\ExportCodeGenerator.cs" />
+ <Compile Include="MonoDevelop.CSharp.Refactoring.CodeIssues\Issues\MissingRequiredProtocolMemberIssue.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Makefile.am" />
Modified: main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/ExportCodeGenerator.cs
===================================================================
@@ -33,22 +33,24 @@
using ICSharpCode.NRefactory.CSharp.Refactoring;
using MonoDevelop.CSharp.Refactoring.CodeActions;
using MonoDevelop.CSharp.Refactoring;
+using MonoDevelop.CodeGeneration;
namespace MonoDevelop.CodeGeneration
{
- class ExportCodeGenerator : ICodeGenerator
+ abstract class BaseExportCodeGenerator : ICodeGenerator
{
+ public abstract bool IsValidMember (IMember member);
#region ICodeGenerator implementation
bool ICodeGenerator.IsValid (CodeGenerationOptions options)
{
- return new ExportMethods (options).IsValid ();
+ return new ExportMethods (this, options).IsValid ();
}
IGenerateAction ICodeGenerator.InitalizeSelection (CodeGenerationOptions options, TreeView treeView)
{
- var exportMethods = new ExportMethods (options);
+ var exportMethods = new ExportMethods (this, options);
exportMethods.Initialize (treeView);
return exportMethods;
}
@@ -59,24 +61,81 @@ IGenerateAction ICodeGenerator.InitalizeSelection (CodeGenerationOptions options
}
}
- string ICodeGenerator.Text {
- get {
- return GettextCatalog.GetString ("Implement protocol methods");
+ public abstract string Text {
+ get;
+ }
+
+ public abstract string GenerateDescription {
+ get;
+ }
+
+ #endregion
+
+ public static bool HasProtocolAttribute (IType type, out string name)
+ {
+ foreach (var attrs in type.GetDefinition ().GetAttributes ()) {
+ if (attrs.AttributeType.Name == "ProtocolAttribute" && attrs.AttributeType.Namespace == "MonoTouch.Foundation") {
+ 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;
}
- string ICodeGenerator.GenerateDescription {
- get {
- return GettextCatalog.GetString ("Select methods to implement");
+ public static ICSharpCode.NRefactory.CSharp.Attribute GenerateExportAttribute (RefactoringContext ctx, IMember member)
+ {
+ if (member == null)
+ return null;
+ 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");
}
+
+ var attr = new ICSharpCode.NRefactory.CSharp.Attribute {
+ Type = astType,
+ };
+ var exportAttribute = member.GetAttribute (new FullTypeName (new TopLevelTypeName ("MonoTouch.Foundation", "ExportAttribute")));
+ if (exportAttribute == null || exportAttribute.PositionalArguments.Count == 0)
+ return null;
+ attr.Arguments.Add (new PrimitiveExpression (exportAttribute.PositionalArguments.First ().ConstantValue));
+ return attr;
+
+ }
+
+ 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;
}
- #endregion
class ExportMethods : AbstractGenerateAction
{
- public ExportMethods (CodeGenerationOptions options) : base (options)
+ readonly BaseExportCodeGenerator cg;
+
+ public ExportMethods (BaseExportCodeGenerator cg, CodeGenerationOptions options) : base (options)
{
+ this.cg = cg;
}
@@ -87,16 +146,24 @@ protected override IEnumerable<object> GetValidMembers ()
yield break;
foreach (var t in type.DirectBaseTypes) {
string name;
- if (!CSharpCodeGenerationService.HasProtocolAttribute (t, out name))
+ if (!HasProtocolAttribute (t, out name))
continue;
var protocolType = Options.Document.Compilation.FindType (new FullTypeName (new TopLevelTypeName (t.Namespace, name)));
if (protocolType == null)
break;
foreach (var member in protocolType.GetMethods (null, GetMemberOptions.IgnoreInheritedMembers)) {
+ if (member.ImplementedInterfaceMembers.Any ())
+ continue;
+ if (!cg.IsValidMember (member))
+ continue;
if (member.Attributes.Any (a => a.AttributeType.Name == "ExportAttribute" && a.AttributeType.Namespace == "MonoTouch.Foundation"))
yield return member;
}
foreach (var member in protocolType.GetProperties (null, GetMemberOptions.IgnoreInheritedMembers)) {
+ if (member.ImplementedInterfaceMembers.Any ())
+ continue;
+ if (!cg.IsValidMember (member))
+ continue;
if (member.CanGet && member.Getter.Attributes.Any (a => a.AttributeType.Name == "ExportAttribute" && a.AttributeType.Namespace == "MonoTouch.Foundation") ||
member.CanSet && member.Setter.Attributes.Any (a => a.AttributeType.Name == "ExportAttribute" && a.AttributeType.Namespace == "MonoTouch.Foundation"))
yield return member;
@@ -123,7 +190,7 @@ protected override IEnumerable<string> GenerateCode (List<object> includedMember
method.Modifiers &= ~Modifiers.Abstract;
method.Attributes.Add (new AttributeSection {
- Attributes = { CSharpCodeGenerationService.GenerateExportAttribute (ctx, member) }
+ Attributes = { GenerateExportAttribute (ctx, member) }
});
yield return method.ToString ();
continue;
@@ -148,7 +215,7 @@ protected override IEnumerable<string> GenerateCode (List<object> includedMember
};
property.Getter.Attributes.Add (new AttributeSection {
- Attributes = { CSharpCodeGenerationService.GenerateExportAttribute (ctx, p.Getter) }
+ Attributes = { GenerateExportAttribute (ctx, p.Getter) }
});
}
if (p.CanSet) {
@@ -157,7 +224,7 @@ protected override IEnumerable<string> GenerateCode (List<object> includedMember
};
property.Setter.Attributes.Add (new AttributeSection {
- Attributes = { CSharpCodeGenerationService.GenerateExportAttribute (ctx, p.Setter) }
+ Attributes = { GenerateExportAttribute (ctx, p.Setter) }
});
}
yield return property.ToString ();
@@ -167,5 +234,46 @@ protected override IEnumerable<string> GenerateCode (List<object> includedMember
}
}
}
+
+ class OptionalProtocolMemberGenerator : BaseExportCodeGenerator
+ {
+ public override string Text {
+ get {
+ return GettextCatalog.GetString ("Implement protocol members");
+ }
+ }
+
+ public override string GenerateDescription {
+ get {
+ return GettextCatalog.GetString ("Select protocol members to implement");
+ }
+ }
+
+ public override bool IsValidMember (IMember member)
+ {
+ return !member.IsAbstract;
+ }
+ }
+
+ class RequiredProtocolMemberGenerator : BaseExportCodeGenerator
+ {
+ public override string Text {
+ get {
+ return GettextCatalog.GetString ("Implement required protocol members");
+ }
+ }
+
+ public override string GenerateDescription {
+ get {
+ return GettextCatalog.GetString ("Select protocol members to implement");
+ }
+ }
+
+ public override bool IsValidMember (IMember member)
+ {
+ return member.IsAbstract;
+ }
+ }
+
}
Added: main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring.CodeIssues/Issues/MissingRequiredProtocolMemberIssue.cs
===================================================================
@@ -0,0 +1,164 @@
+//
+// MissingRequiredProtocolMemberIssue.cs
+//
+// Author:
+// Mike Krüger <[email protected]>
+//
+// Copyright (c) 2013 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 System;
+using MonoDevelop.CSharp.Refactoring.CodeActions;
+using MonoDevelop.CodeIssues;
+using ICSharpCode.NRefactory.CSharp;
+using System.Collections.Generic;
+using ICSharpCode.NRefactory.Semantics;
+using ICSharpCode.NRefactory.CSharp.Resolver;
+using ICSharpCode.NRefactory.TypeSystem;
+using System.Linq;
+using MonoDevelop.CodeGeneration;
+using ICSharpCode.NRefactory.CSharp.Refactoring;
+
+namespace MonoDevelop.CSharp.Refactoring.CodeIssues
+{
+ public class MissingRequiredProtocolMemberIssue : MonoDevelop.CodeIssues.CodeIssueProvider
+ {
+ public override bool HasSubIssues {
+ get {
+ return false;
+ }
+ }
+
+ public MissingRequiredProtocolMemberIssue ()
+ {
+ this.Title = "Missing protocol member issue";
+ this.Description = "Missing protocol member issue";
+ this.Category = IssueCategories.Notifications;
+ this.SetMimeType ("text/x-csharp");
+ this.IsEnabledByDefault = true;
+ this.SetSeverity (ICSharpCode.NRefactory.Refactoring.Severity.Warning);
+ this.SetIsEnabled (true);
+ }
+
+ public override IEnumerable<MonoDevelop.CodeIssues.CodeIssue> GetIssues (object refactoringContext, System.Threading.CancellationToken cancellationToken)
+ {
+ var context = refactoringContext as MDRefactoringContext;
+ if (context == null || context.IsInvalid || context.RootNode == null || context.ParsedDocument.HasErrors)
+ return new MonoDevelop.CodeIssues.CodeIssue[0];
+ var visitor = new MissingRequiredProtocolMemberIssueVisitor (context);
+ context.RootNode.AcceptVisitor (visitor);
+ return visitor.Issues;
+ }
+
+ class MissingRequiredProtocolMemberIssueVisitor : DepthFirstAstVisitor
+ {
+ readonly MDRefactoringContext ctx;
+ public readonly List<MonoDevelop.CodeIssues.CodeIssue> Issues = new List<MonoDevelop.CodeIssues.CodeIssue> ();
+
+ public MissingRequiredProtocolMemberIssueVisitor (MDRefactoringContext ctx)
+ {
+ this.ctx = ctx;
+ }
+
+ bool FindProtocolMember (IType type, IMember member)
+ {
+ foreach (var t in type.GetMembers ()) {
+ if (SignatureComparer.Ordinal.Equals (t, member))
+ return true;
+ }
+ return false;
+ }
+
+ void AddIssue (IType type, AstType bt, IType t)
+ {
+ Issues.Add (
+ new MonoDevelop.CodeIssues.CodeIssue (
+ ICSharpCode.NRefactory.Refactoring.IssueMarker.WavedLine,
+ "Some required protocol members are missing",
+ new DomRegion (bt.StartLocation, bt.EndLocation),
+ "MissingRequiredProtocolMemberIssue",
+ new MonoDevelop.CodeActions.CodeAction[] {
+ new MonoDevelop.CodeActions.DefaultCodeAction (
+ "Implement required protocol members",
+ (ctx, s) => {
+ var service = (ICSharpCode.NRefactory.CSharp.CodeGenerationService)ctx.GetService (typeof (ICSharpCode.NRefactory.CSharp.CodeGenerationService));
+ var implementedNodes = GetAllProtocolMembers (t).Where (member => !FindProtocolMember (type, member)).Select (pm => (AstNode)service.GenerateMemberImplementation (ctx, pm, false)).ToList ();
+ s.InsertWithCursor ("Add missing protocol members", Script.InsertPosition.End, implementedNodes);
+ }
+ )
+ }
+ ));
+ }
+
+ public IEnumerable<IMember> GetAllProtocolMembers (IType t)
+ {
+ string name;
+ if (!BaseExportCodeGenerator.HasProtocolAttribute (t, out name))
+ yield break;
+
+ var protocolType = ctx.Compilation.FindType (new FullTypeName (new TopLevelTypeName (t.Namespace, name)));
+ if (protocolType == null)
+ yield break;
+
+ foreach (var member in protocolType.GetMethods (null, GetMemberOptions.IgnoreInheritedMembers)) {
+ if (member.ImplementedInterfaceMembers.Any ())
+ continue;
+ if (member.Attributes.Any (a => a.AttributeType.Name == "ExportAttribute" && a.AttributeType.Namespace == "MonoTouch.Foundation")) {
+ yield return member;
+ }
+ }
+
+ foreach (var member in protocolType.GetProperties (null, GetMemberOptions.IgnoreInheritedMembers)) {
+ if (member.ImplementedInterfaceMembers.Any ())
+ continue;
+ if (member.CanGet && member.Getter.Attributes.Any (a => a.AttributeType.Name == "ExportAttribute" && a.AttributeType.Namespace == "MonoTouch.Foundation") ||
+ member.CanSet && member.Setter.Attributes.Any (a => a.AttributeType.Name == "ExportAttribute" && a.AttributeType.Namespace == "MonoTouch.Foundation")) {
+ yield return member;
+ }
+ }
+ }
+
+ public override void VisitTypeDeclaration (TypeDeclaration typeDeclaration)
+ {
+ base.VisitTypeDeclaration (typeDeclaration);
+ var type = ctx.Resolve (typeDeclaration).Type;
+
+ foreach (var bt in typeDeclaration.BaseTypes) {
+ var t = ctx.Resolve (bt).Type;
+
+ foreach (var member in GetAllProtocolMembers (t)) {
+ if (!member.IsAbstract)
+ continue;
+ if (!FindProtocolMember (type, member)) {
+ AddIssue (type, bt, t);
+ return;
+ }
+ }
+ }
+ }
+
+ public override void VisitBlockStatement (BlockStatement blockStatement)
+ {
+ // SKIP
+ }
+ }
+ }
+}
+
Modified: main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring/CSharpCodeGenerationService.cs
===================================================================
@@ -35,104 +35,9 @@ namespace MonoDevelop.CSharp.Refactoring
{
public class CSharpCodeGenerationService : DefaultCodeGenerationService
{
- public static bool HasProtocolAttribute (IType type, out string name)
- {
- foreach (var attrs in type.GetDefinition ().GetAttributes ()) {
- if (attrs.AttributeType.Name == "ProtocolAttribute" && attrs.AttributeType.Namespace == "MonoTouch.Foundation") {
- 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 ICSharpCode.NRefactory.CSharp.Attribute GenerateExportAttribute (RefactoringContext ctx, IMember member)
- {
- if (member == null)
- return null;
- 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");
- }
-
- var attr = new ICSharpCode.NRefactory.CSharp.Attribute {
- Type = astType,
- };
- var exportAttribute = member.GetAttribute (new FullTypeName (new TopLevelTypeName ("MonoTouch.Foundation", "ExportAttribute")));
- if (exportAttribute == null || exportAttribute.PositionalArguments.Count == 0)
- return null;
- attr.Arguments.Add (new PrimitiveExpression (exportAttribute.PositionalArguments.First ().ConstantValue));
- return attr;
-
- }
-
- 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;
- }
-
public override EntityDeclaration GenerateMemberImplementation (RefactoringContext context, IMember member, bool explicitImplementation)
{
var result = base.GenerateMemberImplementation (context, member, explicitImplementation);
- string name;
- if (HasProtocolAttribute (member.DeclaringType, out name)) {
- var protocolType = context.Compilation.FindType (new FullTypeName (new TopLevelTypeName (member.DeclaringType.Namespace, name)));
- if (protocolType != null) {
- var property = result as PropertyDeclaration;
- var protocolMember = GetProtocolMember (context, protocolType, member);
- if (protocolMember != null) {
- if (property != null) {
- var ppm = (IProperty)protocolMember;
- if (ppm.CanGet) {
- var attr = CSharpCodeGenerationService.GenerateExportAttribute (context, ppm.Getter);
- if (attr != null) {
- property.Getter.Attributes.Add (new AttributeSection {
- Attributes = { attr }
- });
- }
- }
-
- if (ppm.CanSet) {
- var attr = CSharpCodeGenerationService.GenerateExportAttribute (context, ppm.Setter);
- if (attr != null) {
- property.Getter.Attributes.Add (new AttributeSection {
- Attributes = { attr }
- });
- }
- }
- } else {
- var attribute = CSharpCodeGenerationService.GenerateExportAttribute (context, protocolMember);
- if (attribute != null) {
- result.Attributes.Add (new AttributeSection {
- Attributes = { attribute }
- });
- }
- }
- }
- }
- }
-
if (CSharpCodeGenerator.IsMonoTouchModelMember (member)) {
var m = result as MethodDeclaration;
if (m != null) {
@@ -155,4 +60,3 @@ public override EntityDeclaration GenerateMemberImplementation (RefactoringConte
}
}
}
-
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches