public GetTextBetween ( Mono.TextEditor.DocumentLocation start, Mono.TextEditor.DocumentLocation end ) : string | ||
start | Mono.TextEditor.DocumentLocation | |
end | Mono.TextEditor.DocumentLocation | |
return | string |
public string FormatText (CSharpFormattingPolicy policy, TextStylePolicy textPolicy, string mimeType, string input, int startOffset, int endOffset) { var data = new TextEditorData (); data.Document.SuppressHighlightUpdate = true; data.Document.MimeType = mimeType; data.Document.FileName = "toformat.cs"; if (textPolicy != null) { data.Options.TabsToSpaces = textPolicy.TabsToSpaces; data.Options.TabSize = textPolicy.TabWidth; data.Options.IndentationSize = textPolicy.IndentWidth; data.Options.IndentStyle = textPolicy.RemoveTrailingWhitespace ? IndentStyle.Virtual : IndentStyle.Smart; } data.Text = input; // System.Console.WriteLine ("-----"); // System.Console.WriteLine (data.Text.Replace (" ", ".").Replace ("\t", "->")); // System.Console.WriteLine ("-----"); var parser = new CSharpParser (); var compilationUnit = parser.Parse (data); bool hadErrors = parser.HasErrors; if (hadErrors) { // foreach (var e in parser.ErrorReportPrinter.Errors) // Console.WriteLine (e.Message); return input.Substring (startOffset, Math.Max (0, Math.Min (endOffset, input.Length) - startOffset)); } var originalVersion = data.Document.Version; var textEditorOptions = data.CreateNRefactoryTextEditorOptions (); var formattingVisitor = new ICSharpCode.NRefactory.CSharp.CSharpFormatter ( policy.CreateOptions (), textEditorOptions ) { FormattingMode = FormattingMode.Intrusive }; var changes = formattingVisitor.AnalyzeFormatting (data.Document, compilationUnit); try { changes.ApplyChanges (startOffset, endOffset - startOffset); } catch (Exception e) { LoggingService.LogError ("Error in code formatter", e); return input.Substring (startOffset, Math.Max (0, Math.Min (endOffset, input.Length) - startOffset)); } // check if the formatter has produced errors parser = new CSharpParser (); parser.Parse (data); if (parser.HasErrors) { LoggingService.LogError ("C# formatter produced source code errors. See console for output."); return input.Substring (startOffset, Math.Max (0, Math.Min (endOffset, input.Length) - startOffset)); } var currentVersion = data.Document.Version; string result = data.GetTextBetween (startOffset, originalVersion.MoveOffsetTo (currentVersion, endOffset, ICSharpCode.NRefactory.Editor.AnchorMovementType.Default)); data.Dispose (); return result; }
public string GetExpression(Mono.TextEditor.TextEditorData data, int offset) { if (offset < 0) { return(""); } var doc = IdeApp.Workbench.ActiveDocument; if (doc == null) { return(""); } var loc = RefactoringService.GetCorrectResolveLocation(doc, data.OffsetToLocation(offset)); var unit = doc.ParsedDocument.GetAst <SyntaxTree> (); var parsedFile = doc.ParsedDocument.ParsedFile as CSharpUnresolvedFile; var node = unit.GetNodeAt <Expression> (loc.Line, loc.Column); if (unit == null || parsedFile == null || node == null) { return(""); } return(data.GetTextBetween(node.StartLocation, node.EndLocation)); }
public static string GetWordBeforeCaret (TextEditorData editor) { int offset = editor.Caret.Offset; int start = FindPrevWordStart (editor, offset); return editor.GetTextBetween (start, offset); }
ExpressionResult MakeResult (TextEditorData editor, int startOffset, int endOffset, IEnumerable<ExpressionContext> contexts) { if (endOffset < startOffset) { int tmp = startOffset; startOffset = endOffset; endOffset = tmp; } var start = editor.Document.OffsetToLocation (startOffset); var end = editor.Document.OffsetToLocation (endOffset); return new ExpressionResult (editor.GetTextBetween (startOffset, endOffset), new DomRegion (start.Line, start.Column, end.Line, end.Column), contexts); }
public override string FormatText (PolicyContainer policyParent, IEnumerable<string> mimeTypeChain, string input, int startOffset, int endOffset) { var data = new TextEditorData (); data.Document.SuppressHighlightUpdate = true; data.Document.MimeType = mimeTypeChain.First (); data.Document.FileName = "toformat.cs"; var textPolicy = policyParent.Get<TextStylePolicy> (mimeTypeChain); data.Options.TabsToSpaces = textPolicy.TabsToSpaces; data.Options.TabSize = textPolicy.TabWidth; data.Options.OverrideDocumentEolMarker = true; data.Options.DefaultEolMarker = textPolicy.GetEolMarker (); data.Text = input; // System.Console.WriteLine ("TABS:" + textPolicy.TabsToSpaces); endOffset += CorrectFormatting (data, startOffset, endOffset); /* System.Console.WriteLine ("-----"); System.Console.WriteLine (data.Text.Replace (" ", ".").Replace ("\t", "->")); System.Console.WriteLine ("-----");*/ var compilationUnit = new MonoDevelop.CSharp.Parser.CSharpParser ().Parse (data); var policy = policyParent.Get<CSharpFormattingPolicy> (mimeTypeChain); var domSpacingVisitor = new AstSpacingVisitor (policy, data) { AutoAcceptChanges = false, }; compilationUnit.AcceptVisitor (domSpacingVisitor, null); var domIndentationVisitor = new AstIndentationVisitor (policy, data) { AutoAcceptChanges = false, }; compilationUnit.AcceptVisitor (domIndentationVisitor, null); var changes = new List<Change> (); changes.AddRange (domSpacingVisitor.Changes. Concat (domIndentationVisitor.Changes). Where (c => c is TextReplaceChange && (startOffset <= ((TextReplaceChange)c).Offset && ((TextReplaceChange)c).Offset < endOffset))); RefactoringService.AcceptChanges (null, null, changes); int end = endOffset; foreach (TextReplaceChange c in changes) { end -= c.RemovedChars; if (c.InsertedText != null) end += c.InsertedText.Length; } /* System.Console.WriteLine ("-----"); System.Console.WriteLine (data.Text.Replace (" ", "^").Replace ("\t", "->")); System.Console.WriteLine ("-----");*/ string result = data.GetTextBetween (startOffset, Math.Min (data.Length, end)); data.Dispose (); return result; }
protected override string InternalFormat (PolicyContainer policyParent, string mimeType, string input, int startOffset, int endOffset) { IEnumerable<string> types = DesktopService.GetMimeTypeInheritanceChain (CSharpFormatter.MimeType); TextEditorData data = new TextEditorData (); data.Text = input; data.Document.MimeType = mimeType; data.Document.SuppressHighlightUpdate = true; data.Document.FileName = "toformat.cs"; var textPolicy = policyParent != null ? policyParent.Get<TextStylePolicy> (types) : MonoDevelop.Projects.Policies.PolicyService.GetDefaultPolicy<TextStylePolicy> (types); data.Options.TabsToSpaces = textPolicy.TabsToSpaces; data.Options.TabSize = textPolicy.TabWidth; data.Options.OverrideDocumentEolMarker = true; data.Options.DefaultEolMarker = textPolicy.GetEolMarker (); endOffset += CorrectFormatting (data, startOffset, endOffset); CSharp.Dom.CompilationUnit compilationUnit = new MonoDevelop.CSharp.Parser.CSharpParser ().Parse (data); CSharpFormattingPolicy policy = policyParent != null ? policyParent.Get<CSharpFormattingPolicy> (types) : MonoDevelop.Projects.Policies.PolicyService.GetDefaultPolicy<CSharpFormattingPolicy> (types); DomSpacingVisitor domSpacingVisitor = new DomSpacingVisitor (policy, data); domSpacingVisitor.AutoAcceptChanges = false; compilationUnit.AcceptVisitor (domSpacingVisitor, null); DomIndentationVisitor domIndentationVisitor = new DomIndentationVisitor (policy, data); domIndentationVisitor.AutoAcceptChanges = false; compilationUnit.AcceptVisitor (domIndentationVisitor, null); List<Change> changes = new List<Change> (); changes.AddRange (domSpacingVisitor.Changes. Concat (domIndentationVisitor.Changes). Where (c => c is TextReplaceChange && (startOffset <= ((TextReplaceChange)c).Offset && ((TextReplaceChange)c).Offset < endOffset))); RefactoringService.AcceptChanges (null, null, changes); int end = endOffset; foreach (TextReplaceChange c in changes) { end -= c.RemovedChars; if (c.InsertedText != null) end += c.InsertedText.Length; } string result = data.GetTextBetween (startOffset, end); return result; }
public string BuildDocumentString (DocumentInfo info, TextEditorData data, List<LocalDocumentInfo.OffsetInfo> offsetInfos = null, bool buildExpressions = false) { var document = new StringBuilder (); WriteUsings (info.Imports, document); foreach (var node in info.XScriptBlocks) { var start = data.Document.LocationToOffset (node.Region.Begin.Line, node.Region.Begin.Column) + 2; var end = data.Document.LocationToOffset (node.Region.End.Line, node.Region.End.Column) - 2; if (offsetInfos != null) offsetInfos.Add (new LocalDocumentInfo.OffsetInfo (start, document.Length, end - start)); document.AppendLine (data.Document.GetTextBetween (start, end)); } if (buildExpressions) { WriteClassDeclaration (info, document); document.AppendLine ("{"); document.AppendLine ("void Generated ()"); document.AppendLine ("{"); //Console.WriteLine ("start:" + location.BeginLine +"/" +location.BeginColumn); foreach (var node in info.XExpressions) { bool isBlock = node is WebFormsRenderBlock; var start = data.Document.LocationToOffset (node.Region.Begin.Line, node.Region.Begin.Column) + 2; var end = data.Document.LocationToOffset (node.Region.End.Line, node.Region.End.Column) - 2; if (!isBlock) { document.Append ("WriteLine ("); start += 1; } string expr = data.GetTextBetween (start, end); if (offsetInfos != null) { offsetInfos.Add (new LocalDocumentInfo.OffsetInfo (start, document.Length, expr.Length)); } document.Append (expr); if (!isBlock) document.Append (");"); } document.AppendLine ("}"); document.AppendLine ("}"); } return document.ToString (); }
public static bool GuessSemicolonInsertionOffset (TextEditorData data, ISegment curLine, int caretOffset, out int outOffset) { int lastNonWsOffset = caretOffset; char lastNonWsChar = '\0'; outOffset = caretOffset; int max = curLine.EndOffset; int end = caretOffset; while (end > 1 && char.IsWhiteSpace (data.GetCharAt (end))) end--; int end2 = end; while (end2 > 1 && char.IsLetter (data.GetCharAt (end2 - 1))) end2--; if (end != end2) { string token = data.GetTextBetween (end2, end + 1); // guess property context if (token == "get" || token == "set") return false; } var offset = curLine.Offset; string lineText = data.GetTextAt (caretOffset, max - caretOffset); var lexer = new CSharpCompletionEngineBase.MiniLexer (lineText); lexer.Parse ((ch, i) => { if (lexer.IsInSingleComment || lexer.IsInMultiLineComment) return true; if (ch == '}' && lexer.IsFistNonWs && !IsSemicolonalreadyPlaced (data, caretOffset)) { lastNonWsChar = ';'; return true; } if (!char.IsWhiteSpace (ch)) { lastNonWsOffset = caretOffset + i; lastNonWsChar = ch; } return false; }); // if the line ends with ';' the line end is not the correct place for a new semicolon. if (lastNonWsChar == ';') return false; outOffset = lastNonWsOffset; return true; }
static string GetIdentifierName (TextEditorData editor, Identifier id, out int startOffset) { startOffset = editor.LocationToOffset (id.StartLocation.Line, id.StartLocation.Column); return editor.GetTextBetween (id.StartLocation, id.EndLocation); }
public static string ResolveExpression (TextEditorData editor, ResolveResult result, AstNode node, out int startOffset) { //Console.WriteLine ("result is a {0}", result.GetType ().Name); startOffset = -1; if (result is NamespaceResolveResult || result is ConversionResolveResult || result is ConstantResolveResult || result is ForEachResolveResult || result is TypeIsResolveResult || result is TypeOfResolveResult || result is ErrorResolveResult) return null; if (result.IsCompileTimeConstant) return null; startOffset = editor.LocationToOffset (node.StartLocation.Line, node.StartLocation.Column); if (result is InvocationResolveResult) { var ir = (InvocationResolveResult) result; if (ir.Member.Name == ".ctor") { // if the user is hovering over something like "new Abc (...)", we want to show them type information for Abc return ir.Member.DeclaringType.FullName; } // do not support general method invocation for tooltips because it could cause side-effects return null; } else if (result is LocalResolveResult) { if (node is ParameterDeclaration) { // user is hovering over a method parameter, but we don't want to include the parameter type var param = (ParameterDeclaration) node; return GetIdentifierName (editor, param.NameToken, out startOffset); } if (node is VariableInitializer) { // user is hovering over something like "int fubar = 5;", but we don't want the expression to include the " = 5" var variable = (VariableInitializer) node; return GetIdentifierName (editor, variable.NameToken, out startOffset); } } else if (result is MemberResolveResult) { var mr = (MemberResolveResult) result; if (node is PropertyDeclaration) { var prop = (PropertyDeclaration) node; var name = GetIdentifierName (editor, prop.NameToken, out startOffset); // if the property is static, then we want to return "Full.TypeName.Property" if (prop.Modifiers.HasFlag (Modifiers.Static)) return mr.Member.DeclaringType.FullName + "." + name; // otherwise we want to return "this.Property" so that it won't conflict with anything else in the local scope return "this." + name; } if (node is FieldDeclaration) { var field = (FieldDeclaration) node; var name = GetIdentifierName (editor, field.NameToken, out startOffset); // if the field is static, then we want to return "Full.TypeName.Field" if (field.Modifiers.HasFlag (Modifiers.Static)) return mr.Member.DeclaringType.FullName + "." + name; // otherwise we want to return "this.Field" so that it won't conflict with anything else in the local scope return "this." + name; } if (node is VariableInitializer) { // user is hovering over a field declaration that includes initialization var variable = (VariableInitializer) node; var name = GetIdentifierName (editor, variable.NameToken, out startOffset); // walk up the AST to find the FieldDeclaration so that we can determine if it is static or not var field = variable.GetParent<FieldDeclaration> (); // if the field is static, then we want to return "Full.TypeName.Field" if (field.Modifiers.HasFlag (Modifiers.Static)) return mr.Member.DeclaringType.FullName + "." + name; // otherwise we want to return "this.Field" so that it won't conflict with anything else in the local scope return "this." + name; } if (node is NamedExpression) { // user is hovering over 'Property' in an expression like: var fubar = new Fubar () { Property = baz }; var variable = node.GetParent<VariableInitializer> (); if (variable != null) { var variableName = GetIdentifierName (editor, variable.NameToken, out startOffset); var name = GetIdentifierName (editor, ((NamedExpression) node).NameToken, out startOffset); return variableName + "." + name; } } } else if (result is TypeResolveResult) { return ((TypeResolveResult) result).Type.FullName; } return editor.GetTextBetween (node.StartLocation, node.EndLocation); }
static string GetLocalExpression (TextEditorData editor, LocalResolveResult lr, DomRegion expressionRegion) { var start = new DocumentLocation (expressionRegion.BeginLine, expressionRegion.BeginColumn); var end = new DocumentLocation (expressionRegion.EndLine, expressionRegion.EndColumn); // In a setter, the 'value' variable will have a begin line/column of 0,0 which is an undefined offset if (lr.Variable.Region.BeginLine != 0 && lr.Variable.Region.BeginColumn != 0) { // Use the start and end offsets of the variable region so that we get the "@" in variable names like "@class" start = new DocumentLocation (lr.Variable.Region.BeginLine, lr.Variable.Region.BeginColumn); end = new DocumentLocation (lr.Variable.Region.EndLine, lr.Variable.Region.EndColumn); } string expression = editor.GetTextBetween (start, end).Trim (); // Note: When the LocalResolveResult is a parameter, the Variable.Region includes the type if (lr.IsParameter) { int index = IndexOfLastWhiteSpace (expression); if (index != -1) expression = expression.Substring (index + 1); } return expression; }
internal static bool TryResolveExpression (TextEditorData editor, ResolveResult res, DomRegion expressionRegion, out string expression) { expression = null; //Console.WriteLine ("res is a {0}", res.GetType ().Name); if (expressionRegion.IsEmpty) return false; if (res is NamespaceResolveResult || res is ConversionResolveResult || res is ConstantResolveResult || res is ForEachResolveResult || res is TypeIsResolveResult || res is TypeOfResolveResult || res is ErrorResolveResult) return false; if (res.IsCompileTimeConstant) return false; var start = new DocumentLocation (expressionRegion.BeginLine, expressionRegion.BeginColumn); var end = new DocumentLocation (expressionRegion.EndLine, expressionRegion.EndColumn); if (res is LocalResolveResult) { expression = GetLocalExpression (editor, (LocalResolveResult) res, expressionRegion); } else if (res is InvocationResolveResult) { var ir = (InvocationResolveResult) res; if (ir.Member.Name != ".ctor") return false; expression = ir.Member.DeclaringType.FullName; } else if (res is MemberResolveResult) { expression = GetMemberExpression (editor, (MemberResolveResult) res, expressionRegion); } else if (res is NamedArgumentResolveResult) { expression = editor.GetTextBetween (start, end); } else if (res is ThisResolveResult) { expression = editor.GetTextBetween (start, end); } else if (res is TypeResolveResult) { expression = editor.GetTextBetween (start, end); } else { return false; } return true; }
static string GetMemberExpression (TextEditorData editor, MemberResolveResult mr, DomRegion expressionRegion) { string expression = null; string member = null; if (mr.Member != null) { if (mr.Member is IProperty) { // Visual Studio will evaluate Properties if you hover over their definitions... var prop = (IProperty) mr.Member; if (prop.CanGet) { if (prop.IsStatic) expression = prop.FullName; else member = prop.Name; } else { return null; } } else if (mr.Member is IField) { var field = (IField) mr.Member; if (field.IsStatic) expression = field.FullName; else member = field.Name; } else { return null; } } else { return null; } if (expression == null) { if (mr.TargetResult != null) { var targetRegion = mr.TargetResult.GetDefinitionRegion (); if (mr.TargetResult is LocalResolveResult) { expression = GetLocalExpression (editor, (LocalResolveResult) mr.TargetResult, targetRegion); } else if (mr.TargetResult is MemberResolveResult) { expression = GetMemberExpression (editor, (MemberResolveResult) mr.TargetResult, targetRegion); } else if (mr.TargetResult is InitializedObjectResolveResult) { return null; } else if (mr.TargetResult is ThisResolveResult) { return "this." + member; } else if (!targetRegion.IsEmpty) { var start = new DocumentLocation (targetRegion.BeginLine, targetRegion.BeginColumn); var end = new DocumentLocation (targetRegion.EndLine, targetRegion.EndColumn); expression = editor.GetTextBetween (start, end).Trim (); } if (expression == null) { var start = new DocumentLocation (expressionRegion.BeginLine, expressionRegion.BeginColumn); var end = new DocumentLocation (expressionRegion.EndLine, expressionRegion.EndColumn); return editor.GetTextBetween (start, end).Trim (); } } if (!string.IsNullOrEmpty (expression)) expression += "." + member; else expression = member; } return expression; }
public static bool GuessSemicolonInsertionOffset (TextEditorData data, IDocumentLine curLine, int caretOffset, out int outOffset) { int lastNonWsOffset = caretOffset; char lastNonWsChar = '\0'; outOffset = caretOffset; int max = curLine.EndOffset; // if (caretOffset - 2 >= curLine.Offset && data.Document.GetCharAt (caretOffset - 2) == ')' && !IsSemicolonalreadyPlaced (data, caretOffset)) // return false; int end = caretOffset; while (end > 1 && char.IsWhiteSpace (data.GetCharAt (end))) end--; int end2 = end; while (end2 > 1 && char.IsLetter(data.GetCharAt (end2 - 1))) end2--; if (end != end2) { string token = data.GetTextBetween (end2, end + 1); // guess property context if (token == "get" || token == "set") return false; } bool isInString = false , isInChar= false , isVerbatimString= false; bool isInLineComment = false , isInBlockComment= false; bool firstChar = true; for (int pos = caretOffset; pos < max; pos++) { if (pos == caretOffset) { if (isInString || isInChar || isVerbatimString || isInLineComment || isInBlockComment) { outOffset = pos; return true; } } char ch = data.Document.GetCharAt (pos); switch (ch) { case '}': if (firstChar && !IsSemicolonalreadyPlaced (data, caretOffset)) return false; break; case '/': if (isInBlockComment) { if (pos > 0 && data.Document.GetCharAt (pos - 1) == '*') isInBlockComment = false; } else if (!isInString && !isInChar && pos + 1 < max) { char nextChar = data.Document.GetCharAt (pos + 1); if (nextChar == '/') { outOffset = lastNonWsOffset; return true; } if (!isInLineComment && nextChar == '*') { outOffset = lastNonWsOffset; return true; } } break; case '\\': if (isInChar || (isInString && !isVerbatimString)) pos++; break; case '@': if (!(isInString || isInChar || isInLineComment || isInBlockComment) && pos + 1 < max && data.Document.GetCharAt (pos + 1) == '"') { isInString = true; isVerbatimString = true; pos++; } break; case '"': if (!(isInChar || isInLineComment || isInBlockComment)) { if (isInString && isVerbatimString && pos + 1 < max && data.Document.GetCharAt (pos + 1) == '"') { pos++; } else { isInString = !isInString; isVerbatimString = false; } } break; case '\'': if (!(isInString || isInLineComment || isInBlockComment)) isInChar = !isInChar; break; } if (!char.IsWhiteSpace (ch)) { firstChar = false; lastNonWsOffset = pos; lastNonWsChar = ch; } } // if the line ends with ';' the line end is not the correct place for a new semicolon. if (lastNonWsChar == ';') return false; outOffset = lastNonWsOffset; return true; }
public LocalDocumentInfo BuildLocalDocument (DocumentInfo info, TextEditorData data, string expressionText, string textAfterCaret, bool isExpression) { var sb = new StringBuilder (); WriteUsings (info.Imports, sb); WriteClassDeclaration (info, sb); sb.AppendLine ("{"); var result = new LocalDocumentInfo (); if (isExpression) { sb.AppendLine ("void Generated ()"); sb.AppendLine ("{"); //Console.WriteLine ("start:" + location.BeginLine +"/" +location.BeginColumn); foreach (var node in info.XExpressions) { bool isBlock = node is WebFormsRenderBlock; if (node.Region.Begin.Line > data.Caret.Line || node.Region.Begin.Line == data.Caret.Line && node.Region.Begin.Column > data.Caret.Column - 5) continue; //Console.WriteLine ("take xprt:" + expressions.Key.BeginLine +"/" +expressions.Key.BeginColumn); var start = data.Document.LocationToOffset (node.Region.Begin.Line, node.Region.Begin.Column) + 2; var end = data.Document.LocationToOffset (node.Region.End.Line, node.Region.End.Column) - 2; if (!isBlock) { sb.Append ("WriteLine ("); start += 1; } string expr = data.GetTextBetween (start, end); result.AddTextPosition (start, end, expr.Length); sb.Append (expr); if (!isBlock) sb.Append (");"); } } sb.Append (expressionText); int caretPosition = sb.Length; sb.Append (textAfterCaret); sb.AppendLine (); sb.AppendLine ("}"); sb.AppendLine ("}"); result.LocalDocument = sb.ToString (); result.CaretPosition = caretPosition; result.OriginalCaretPosition = data.Caret.Offset; result.ParsedLocalDocument = Parse (info.AspNetDocument.FileName, sb.ToString ()); return result; }
public string FormatText (CSharpFormattingPolicy policy, TextStylePolicy textPolicy, string mimeType, string input, int startOffset, int endOffset) { var data = new TextEditorData (); data.Document.SuppressHighlightUpdate = true; data.Document.MimeType = mimeType; data.Document.FileName = "toformat.cs"; if (textPolicy != null) { data.Options.TabsToSpaces = textPolicy.TabsToSpaces; data.Options.TabSize = textPolicy.TabWidth; data.Options.DefaultEolMarker = textPolicy.GetEolMarker (); } data.Options.OverrideDocumentEolMarker = true; data.Text = input; // System.Console.WriteLine ("-----"); // System.Console.WriteLine (data.Text.Replace (" ", ".").Replace ("\t", "->")); // System.Console.WriteLine ("-----"); var parser = new CSharpParser (); var compilationUnit = parser.Parse (data); bool hadErrors = parser.HasErrors; if (hadErrors) { // foreach (var e in parser.ErrorReportPrinter.Errors) // Console.WriteLine (e.Message); return input.Substring (startOffset, Math.Max (0, Math.Min (endOffset, input.Length) - startOffset)); } var adapter = new TextEditorDataAdapter (data); var formattingVisitor = new ICSharpCode.NRefactory.CSharp.AstFormattingVisitor (policy.CreateOptions (), adapter, new FormattingActionFactory (data)) { HadErrors = hadErrors }; compilationUnit.AcceptVisitor (formattingVisitor, null); var changes = new List<ICSharpCode.NRefactory.CSharp.Refactoring.Action> (); changes.AddRange (formattingVisitor.Changes. Where (c => (startOffset <= c.Offset && c.Offset < endOffset))); MDRefactoringContext.MdScript.RunActions (changes, null); // check if the formatter has produced errors parser = new CSharpParser (); parser.Parse (data); if (parser.HasErrors) { LoggingService.LogError ("C# formatter produced source code errors. See console for output."); Console.WriteLine (data.Text); return input.Substring (startOffset, Math.Max (0, Math.Min (endOffset, input.Length) - startOffset)); } int end = endOffset; foreach (TextReplaceAction c in changes) { end -= c.RemovedChars; if (c.InsertedText != null) end += c.InsertedText.Length; } /* System.Console.WriteLine ("-----"); System.Console.WriteLine (data.Text.Replace (" ", "^").Replace ("\t", "->")); System.Console.WriteLine ("-----");*/ string result = data.GetTextBetween (startOffset, Math.Min (data.Length, end)); data.Dispose (); return result; }
// // TODO - It seems the support for properties varies // depending on the ECMA script requested version. // Fix the code here. // public static int GuessSemicolonInsertionOffset(TextEditorData data, DocumentLine currLine, int caretOffset) { int lastNonWsOffset = caretOffset; char lastNonWsChar = '\0'; int max = currLine.EndOffset; // PORT NOTE: Honestly, this looks like a hack. if (caretOffset - 2 >= currLine.Offset && data.Document.GetCharAt (caretOffset - 2) == ')') return caretOffset; int end = caretOffset; while (end > 1 && Char.IsWhiteSpace (data.GetCharAt (end))) end--; int end2 = end; while (end2 > 1 && Char.IsLetter (data.GetCharAt (end2 - 1))) end2--; if (end != end2) { string token = data.GetTextBetween (end2, end + 1); // guess property context if (token == "get" || token == "set") return caretOffset; } bool isInDQuotedString = false, isInSQuotedString = false; bool isInLineComment = false , isInBlockComment = false; // Compare the first check against the original one. for (int pos = caretOffset; pos < max; pos++) { if (pos == caretOffset) { if (isInDQuotedString || isInSQuotedString || isInLineComment || isInBlockComment) return pos; } char ch = data.Document.GetCharAt (pos); switch (ch) { case '/': if (isInBlockComment) { if (pos > 0 && data.Document.GetCharAt (pos - 1) == '*') isInBlockComment = false; } else if (!(isInDQuotedString || isInSQuotedString) && pos + 1 < max) { char nextChar = data.Document.GetCharAt (pos + 1); if (nextChar == '/') { isInLineComment = true; return lastNonWsOffset; } if (!isInLineComment && nextChar == '*') { isInBlockComment = true; return lastNonWsOffset; } } break; case '\\': if (isInSQuotedString || isInDQuotedString) pos++; break; case '"': if (!(isInSQuotedString || isInLineComment || isInBlockComment)) { if (isInDQuotedString && pos + 1 < max && data.Document.GetCharAt (pos + 1) == '"') pos++; else isInDQuotedString = !isInDQuotedString; } break; case '\'': if (!(isInDQuotedString || isInLineComment || isInBlockComment)) isInSQuotedString = !isInSQuotedString; break; } if (!Char.IsWhiteSpace (ch)) { lastNonWsOffset = pos; lastNonWsChar = ch; } } // if the line ends with ';' the line end is not the correct place for a new semicolon. if (lastNonWsChar == ';') return caretOffset; return lastNonWsOffset; }