#develop (short for SharpDevelop) is a free IDE for .NET programming languages.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

110 lines
4.0 KiB

// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Linq;
using CSharpBinding.Parser;
using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.CSharp.Refactoring;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Parser;
namespace CSharpBinding.Refactoring
{
/// <summary>
/// Refactoring change script.
/// </summary>
sealed class SDScript : DocumentScript
{
readonly ITextEditor editor;
readonly TextSegmentCollection<TextSegment> textSegmentCollection;
readonly SDRefactoringContext context;
public SDScript(ITextEditor editor, SDRefactoringContext context) : base(editor.Document, new CSharpFormattingOptions(), context.TextEditorOptions)
{
this.editor = editor;
this.context = context;
this.textSegmentCollection = new TextSegmentCollection<TextSegment>((TextDocument)editor.Document);
}
protected override ISegment CreateTrackedSegment(int offset, int length)
{
var segment = new TextSegment();
segment.StartOffset = offset;
segment.Length = length;
textSegmentCollection.Add(segment);
return segment;
}
public override void FormatText(AstNode node)
{
var parseInfo = SD.ParserService.Parse(editor.FileName, editor.Document) as CSharpFullParseInformation;
if (parseInfo != null) {
//var startLocation = editor.Document.GetLocation(offset);
//var endLocation = editor.Document.GetLocation(offset + length);
//var node = parseInfo.CompilationUnit.GetNodeContaining(startLocation, endLocation);
var formatter = new AstFormattingVisitor(new CSharpFormattingOptions(), editor.Document, context.TextEditorOptions);
parseInfo.CompilationUnit.AcceptVisitor(formatter);
var segment = GetSegment(node);
formatter.ApplyChanges(segment.Offset, segment.Length);
} else {
base.FormatText(node);
}
}
public override void Select(AstNode node)
{
var segment = GetSegment(node);
int startOffset = segment.Offset;
int endOffset = segment.EndOffset;
// If the area to select includes a newline (e.g. node is a statement),
// exclude that newline from the selection.
if (endOffset > startOffset && editor.Document.GetLineByOffset(endOffset).Offset == endOffset) {
endOffset = editor.Document.GetLineByOffset(endOffset).PreviousLine.EndOffset;
}
editor.Select(startOffset, endOffset - startOffset);
}
public override void Link(params AstNode[] nodes)
{
// TODO
}
public override void InsertWithCursor(string operation, AstNode node, InsertPosition defaultPosition)
{
AstNode contextNode = context.GetNode();
if (contextNode == null)
return;
var resolver = context.GetResolverStateBefore(contextNode);
InsertWithCursor(operation, node, resolver.CurrentTypeDefinition);
}
public override void InsertWithCursor(string operation, AstNode node, ITypeDefinition parentType)
{
if (parentType == null)
return;
var currentPart = parentType.Parts.FirstOrDefault(p => p.ParsedFile != null && string.Equals(p.ParsedFile.FileName, editor.FileName, StringComparison.OrdinalIgnoreCase));
if (currentPart != null) {
var insertionPoints = InsertionPoint.GetInsertionPoints(editor.Document, currentPart);
if (insertionPoints.Count > 0) {
int indentLevel = GetIndentLevelAt(editor.Document.GetOffset(insertionPoints[0].Location));
var output = OutputNode(indentLevel, node);
insertionPoints[0].Insert(editor.Document, output.Text);
}
}
}
public override void Dispose()
{
base.Dispose();
// refresh parse information so that the issue can disappear immediately
SD.ParserService.ParseAsync(editor.FileName, editor.Document).FireAndForget();
}
}
}