diff --git a/src/CppParser/Bootstrap/Bootstrap.cs b/src/CppParser/Bootstrap/Bootstrap.cs index 890a58fe..0a0b48a8 100644 --- a/src/CppParser/Bootstrap/Bootstrap.cs +++ b/src/CppParser/Bootstrap/Bootstrap.cs @@ -1762,11 +1762,9 @@ namespace CppSharp } if (!hasConflict) - name = CaseRenamePass.ConvertCaseString(decl, - RenameCasePattern.UpperCamelCase); - - if (CSharpSources.IsReservedKeyword(name)) - name = $"@{name}"; + name = CSharpSources.SafeIdentifier( + CaseRenamePass.ConvertCaseString(decl, + RenameCasePattern.UpperCamelCase)); } else throw new NotImplementedException(); diff --git a/src/Generator/Driver.cs b/src/Generator/Driver.cs index 3ae9255e..a1b619bd 100644 --- a/src/Generator/Driver.cs +++ b/src/Generator/Driver.cs @@ -277,7 +277,10 @@ namespace CppSharp if (Options.GeneratorKind == GeneratorKind.CLI || Options.GeneratorKind == GeneratorKind.CSharp) - TranslationUnitPasses.RenameDeclsUpperCase(RenameTargets.Any &~ RenameTargets.Parameter); + { + TranslationUnitPasses.RenameDeclsUpperCase(RenameTargets.Any & ~RenameTargets.Parameter); + TranslationUnitPasses.AddPass(new CheckKeywordNamesPass()); + } } public void ProcessCode() diff --git a/src/Generator/Generators/C/CCodeGenerator.cs b/src/Generator/Generators/C/CCodeGenerator.cs index d456a90d..3934848b 100644 --- a/src/Generator/Generators/C/CCodeGenerator.cs +++ b/src/Generator/Generators/C/CCodeGenerator.cs @@ -41,11 +41,6 @@ namespace CppSharp.Generators.C return decl.QualifiedName; } - public override string GeneratedIdentifier(string id) - { - return "__" + id.Replace('-', '_'); - } - private CppTypePrinter typePrinter = new CppTypePrinter(); public virtual CppTypePrinter CTypePrinter => typePrinter; @@ -186,7 +181,7 @@ namespace CppSharp.Generators.C if (Options.GeneratorKind == GeneratorKind.CLI) { - keywords.Add(AccessIdentifier(@class.Access)); + keywords.Add(Helpers.GetAccess(@class.Access)); if (@class.IsAbstract) keywords.Add("abstract"); diff --git a/src/Generator/Generators/CSharp/CSharpSources.cs b/src/Generator/Generators/CSharp/CSharpSources.cs index 296e07eb..137a2fb6 100644 --- a/src/Generator/Generators/CSharp/CSharpSources.cs +++ b/src/Generator/Generators/CSharp/CSharpSources.cs @@ -59,9 +59,7 @@ namespace CppSharp.Generators.CSharp "void", "partial", "yield", "where" }; - public static bool IsReservedKeyword(string id) => ReservedKeywords.Contains(id); - - public override string SafeIdentifier(string id) + public static string SafeIdentifier(string id) { if (id.All(char.IsLetterOrDigit)) return ReservedKeywords.Contains(id) ? "@" + id : id; @@ -246,7 +244,7 @@ namespace CppSharp.Generators.CSharp return; PushBlock(BlockKind.Functions); - var parentName = SafeIdentifier(context.TranslationUnit.FileNameWithoutExtension); + var parentName = context.TranslationUnit.FileNameWithoutExtension; var keyword = "class"; var classes = EnumerateClasses().ToList(); @@ -724,7 +722,7 @@ namespace CppSharp.Generators.CSharp keywords.Add("partial"); keywords.Add(@class.IsInterface ? "interface" : (@class.IsValueType ? "struct" : "class")); - keywords.Add(SafeIdentifier(@class.Name)); + keywords.Add(@class.Name); Write(string.Join(" ", keywords)); if (@class.IsDependent && @class.TemplateParameters.Any()) @@ -927,7 +925,7 @@ namespace CppSharp.Generators.CSharp else { var name = @class.Layout.Fields.First(f => f.FieldPtr == field.OriginalPtr).Name; - var identifier = SafeIdentifier(name); + var identifier = name; if (@class.IsValueType) returnVar = $"{Helpers.InstanceField}.{identifier}"; else @@ -998,7 +996,7 @@ namespace CppSharp.Generators.CSharp var name = ((Class) field.Namespace).Layout.Fields.First( f => f.FieldPtr == field.OriginalPtr).Name; WriteLine(string.Format("fixed ({0} {1} = {2}.{3})", - type, arrPtr, Helpers.InstanceField, SafeIdentifier(name))); + type, arrPtr, Helpers.InstanceField, name)); WriteOpenBraceAndIndent(); return arrPtr; } @@ -1219,11 +1217,11 @@ namespace CppSharp.Generators.CSharp if (arrayType != null) returnVar = HandleValueArray(arrayType, field); else - returnVar = $"{Helpers.InstanceField}.{SafeIdentifier(name)}"; + returnVar = $"{Helpers.InstanceField}.{name}"; } else { - returnVar = $"(({TypePrinter.PrintNative(@class)}*) {Helpers.InstanceIdentifier})->{SafeIdentifier(name)}"; + returnVar = $"(({TypePrinter.PrintNative(@class)}*) {Helpers.InstanceIdentifier})->{name}"; // Class field getter should return a reference object instead of a copy. Wrapping `returnVar` in // IntPtr ensures that non-copying object constructor is invoked. Class typeClass; @@ -1372,8 +1370,8 @@ namespace CppSharp.Generators.CSharp { var name = @class.Layout.Fields.First(f => f.FieldPtr == prop.Field.OriginalPtr).Name; GenerateClassField(prop.Field); - WriteLine("private bool {0};", - GeneratedIdentifier(string.Format("{0}Initialised", name))); + string safeIdentifier = name.StartsWith("@") ? name.Substring(1) : name; + WriteLine($"private bool __{safeIdentifier}Initialised;"); } GenerateDeclarationCommon(prop); @@ -1434,7 +1432,7 @@ namespace CppSharp.Generators.CSharp { var isIndexer = prop.Parameters.Count != 0; if (!isIndexer) - return SafeIdentifier(prop.Name); + return prop.Name; var @params = prop.Parameters.Select(param => { var p = new Parameter(param); @@ -3109,7 +3107,7 @@ namespace CppSharp.Generators.CSharp // internal P/Invoke declarations must see protected enums if (@enum.Access == AccessSpecifier.Protected) Write("internal "); - Write("enum {0}", SafeIdentifier(@enum.Name)); + Write("enum {0}", @enum.Name); var typeName = TypePrinter.VisitPrimitiveType(@enum.BuiltinType.Type, new TypeQualifiers()); diff --git a/src/Generator/Generators/CSharp/CSharpTypePrinter.cs b/src/Generator/Generators/CSharp/CSharpTypePrinter.cs index 630dcd43..cce03c1f 100644 --- a/src/Generator/Generators/CSharp/CSharpTypePrinter.cs +++ b/src/Generator/Generators/CSharp/CSharpTypePrinter.cs @@ -739,22 +739,16 @@ namespace CppSharp.Generators.CSharp public override TypePrinterResult VisitFieldDecl(Field field) { var cSharpSourcesDummy = new CSharpSources(Context, new List()); - var safeIdentifier = cSharpSourcesDummy.SafeIdentifier(field.Name); - if (safeIdentifier.All(c => c.Equals('_'))) - { - safeIdentifier = cSharpSourcesDummy.SafeIdentifier(field.Name); - } - - PushMarshalKind(MarshalKind.NativeField); + PushMarshalKind(MarshalKind.NativeField); var fieldTypePrinted = field.QualifiedType.Visit(this); PopMarshalKind(); - + var returnTypePrinter = new TypePrinterResult(); if (!string.IsNullOrWhiteSpace(fieldTypePrinted.NameSuffix)) returnTypePrinter.NameSuffix = fieldTypePrinted.NameSuffix; - returnTypePrinter.Type = $"{fieldTypePrinted.Type} {safeIdentifier}"; + returnTypePrinter.Type = $"{fieldTypePrinted.Type} {field.Name}"; return returnTypePrinter; } diff --git a/src/Generator/Generators/CodeGenerator.cs b/src/Generator/Generators/CodeGenerator.cs index a520157b..0f183002 100644 --- a/src/Generator/Generators/CodeGenerator.cs +++ b/src/Generator/Generators/CodeGenerator.cs @@ -105,19 +105,6 @@ namespace CppSharp.Generators #endregion - #region Identifiers generation - - public virtual string SafeIdentifier(string id) => id; - - public virtual string GeneratedIdentifier(string id) => Generator.GeneratedIdentifier(id); - - public virtual string AccessIdentifier(AccessSpecifier accessSpecifier) - { - return Helpers.GetAccess(accessSpecifier); - } - - #endregion - #region Comment generation public virtual void GenerateSummary(string comment) diff --git a/src/Generator/Passes/CheckKeywordNamesPass.cs b/src/Generator/Passes/CheckKeywordNamesPass.cs new file mode 100644 index 00000000..fa567046 --- /dev/null +++ b/src/Generator/Passes/CheckKeywordNamesPass.cs @@ -0,0 +1,31 @@ +using CppSharp.AST; +using CppSharp.Generators.CSharp; + +namespace CppSharp.Passes +{ + public class CheckKeywordNamesPass : TranslationUnitPass + { + public override bool VisitClassDecl(Class @class) + { + if (!base.VisitClassDecl(@class) || @class.Layout == null) + return false; + + foreach (var field in @class.Layout.Fields) + field.Name = SafeIdentifier(field.Name); + + return true; + } + + public override bool VisitDeclaration(Declaration decl) + { + if (!base.VisitDeclaration(decl) || decl.Ignore) + return false; + + decl.Name = SafeIdentifier(decl.Name); + return true; + } + + private string SafeIdentifier(string id) => + Options.IsCLIGenerator ? id : CSharpSources.SafeIdentifier(id); + } +} diff --git a/src/Generator/Passes/CleanInvalidDeclNamesPass.cs b/src/Generator/Passes/CleanInvalidDeclNamesPass.cs index dbd2a9f9..61d12ef1 100644 --- a/src/Generator/Passes/CleanInvalidDeclNamesPass.cs +++ b/src/Generator/Passes/CleanInvalidDeclNamesPass.cs @@ -2,23 +2,12 @@ using System.Linq; using System.Text; using CppSharp.AST; -using CppSharp.Generators.CLI; -using CppSharp.Generators.CSharp; using CppSharp.Generators; namespace CppSharp.Passes { public class CleanInvalidDeclNamesPass : TranslationUnitPass { - public override bool VisitASTContext(ASTContext context) - { - // TODO: Fix this to not need per-generator code. - generator = Options.IsCLIGenerator ? - new CLIHeaders(Context, new List()) : - (CodeGenerator) new CSharpSources(Context); - return base.VisitASTContext(context); - } - public override bool VisitClassDecl(Class @class) { if (!base.VisitClassDecl(@class)) @@ -138,10 +127,8 @@ namespace CppSharp.Passes if (char.IsNumber(name[0])) return '_' + name; - return generator.SafeIdentifier(name); + return name; } - - private CodeGenerator generator; } } diff --git a/src/Generator/Passes/SpecializationMethodsWithDependentPointersPass.cs b/src/Generator/Passes/SpecializationMethodsWithDependentPointersPass.cs index 3bee97f7..328b4a28 100644 --- a/src/Generator/Passes/SpecializationMethodsWithDependentPointersPass.cs +++ b/src/Generator/Passes/SpecializationMethodsWithDependentPointersPass.cs @@ -129,7 +129,7 @@ namespace CppSharp.Passes var thisParameter = new Parameter(); thisParameter.QualifiedType = new QualifiedType(new PointerType( new QualifiedType(new TagType(specializedMethod.Namespace)))); - thisParameter.Name = "@this"; + thisParameter.Name = "this"; thisParameter.Kind = ParameterKind.Extension; thisParameter.Namespace = extensionMethod; extensionMethod.Parameters.Insert(0, thisParameter);