@@ -19,7 +19,7 @@ namespace AsyncToSyncCodeRoundtripSynchroniserMonitor
19
19
static class AsyncToSyncConverter
20
20
{
21
21
//TODO config file
22
- public static readonly List<KVP> Replacements = new List<KVP>()
22
+ public static readonly List<KVP> CS_Replacements = new List<KVP>()
23
23
{
24
24
//NB! VS may put the /*--await--*/ on a separate line therefore need handling for various space types after /*--await--*/
25
25
//TODO!: ensure that await starts at word boundary
@@ -41,15 +41,18 @@ static class AsyncToSyncConverter
41
41
new KVP("(async\r", "(/*--async--*/\r"),
42
42
new KVP("(async\n", "(/*--async--*/\n"),
43
43
44
+ new KVP(@", Task ", @", /*--Task--*/Action "), //method argument type
45
+ new KVP(@"(Task ", @"(/*--Task--*/Action "), //method argument type
46
+ new KVP(@", Task<T> ", @", /*--Task<T>--*/Func<T> "), //method argument type
47
+ new KVP(@"(Task<T> ", @"(/*--Task<T>--*/Func<T> "), //method argument type
44
48
new KVP(@" Task ", @" /*--Task--*/void "), //method return type
45
- new KVP(@"Task ", @"/*--Task--*/Action "), //method argument type
46
- new KVP(@"Task<T> ", @"/*--Task<T>--*/Func<T> "), //method argument type
47
49
48
50
new KVP(@").Wait();", @")/*--.Wait()--*/;"),
49
51
//new KVP("Task.Delay", "/*--Task.Delay--*/System.Threading.Thread.Sleep"), //this needs special regex in sync to async direction
50
52
new KVP(@"Task.FromResult", @"/*--Task.FromResult--*/"),
51
53
new KVP(@"Task.WhenAll", @"/*--Task.WhenAll--*/"),
52
- new KVP(@" AsyncLock", @" /*--AsyncLock--*/object"),
54
+ new KVP(@" AsyncLock ", @" /*--AsyncLock--*/object "), //TODO!!! add handling for \t \r \n
55
+ new KVP(@" AsyncLock(", @" /*--AsyncLock--*/object("),
53
56
54
57
new KVP(@"#define ASYNC", @"#define NOASYNC"),
55
58
};
@@ -59,47 +62,96 @@ static class AsyncToSyncConverter
59
62
//private static readonly string AsyncLockReplaceRegexReplacement = @"$1/*--AsyncLock--*/object";
60
63
61
64
62
- private static readonly Regex TaskDelayReplaceRegex = new Regex(@"Task[.]Delay", RegexOptions.Singleline | RegexOptions.Compiled);
63
- private const string TaskDelayReplaceRegexReplacement = @"/*--Task.Delay--*/System.Threading.Thread.Sleep";
65
+ private static readonly Regex CS_TaskDelayReplaceRegex = new Regex(@"Task[.]Delay", RegexOptions.Singleline | RegexOptions.Compiled);
66
+ private const string CS_TaskDelayReplaceRegexReplacement = @"/*--Task.Delay--*/System.Threading.Thread.Sleep";
64
67
65
68
66
- private static readonly Regex TaskReplaceRegex = new Regex(@"(\s+)(async\s+)?Task<([^(]+)>(\s+)", RegexOptions.Singleline | RegexOptions.Compiled);
67
- private const string TaskReplaceRegexReplacement = @"$1/*--$2Task<--*/$3/*-->--*/$4";
69
+ private static readonly Regex CS_TaskReplaceRegex = new Regex(@"(\s+)(async\s+)?Task<([^(]+)>(\s+)", RegexOptions.Singleline | RegexOptions.Compiled);
70
+ private const string CS_TaskReplaceRegexReplacement = @"$1/*--$2Task<--*/$3/*-->--*/$4";
68
71
69
72
70
- private static readonly Regex AsyncLockReplaceRegex = new Regex(@"using([^(]*)[(]await(\s+[^(]+)[.]LockAsync[(][)][)]", RegexOptions.Singleline | RegexOptions.Compiled);
71
- private const string AsyncLockReplaceRegexReplacement = @"/*--using--*/lock$1(/*--await--*/ $2/*--.Lock A s y n c()--*/)";
73
+ private static readonly Regex CS_AsyncLockReplaceRegex = new Regex(@"using([^(]*)[(]await(\s+[^(]+)[.]LockAsync[(][)][)]", RegexOptions.Singleline | RegexOptions.Compiled);
74
+ private const string CS_AsyncLockReplaceRegexReplacement = @"/*--using--*/lock$1(/*--await--*/ $2/*--.Lock A s y n c()--*/)";
75
+
76
+
77
+ private static readonly Regex CS_FuncTaskReplaceRegex = new Regex(@"([\s,(]+)Func<Task<([^=)]+)>>", RegexOptions.Singleline | RegexOptions.Compiled);
78
+ private const string CS_FuncTaskReplaceRegexReplacement = @"$1Func</*--Task<--*/$2/*-->--*/>";
79
+
80
+
81
+
82
+
83
+ public static readonly List<KVP> PY_Replacements = new List<KVP>()
84
+ {
85
+ //TODO!: ensure that matches start at word boundary
86
+
87
+ new KVP(@"ASYNC = True", @"ASYNC = False"),
88
+ new KVP(@"NOASYNC = False", @"NOASYNC = True"),
89
+
90
+ new KVP(" aiofiles.open", " open"),
91
+ new KVP("\taiofiles.open", "\topen"),
92
+ new KVP("\raiofiles.open", "\ropen"),
93
+ new KVP("\naiofiles.open", "\nopen"),
94
+
95
+ new KVP(" open", " io.open"),
96
+ new KVP("\topen", "\tio.open"),
97
+ new KVP("\ropen", "\rio.open"),
98
+ new KVP("\nopen", "\nio.open"),
99
+ };
100
+
101
+
102
+ private static readonly Regex PY_AwaitReplaceRegex = new Regex(@"(\n\r|\r\n|\n)(\s*)await(\s+)", RegexOptions.Singleline | RegexOptions.Compiled);
103
+ private const string PY_AwaitReplaceRegexReplacement = @"$1#--$2await$3--$1";
104
+
105
+
106
+ private static readonly Regex PY_Await2ReplaceRegex = new Regex(@"=(\s*)await(\s+)", RegexOptions.Singleline | RegexOptions.Compiled);
107
+ private const string PY_Await2ReplaceRegexReplacement = @"=#--$1await$2--$1";
108
+
109
+
110
+ private static readonly Regex PY_AsyncReplaceRegex = new Regex(@"(\n\r|\r\n|\n)(\s*)async(\s+)", RegexOptions.Singleline | RegexOptions.Compiled);
111
+ private const string PY_AsyncRegexReplacement = @"$1#--$2async$3--$2";
72
112
73
113
74
- private static readonly Regex FuncTaskReplaceRegex = new Regex(@"([\s,(]+)Func<Task<([^=)]+)>>", RegexOptions.Singleline | RegexOptions.Compiled);
75
- private const string FuncTaskReplaceRegexReplacement = @"$1Func</*--Task<--*/$2/*-->--*/>";
76
114
77
115
78
116
public static async Task AsyncFileUpdated(string fullName, Context context)
79
117
{
80
118
//using (await Global.FileOperationAsyncLock.LockAsync())
81
119
{
82
- //@"\\?\" prefix is needed for reading from long paths: https://stackoverflow.com/questions/44888844/directorynotfoundexception-when-using-long-paths-in-net-4-7
83
- var fileData = await FileExtensions.ReadAllTextAsync(@"\\?\" + fullName, context.Token);
120
+ var fileData = await FileExtensions.ReadAllTextAsync(Extensions.GetLongPath(fullName), context.Token);
84
121
var originalData = fileData;
85
122
86
123
124
+ if (fullName.EndsWith(".cs"))
125
+ {
126
+ foreach (var replacement in CS_Replacements)
127
+ {
128
+ fileData = fileData.Replace(replacement.Item1, replacement.Item2);
129
+ }
130
+
131
+ fileData = CS_FuncTaskReplaceRegex.Replace(fileData, CS_FuncTaskReplaceRegexReplacement);
132
+ fileData = CS_AsyncLockReplaceRegex.Replace(fileData, CS_AsyncLockReplaceRegexReplacement);
133
+ fileData = CS_TaskReplaceRegex.Replace(fileData, CS_TaskReplaceRegexReplacement);
134
+ fileData = CS_TaskDelayReplaceRegex.Replace(fileData, CS_TaskDelayReplaceRegexReplacement);
135
+ }
136
+ else if (fullName.EndsWith(".py"))
137
+ {
138
+ foreach (var replacement in PY_Replacements)
139
+ {
140
+ fileData = fileData.Replace(replacement.Item1, replacement.Item2);
141
+ }
87
142
88
- fileData = FuncTaskReplaceRegex.Replace(fileData, FuncTaskReplaceRegexReplacement);
89
- fileData = AsyncLockReplaceRegex.Replace(fileData, AsyncLockReplaceRegexReplacement);
90
- fileData = TaskReplaceRegex.Replace(fileData, TaskReplaceRegexReplacement);
91
- fileData = TaskDelayReplaceRegex.Replace(fileData, TaskDelayReplaceRegexReplacement);
92
-
93
-
94
- foreach (var replacement in Replacements)
143
+ fileData = PY_AwaitReplaceRegex.Replace(fileData, PY_AwaitReplaceRegexReplacement);
144
+ fileData = PY_AsyncReplaceRegex.Replace(fileData, PY_AsyncRegexReplacement);
145
+ }
146
+ else
95
147
{
96
- fileData = fileData.Replace(replacement.Item1, replacement.Item2 );
148
+ throw new NotImplementedException("Unknown file extension" );
97
149
}
98
150
99
151
100
152
await ConsoleWatch.SaveFileModifications(fullName, fileData, originalData, context);
101
153
102
154
} //using (await Global.FileOperationAsyncLock.LockAsync())
103
- }
155
+ } //public static async Task AsyncFileUpdated(string fullName, Context context)
104
156
}
105
157
}
0 commit comments