Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / System.Data.Entity.Design / System / Data / EntityModel / Emitters / FixUp.cs
1 //---------------------------------------------------------------------
2 // <copyright file="FixUp.cs" company="Microsoft">
3 //      Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //
6 // @owner       Microsoft
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
9
10 using System;
11 using System.Data.EntityModel.SchemaObjectModel;
12 using System.Data.Entity.Design;
13
14 namespace System.Data.EntityModel.Emitters
15 {
16     /// <summary>
17     /// 
18     /// </summary>
19     internal sealed class FixUp
20     {
21         #region Internal Property
22         internal delegate string FixMethod(string line);
23         #endregion
24
25         #region Instance Fields
26         FixUpType m_type;
27         private string _class = null;
28         private string _method = null;
29         private string _property = null;
30         #endregion
31
32         #region static
33         private static readonly FixMethod[] _CSFixMethods = new FixMethod[] 
34         {
35             null,
36             new FixMethod(CSMarkOverrideMethodAsSealed),
37             new FixMethod(CSMarkPropertySetAsInternal),
38             new FixMethod(CSMarkClassAsStatic),
39             new FixMethod(CSMarkPropertyGetAsPrivate),
40             new FixMethod(CSMarkPropertyGetAsInternal),
41             new FixMethod(CSMarkPropertyGetAsPublic),
42             new FixMethod(CSMarkPropertySetAsPrivate),
43             new FixMethod(CSMarkPropertySetAsPublic),
44             new FixMethod(CSMarkMethodAsPartial),
45             new FixMethod(CSMarkPropertyGetAsProtected),
46             new FixMethod(CSMarkPropertySetAsProtected)
47         };
48
49         private static readonly FixMethod[] _VBFixMethods = new FixMethod[] 
50         {
51             null,
52             new FixMethod(VBMarkOverrideMethodAsSealed),
53             new FixMethod(VBMarkPropertySetAsInternal),
54             null, // VB doesn't support static classes (during CodeGen we added a private ctor to the class)
55             new FixMethod(VBMarkPropertyGetAsPrivate),
56             new FixMethod(VBMarkPropertyGetAsInternal),
57             new FixMethod(VBMarkPropertyGetAsPublic),
58             new FixMethod(VBMarkPropertySetAsPrivate),
59             new FixMethod(VBMarkPropertySetAsPublic),
60             new FixMethod(VBMarkMethodAsPartial),
61             new FixMethod(VBMarkPropertyGetAsProtected),
62             new FixMethod(VBMarkPropertySetAsProtected)
63         };
64         #endregion
65
66         #region Public Methods
67         /// <summary>
68         /// 
69         /// </summary>
70         /// <param name="fqName"></param>
71         /// <param name="type"></param>
72         public FixUp(string fqName,FixUpType type)
73         {
74             Type = type;
75             string[] nameParts = Utils.SplitName(fqName);
76             if ( type == FixUpType.MarkClassAsStatic )
77             {
78                 Class = nameParts[nameParts.Length-1];
79             }
80             else
81             {
82                 Class = nameParts[nameParts.Length-2];
83                 string name = nameParts[nameParts.Length-1];
84                 switch ( type )
85                 {
86                     case FixUpType.MarkAbstractMethodAsPartial:
87                     case FixUpType.MarkOverrideMethodAsSealed:
88                         Method = name;
89                         break;
90                     case FixUpType.MarkPropertyGetAsPrivate:
91                     case FixUpType.MarkPropertyGetAsInternal:
92                     case FixUpType.MarkPropertyGetAsPublic:
93                     case FixUpType.MarkPropertyGetAsProtected:
94                     case FixUpType.MarkPropertySetAsPrivate:
95                     case FixUpType.MarkPropertySetAsInternal:
96                     case FixUpType.MarkPropertySetAsPublic:
97                     case FixUpType.MarkPropertySetAsProtected:
98                         Property = name;
99                         break;
100                 }
101             }
102         }
103
104         /// <summary>
105         /// 
106         /// </summary>
107         /// <param name="language"></param>
108         /// <param name="line"></param>
109         /// <returns></returns>
110         public string Fix(LanguageOption language, string line)
111         {
112             FixMethod method = null;
113             if ( language == LanguageOption.GenerateCSharpCode )
114             {
115                 method = _CSFixMethods[(int)Type];
116             }
117             else if ( language == LanguageOption.GenerateVBCode )
118             {
119                 method = _VBFixMethods[(int)Type];
120             }
121
122             if ( method != null )
123             {
124                 line = method( line );
125             }
126
127             return line;
128         }
129         #endregion
130
131         #region Public Properties
132         /// <summary>
133         /// 
134         /// </summary>
135         /// <value></value>
136         public string Class
137         {
138             get
139             {
140                 return _class;
141             }
142             private set
143             {
144                 _class = value;
145             }
146         }
147         /// <summary>
148         /// 
149         /// </summary>
150         /// <value></value>
151         public string Property
152         {
153             get
154             {
155                 return _property;
156             }
157             private set
158             {
159                 _property = value;
160             }
161         }
162         /// <summary>
163         /// 
164         /// </summary>
165         /// <value></value>
166         public string Method
167         {
168             get
169             {
170                 return _method;
171             }
172             private set
173             {
174                 _method = value;
175             }
176         }
177         /// <summary>
178         /// 
179         /// </summary>
180         /// <value></value>
181         public FixUpType Type
182         {
183             get
184             {
185                 return m_type;
186             }
187             private set
188             {
189                 m_type = value;
190             }
191         }
192         #endregion
193
194         #region Private Methods
195         /// <summary>
196         /// 
197         /// </summary>
198         /// <param name="line"></param>
199         /// <returns></returns>
200         private static string CSMarkMethodAsPartial(string line)
201         {
202             line = ReplaceFirst(line, "public abstract", "partial");
203             return line;
204         }
205
206         /// <summary>
207         /// 
208         /// </summary>
209         /// <param name="line"></param>
210         /// <returns></returns>
211         private static string VBMarkMethodAsPartial(string line)
212         {
213             line = ReplaceFirst(line, "Public MustOverride", "Partial Private");
214             line += Environment.NewLine + "        End Sub";
215             return line;
216         }
217
218         private static string ReplaceFirst(string line, string str1, string str2)
219         {
220             int idx = line.IndexOf(str1, StringComparison.Ordinal);
221             if (idx >= 0)
222             {
223                 line = line.Remove(idx, str1.Length);
224                 line = line.Insert(idx, str2);
225             }
226             return line;
227         }
228         /// <summary>
229         /// 
230         /// </summary>
231         /// <param name="line"></param>
232         /// <returns></returns>
233         private static string CSMarkOverrideMethodAsSealed(string line)
234         {
235             return InsertBefore(line,"override","sealed");
236         }
237
238         /// <summary>
239         /// 
240         /// </summary>
241         /// <param name="line"></param>
242         /// <returns></returns>
243         private static string VBMarkOverrideMethodAsSealed(string line)
244         {
245             return InsertBefore(line, "Overrides", "NotOverridable");
246         }
247
248         /// <summary>
249         /// 
250         /// </summary>
251         /// <param name="line"></param>
252         /// <returns></returns>
253         private static string CSMarkPropertySetAsInternal(string line)
254         {
255             return InsertBefore(line,"set","internal");
256         }
257
258         /// <summary>
259         /// 
260         /// </summary>
261         /// <param name="line"></param>
262         /// <returns></returns>
263         private static string VBMarkPropertySetAsInternal(string line)
264         {
265             return InsertBefore(line,"Set","Friend");
266         }
267
268
269         private static string CSMarkPropertyGetAsPrivate(string line)
270         {
271             return InsertBefore(line, "get", "private");
272         }
273
274         private static string VBMarkPropertyGetAsPrivate(string line)
275         {
276             return InsertBefore(line, "Get", "Private");
277         }
278
279
280         private static string CSMarkPropertyGetAsInternal(string line)
281         {
282             return InsertBefore(line, "get", "internal");
283         }
284
285         private static string VBMarkPropertyGetAsInternal(string line)
286         {
287             return InsertBefore(line, "Get", "Friend");
288         }
289
290         private static string CSMarkPropertySetAsProtected(string line)
291         {
292             return InsertBefore(line, "set", "protected");
293         }
294
295         private static string VBMarkPropertySetAsProtected(string line)
296         {
297             return InsertBefore(line, "Set", "Protected");
298         }
299
300         private static string CSMarkPropertyGetAsProtected(string line)
301         {
302             return InsertBefore(line, "get", "protected");
303         }
304
305         private static string VBMarkPropertyGetAsProtected(string line)
306         {
307             return InsertBefore(line, "Get", "Protected");
308         }
309
310         private static string CSMarkPropertyGetAsPublic(string line)
311         {
312             return InsertBefore(line, "get", "public");
313         }
314
315         private static string VBMarkPropertyGetAsPublic(string line)
316         {
317             return InsertBefore(line, "Get", "Public");
318         }
319
320
321         private static string CSMarkPropertySetAsPrivate(string line)
322         {
323             return InsertBefore(line, "set", "private");
324         }
325
326         private static string VBMarkPropertySetAsPrivate(string line)
327         {
328             return InsertBefore(line, "Set", "Private");
329         }
330
331
332         private static string CSMarkPropertySetAsPublic(string line)
333         {
334             return InsertBefore(line, "set", "public");
335         }
336
337         private static string VBMarkPropertySetAsPublic(string line)
338         {
339             return InsertBefore(line, "Set", "Public");
340         }
341
342
343         /// <summary>
344         /// 
345         /// </summary>
346         /// <param name="line"></param>
347         /// <returns></returns>
348         private static string CSMarkClassAsStatic(string line)
349         {
350             if ( IndexOfKeyword(line,"static") >= 0 )
351                 return line;
352
353             int insertPoint = IndexOfKeyword(line,"class");
354             if ( insertPoint < 0 )
355                 return line;
356
357             // nothing can be between partial and class
358             int partialIndex = IndexOfKeyword(line,"partial");
359             if ( partialIndex >= 0 )
360                 insertPoint = partialIndex;
361
362             return line.Insert(insertPoint,"static ");
363         }
364
365         /// <summary>
366         /// Inserts one keyword before another one.
367         /// Does nothing if the keyword to be inserted already exists in the line OR if the keyword to insert before doesn't
368         /// </summary>
369         /// <param name="line">line of text to examine</param>
370         /// <param name="searchText">keyword to search for </param>
371         /// <param name="insertText">keyword to be inserted</param>
372         /// <returns>the possibly modified line line</returns>
373         private static string InsertBefore(string line,string searchText,string insertText)
374         {
375             if ( IndexOfKeyword(line,insertText) >= 0 )
376                 return line;
377
378             int index = IndexOfKeyword(line,searchText);
379             if ( index < 0 )
380                 return line;
381
382             return line.Insert(index,insertText+" ");
383         }
384
385         /// <summary>
386         /// Finds location of a keyword in a line.
387         /// keyword must be at the beginning of the line or preceeded by whitespace AND at the end of the line or followed by whitespace
388         /// </summary>
389         /// <param name="line">line to seach</param>
390         /// <param name="keyword">keyword to search for</param>
391         /// <returns>location of first character of keyword</returns>
392         private static int IndexOfKeyword(string line,string keyword)
393         {
394             int index = line.IndexOf(keyword,StringComparison.Ordinal);
395             if ( index < 0 )
396                 return index;
397
398             int indexAfter = index+keyword.Length;
399             if ( (index == 0 || char.IsWhiteSpace(line,index-1)) && (indexAfter == line.Length || char.IsWhiteSpace(line,indexAfter)) )
400                 return index;
401
402             return -1;
403         }
404         #endregion
405     }
406 }