[clang] e20a1e4 - clang-format-vs : Fix Unicode formatting
Hans Wennborg via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 27 00:59:12 PST 2019
Author: Hans Wennborg
Date: 2019-11-27T09:58:59+01:00
New Revision: e20a1e486e144c88188bc7b420885d5326b39088
URL: https://github.com/llvm/llvm-project/commit/e20a1e486e144c88188bc7b420885d5326b39088
DIFF: https://github.com/llvm/llvm-project/commit/e20a1e486e144c88188bc7b420885d5326b39088.diff
LOG: clang-format-vs : Fix Unicode formatting
Use UTF-8 for communication with clang-format and convert the
replacements offset/length to characters position/count.
Internally VisualStudio.Text.Editor.IWpfTextView use sequence of Unicode
characters encoded using UTF-16 and use characters position/count for
manipulating text.
Resolved "Error while running clang-format: Specified argument was out
of the range of valid values. Parameter name: replaceSpan".
Patch by empty2fill!
Differential revision: https://reviews.llvm.org/D70633
Added:
Modified:
clang/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs
Removed:
################################################################################
diff --git a/clang/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs b/clang/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs
index 7443405efad2..26a0af3b55b5 100644
--- a/clang/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs
+++ b/clang/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs
@@ -24,6 +24,7 @@
using System.Runtime.InteropServices;
using System.Xml.Linq;
using System.Linq;
+using System.Text;
namespace LLVM.ClangFormat
{
@@ -292,8 +293,7 @@ private void FormatSelection(OptionPageGrid options)
string text = view.TextBuffer.CurrentSnapshot.GetText();
int start = view.Selection.Start.Position.GetContainingLine().Start.Position;
int end = view.Selection.End.Position.GetContainingLine().End.Position;
- int length = end - start;
-
+
// clang-format doesn't support formatting a range that starts at the end
// of the file.
if (start >= text.Length && text.Length > 0)
@@ -301,7 +301,7 @@ private void FormatSelection(OptionPageGrid options)
string path = Vsix.GetDocumentParent(view);
string filePath = Vsix.GetDocumentPath(view);
- RunClangFormatAndApplyReplacements(text, start, length, path, filePath, options, view);
+ RunClangFormatAndApplyReplacements(text, start, end, path, filePath, options, view);
}
/// <summary>
@@ -336,11 +336,11 @@ private void FormatView(IWpfTextView view, OptionPageGrid options)
RunClangFormatAndApplyReplacements(text, 0, text.Length, path, filePath, options, view);
}
- private void RunClangFormatAndApplyReplacements(string text, int offset, int length, string path, string filePath, OptionPageGrid options, IWpfTextView view)
+ private void RunClangFormatAndApplyReplacements(string text, int start, int end, string path, string filePath, OptionPageGrid options, IWpfTextView view)
{
try
{
- string replacements = RunClangFormat(text, offset, length, path, filePath, options);
+ string replacements = RunClangFormat(text, start, end, path, filePath, options);
ApplyClangFormatReplacements(replacements, view);
}
catch (Exception e)
@@ -363,9 +363,9 @@ private void RunClangFormatAndApplyReplacements(string text, int offset, int len
/// <summary>
/// Runs the given text through clang-format and returns the replacements as XML.
///
- /// Formats the text range starting at offset of the given length.
+ /// Formats the text in range start and end.
/// </summary>
- private static string RunClangFormat(string text, int offset, int length, string path, string filePath, OptionPageGrid options)
+ private static string RunClangFormat(string text, int start, int end, string path, string filePath, OptionPageGrid options)
{
string vsixPath = Path.GetDirectoryName(
typeof(ClangFormatPackage).Assembly.Location);
@@ -373,6 +373,9 @@ private static string RunClangFormat(string text, int offset, int length, string
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.UseShellExecute = false;
process.StartInfo.FileName = vsixPath + "\\clang-format.exe";
+ char[] chars = text.ToCharArray();
+ int offset = Encoding.UTF8.GetByteCount(chars, 0, start);
+ int length = Encoding.UTF8.GetByteCount(chars, 0, end) - offset;
// Poor man's escaping - this will not work when quotes are already escaped
// in the input (but we don't need more).
string style = options.Style.Replace("\"", "\\\"");
@@ -413,10 +416,11 @@ private static string RunClangFormat(string text, int offset, int length, string
// 2. We write everything to the standard output - this cannot block, as clang-format
// reads the full standard input before analyzing it without writing anything to the
// standard output.
- process.StandardInput.Write(text);
+ StreamWriter utf8Writer = new StreamWriter(process.StandardInput.BaseStream, new UTF8Encoding(false));
+ utf8Writer.Write(text);
// 3. We notify clang-format that the input is done - after this point clang-format
// will start analyzing the input and eventually write the output.
- process.StandardInput.Close();
+ utf8Writer.Close();
// 4. We must read clang-format's output before waiting for it to exit; clang-format
// will close the channel by exiting.
string output = process.StandardOutput.ReadToEnd();
@@ -440,13 +444,18 @@ private static void ApplyClangFormatReplacements(string replacements, IWpfTextVi
if (replacements.Length == 0)
return;
+ string text = view.TextBuffer.CurrentSnapshot.GetText();
+ byte[] bytes = Encoding.UTF8.GetBytes(text);
+
var root = XElement.Parse(replacements);
var edit = view.TextBuffer.CreateEdit();
foreach (XElement replacement in root.Descendants("replacement"))
{
+ int offset = int.Parse(replacement.Attribute("offset").Value);
+ int length = int.Parse(replacement.Attribute("length").Value);
var span = new Span(
- int.Parse(replacement.Attribute("offset").Value),
- int.Parse(replacement.Attribute("length").Value));
+ Encoding.UTF8.GetCharCount(bytes, 0, offset),
+ Encoding.UTF8.GetCharCount(bytes, offset, length));
edit.Replace(span, replacement.Value);
}
edit.Apply();
More information about the cfe-commits
mailing list