mirror of https://github.com/mono/CppSharp.git
c-sharpdotnetmonobindingsbridgecclangcpluspluscppsharpglueinteropparserparsingpinvokeswigsyntax-treevisitorsxamarinxamarin-bindings
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.
270 lines
7.5 KiB
270 lines
7.5 KiB
using System; |
|
using System.Text; |
|
using System.Text.RegularExpressions; |
|
|
|
namespace CppSharp.Passes |
|
{ |
|
/// <summary> |
|
/// Base class for transform that perform renames of declarations. |
|
/// </summary> |
|
public abstract class RenamePass : TranslationUnitPass |
|
{ |
|
public RenameTargets Targets = RenameTargets.Any; |
|
|
|
protected RenamePass() |
|
{ |
|
} |
|
|
|
protected RenamePass(RenameTargets targets) |
|
{ |
|
Targets = targets; |
|
} |
|
|
|
public abstract bool Rename(string name, out string newName); |
|
|
|
public bool IsRenameableDecl(Declaration decl) |
|
{ |
|
if (decl is Class) return true; |
|
if (decl is Field) return true; |
|
if (decl is Method) return true; |
|
if (decl is Function) return true; |
|
if (decl is Parameter) return true; |
|
if (decl is Enumeration) return true; |
|
return false; |
|
} |
|
|
|
public override bool VisitDeclaration(Declaration decl) |
|
{ |
|
if (!IsRenameableDecl(decl)) |
|
return true; |
|
|
|
if (AlreadyVisited(decl)) |
|
return true; |
|
|
|
Visited.Add(decl); |
|
|
|
if (decl.Name == null) |
|
return true; |
|
|
|
string newName; |
|
if (Rename(decl.Name, out newName)) |
|
{ |
|
decl.Name = newName; |
|
return true; |
|
} |
|
|
|
return true; |
|
} |
|
|
|
public override bool VisitEnumItem(Enumeration.Item item) |
|
{ |
|
if (!Targets.HasFlag(RenameTargets.EnumItem)) |
|
return false; |
|
|
|
string newName; |
|
if (Rename(item.Name, out newName)) |
|
{ |
|
item.Name = newName; |
|
return true; |
|
} |
|
|
|
return true; |
|
} |
|
|
|
public override bool VisitFieldDecl(Field field) |
|
{ |
|
if (!Targets.HasFlag(RenameTargets.Field)) |
|
return false; |
|
|
|
return base.VisitFieldDecl(field); |
|
} |
|
|
|
public override bool VisitMethodDecl(Method method) |
|
{ |
|
if (!Targets.HasFlag(RenameTargets.Method)) |
|
return false; |
|
|
|
if (method.Kind != CXXMethodKind.Normal) |
|
return false; |
|
|
|
return base.VisitMethodDecl(method); |
|
} |
|
|
|
public override bool VisitFunctionDecl(Function function) |
|
{ |
|
if (!Targets.HasFlag(RenameTargets.Function)) |
|
return false; |
|
|
|
return base.VisitFunctionDecl(function); |
|
} |
|
|
|
public override bool VisitParameterDecl(Parameter parameter) |
|
{ |
|
if (!Targets.HasFlag(RenameTargets.Parameter)) |
|
return false; |
|
|
|
return base.VisitParameterDecl(parameter); |
|
} |
|
} |
|
|
|
[Flags] |
|
public enum RenameTargets |
|
{ |
|
Class, |
|
Field, |
|
Method, |
|
Function, |
|
Parameter, |
|
Enum, |
|
EnumItem, |
|
Any = Function | Method | Parameter | Class | Field | Enum | EnumItem, |
|
} |
|
|
|
/// <summary> |
|
/// Renames a declaration based on a regular expression pattern. |
|
/// </summary> |
|
public class RegexRenamePass : RenamePass |
|
{ |
|
public string Pattern; |
|
public string Replacement; |
|
|
|
public RegexRenamePass(string pattern, string replacement) |
|
{ |
|
Pattern = pattern; |
|
Replacement = replacement; |
|
} |
|
|
|
public RegexRenamePass(string pattern, string replacement, |
|
RenameTargets targets) |
|
: this(pattern, replacement) |
|
{ |
|
Targets = targets; |
|
} |
|
|
|
public override bool Rename(string name, out string newName) |
|
{ |
|
var replace = Regex.Replace(name, Pattern, Replacement); |
|
|
|
if (!name.Equals(replace)) |
|
{ |
|
newName = replace; |
|
return true; |
|
} |
|
|
|
newName = null; |
|
return false; |
|
} |
|
} |
|
|
|
public enum RenameCasePattern |
|
{ |
|
UpperCamelCase, |
|
LowerCamelCase |
|
} |
|
|
|
/// <summary> |
|
/// Renames a declaration based on a regular expression pattern. |
|
/// </summary> |
|
public class CaseRenamePass : RenamePass |
|
{ |
|
public RenameCasePattern Pattern; |
|
|
|
public CaseRenamePass(RenameTargets targets, RenameCasePattern pattern) |
|
: base(targets) |
|
{ |
|
Pattern = pattern; |
|
} |
|
|
|
public override bool Rename(string name, out string newName) |
|
{ |
|
newName = null; |
|
|
|
switch (Pattern) |
|
{ |
|
case RenameCasePattern.LowerCamelCase: |
|
newName = ConvertCaseString(name, RenameCasePattern.LowerCamelCase); |
|
return true; |
|
case RenameCasePattern.UpperCamelCase: |
|
newName = ConvertCaseString(name, RenameCasePattern.UpperCamelCase); |
|
return true; |
|
} |
|
|
|
return false; |
|
} |
|
|
|
/// <summary> |
|
/// Converts the phrase to specified convention. |
|
/// </summary> |
|
/// <param name="phrase"></param> |
|
/// <param name="pattern">The cases.</param> |
|
/// <returns>string</returns> |
|
static string ConvertCaseString(string phrase, RenameCasePattern pattern) |
|
{ |
|
var splittedPhrase = phrase.Split(' ', '-', '.'); |
|
var sb = new StringBuilder(); |
|
|
|
switch (pattern) |
|
{ |
|
case RenameCasePattern.LowerCamelCase: |
|
sb.Append(splittedPhrase[0].ToLower()); |
|
splittedPhrase[0] = string.Empty; |
|
break; |
|
case RenameCasePattern.UpperCamelCase: |
|
sb = new StringBuilder(); |
|
break; |
|
} |
|
|
|
foreach (var s in splittedPhrase) |
|
{ |
|
var splittedPhraseChars = s.ToCharArray(); |
|
if (splittedPhraseChars.Length > 0) |
|
{ |
|
var str = new String(splittedPhraseChars[0], 1); |
|
splittedPhraseChars[0] = (str.ToUpper().ToCharArray())[0]; |
|
} |
|
sb.Append(new String(splittedPhraseChars)); |
|
} |
|
return sb.ToString(); |
|
} |
|
} |
|
|
|
public static class RenamePassExtensions |
|
{ |
|
public static void RenameWithPattern(this PassBuilder builder, |
|
string pattern, string replacement, RenameTargets targets) |
|
{ |
|
builder.AddPass(new RegexRenamePass(pattern, replacement, targets)); |
|
} |
|
|
|
public static void RemovePrefix(this PassBuilder builder, string prefix) |
|
{ |
|
builder.AddPass(new RegexRenamePass("^" + prefix, String.Empty)); |
|
} |
|
|
|
public static void RemovePrefixEnumItem(this PassBuilder builder, string prefix) |
|
{ |
|
builder.AddPass(new RegexRenamePass("^" + prefix, String.Empty, |
|
RenameTargets.EnumItem)); |
|
} |
|
|
|
public static void RenameDeclsCase(this PassBuilder builder, |
|
RenameTargets targets, RenameCasePattern pattern) |
|
{ |
|
builder.AddPass(new CaseRenamePass(targets, pattern)); |
|
} |
|
|
|
public static void RenameDeclsUpperCase(this PassBuilder builder, |
|
RenameTargets targets) |
|
{ |
|
builder.AddPass(new CaseRenamePass(targets, |
|
RenameCasePattern.UpperCamelCase)); |
|
} |
|
|
|
public static void RenameDeclsLowerCase(this PassBuilder builder, |
|
RenameTargets targets) |
|
{ |
|
builder.AddPass(new CaseRenamePass(targets, |
|
RenameCasePattern.LowerCamelCase)); |
|
} |
|
} |
|
}
|
|
|