From 5c3783f8e826c83f16262d884fba07f53fc7f3ce Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Thu, 1 May 2014 20:59:28 +0200 Subject: [PATCH] Fix #450: FormatItem completion and partial completion --- .../Project/CSharpBinding.csproj | 4 +- .../Completion/CSharpCompletionDataFactory.cs | 4 +- .../Project/Src/Completion/CompletionData.cs | 14 ++- .../Completion/FormatItemCompletionData.cs | 53 +++++++++++ .../Src/Completion/PartialCompletionData.cs | 93 +++++++++++++++++++ 5 files changed, 164 insertions(+), 4 deletions(-) create mode 100644 src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/FormatItemCompletionData.cs create mode 100644 src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/PartialCompletionData.cs diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj b/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj index 01c4eeb7f2..2762300961 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj @@ -79,17 +79,19 @@ + + CSharpSemanticHighlighter.cs - + diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpCompletionDataFactory.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpCompletionDataFactory.cs index f9342c40f0..8fbfc7e3f7 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpCompletionDataFactory.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpCompletionDataFactory.cs @@ -136,7 +136,7 @@ namespace CSharpBinding.Completion ICompletionData ICompletionDataFactory.CreateNewPartialCompletionData(int declarationBegin, IUnresolvedTypeDefinition type, IUnresolvedMember m) { - return new CompletionData("TODO: partial completion"); + return new PartialCompletionData(declarationBegin, m.Resolve(contextAtCaret.CurrentTypeResolveContext), contextAtCaret); } IEnumerable ICompletionDataFactory.CreateCodeTemplateCompletionData() @@ -162,7 +162,7 @@ namespace CSharpBinding.Completion ICompletionData ICompletionDataFactory.CreateFormatItemCompletionData(string format, string description, object example) { - return new CompletionData("TODO: format item completion"); + return new FormatItemCompletionData(format, description, example); } ICompletionData ICompletionDataFactory.CreateXmlDocCompletionData(string tag, string description, string tagInsertionText) diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CompletionData.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CompletionData.cs index 507310c1cf..7c04f56b9f 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CompletionData.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CompletionData.cs @@ -87,8 +87,20 @@ namespace CSharpBinding.Completion context.EndOffset = context.StartOffset + this.CompletionText.Length; } + object fancyContent; + object IFancyCompletionItem.Content { - get { return this.DisplayText; } + get { + if (fancyContent == null) { + fancyContent = CreateFancyContent(); + } + return fancyContent; + } + } + + protected virtual object CreateFancyContent() + { + return DisplayText; } object fancyDescription; diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/FormatItemCompletionData.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/FormatItemCompletionData.cs new file mode 100644 index 0000000000..f0881fe996 --- /dev/null +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/FormatItemCompletionData.cs @@ -0,0 +1,53 @@ +// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team +// +// 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 System.Windows; +using System.Windows.Controls; +using System.Windows.Documents; +using ICSharpCode.SharpDevelop.Editor.CodeCompletion; + +namespace CSharpBinding.Completion +{ + class FormatItemCompletionData : CompletionData + { + readonly string description; + readonly string format; + + public FormatItemCompletionData(string format, string description, object example) + : base(format) + { + this.description = description; + this.format = format; + this.DisplayText = format + " - " + description; + try { + this.Description = string.Format("{0:" + format + "}", example); + } catch (FormatException) { + } + } + + protected override object CreateFancyContent() + { + TextBlock textBlock = new TextBlock(); + textBlock.Inlines.Add(new Run(format)); + textBlock.Inlines.Add(new Run(" - " + description) { Foreground = SystemColors.GrayTextBrush }); + return textBlock; + } + } +} diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/PartialCompletionData.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/PartialCompletionData.cs new file mode 100644 index 0000000000..7cd6f37a43 --- /dev/null +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/PartialCompletionData.cs @@ -0,0 +1,93 @@ +// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team +// +// 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 System.IO; +using System.Linq; +using ICSharpCode.NRefactory.CSharp; +using ICSharpCode.NRefactory.CSharp.Refactoring; +using ICSharpCode.NRefactory.CSharp.Resolver; +using ICSharpCode.NRefactory.TypeSystem; +using ICSharpCode.SharpDevelop; +using ICSharpCode.SharpDevelop.Editor.CodeCompletion; +using CSharpBinding.FormattingStrategy; + +namespace CSharpBinding.Completion +{ + /// + /// Item for 'partial' completion. + /// + class PartialCompletionData : EntityCompletionData + { + protected readonly int declarationBegin; + protected readonly CSharpResolver contextAtCaret; + + public PartialCompletionData(int declarationBegin, IMember m, CSharpResolver contextAtCaret) + : base(m) + { + this.declarationBegin = declarationBegin; + this.contextAtCaret = contextAtCaret; + var ambience = new CSharpAmbience(); + ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList | ConversionFlags.ShowParameterList | ConversionFlags.ShowParameterNames; + this.CompletionText = ambience.ConvertSymbol(m); + } + + public override void Complete(CompletionContext context) + { + if (declarationBegin > context.StartOffset) { + base.Complete(context); + return; + } + + TypeSystemAstBuilder b = new TypeSystemAstBuilder(contextAtCaret); + b.GenerateBody = true; + + var entityDeclaration = b.ConvertEntity(this.Entity); + entityDeclaration.Modifiers &= ~Modifiers.VisibilityMask; // remove visiblity + entityDeclaration.Modifiers |= Modifiers.Partial; + + var document = context.Editor.Document; + StringWriter w = new StringWriter(); + var formattingOptions = CSharpFormattingOptionsPersistence.GetProjectOptions(contextAtCaret.Compilation.GetProject()); + var segmentDict = SegmentTrackingOutputFormatter.WriteNode( + w, entityDeclaration, formattingOptions.OptionsContainer.GetEffectiveOptions(), context.Editor.Options); + + using (document.OpenUndoGroup()) { + string newText = w.ToString().TrimEnd(); + document.Replace(declarationBegin, context.EndOffset - declarationBegin, newText); + var throwStatement = entityDeclaration.Descendants.FirstOrDefault(n => n is ThrowStatement); + if (throwStatement != null) { + var segment = segmentDict[throwStatement]; + context.Editor.Select(declarationBegin + segment.Offset, segment.Length); + } + CSharpFormatterHelper.Format(context.Editor, declarationBegin, newText.Length, formattingOptions.OptionsContainer); + } + } + + IEnumerable ParametersToExpressions(IEntity entity) + { + foreach (var p in ((IParameterizedMember)entity).Parameters) { + if (p.IsRef || p.IsOut) + yield return new DirectionExpression(p.IsOut ? FieldDirection.Out : FieldDirection.Ref, new IdentifierExpression(p.Name)); + else + yield return new IdentifierExpression(p.Name); + } + } + } +}