diff options
author | Marek Safar <marek.safar@gmail.com> | 2017-01-17 17:35:38 +0300 |
---|---|---|
committer | Stephen Toub <stoub@microsoft.com> | 2017-02-07 22:37:01 +0300 |
commit | 11cd918f38bd14251a3464e0fcfce0d77075b2f6 (patch) | |
tree | fc23f2795ec96c76bde99410e4f7e9d37aef3477 | |
parent | 42ce0e696e08e190aceaf8613e47e67d57178550 (diff) |
CodeDom fixes for explicit interface implementation with built-in types
This is quite corner case but C#/VB compilers cannot even parse code
where built in types are used as prefix in explicit interface implementation
The patch fixes cases like the one bellow to always use fully qualified name
in this scenario.
public class Test1
{
event int int.Click;
}
3 files changed, 106 insertions, 137 deletions
diff --git a/src/System.CodeDom/src/Microsoft/CSharp/CSharpCodeGenerator.cs b/src/System.CodeDom/src/Microsoft/CSharp/CSharpCodeGenerator.cs index 242a60a2e8..e180cb5c5a 100644 --- a/src/System.CodeDom/src/Microsoft/CSharp/CSharpCodeGenerator.cs +++ b/src/System.CodeDom/src/Microsoft/CSharp/CSharpCodeGenerator.cs @@ -1213,7 +1213,7 @@ namespace Microsoft.CSharp string name = e.Name; if (e.PrivateImplementationType != null) { - name = GetBaseTypeOutput(e.PrivateImplementationType) + "." + name; + name = GetBaseTypeOutput(e.PrivateImplementationType, preferBuiltInTypes: false) + "." + name; } OutputTypeNamePair(e.Type, name); Output.WriteLine(';'); @@ -1472,7 +1472,7 @@ namespace Microsoft.CSharp Output.Write(' '); if (e.PrivateImplementationType != null) { - Output.Write(GetBaseTypeOutput(e.PrivateImplementationType)); + Output.Write(GetBaseTypeOutput(e.PrivateImplementationType, preferBuiltInTypes: false)); Output.Write('.'); } OutputIdentifier(e.Name); @@ -1558,7 +1558,7 @@ namespace Microsoft.CSharp if (e.PrivateImplementationType != null && !IsCurrentInterface) { - Output.Write(GetBaseTypeOutput(e.PrivateImplementationType)); + Output.Write(GetBaseTypeOutput(e.PrivateImplementationType, preferBuiltInTypes: false)); Output.Write('.'); } @@ -2803,68 +2803,56 @@ namespace Microsoft.CSharp } // returns the type name without any array declaration. - private string GetBaseTypeOutput(CodeTypeReference typeRef) + private string GetBaseTypeOutput(CodeTypeReference typeRef, bool preferBuiltInTypes = true) { string s = typeRef.BaseType; - if (s.Length == 0) - { - s = "void"; - return s; - } - string lowerCaseString = s.ToLower(CultureInfo.InvariantCulture).Trim(); + if (preferBuiltInTypes) + { + if (s.Length == 0) + { + return "void"; + } + + string lowerCaseString = s.ToLower(CultureInfo.InvariantCulture).Trim(); + + switch (lowerCaseString) + { + case "system.int16": + return "short"; + case "system.int32": + return "int"; + case "system.int64": + return "long"; + case "system.string": + return "string"; + case "system.object": + return "object"; + case "system.boolean": + return "bool"; + case "system.void": + return "void"; + case "system.char": + return "char"; + case "system.byte": + return "byte"; + case "system.uint16": + return "ushort"; + case "system.uint32": + return "uint"; + case "system.uint64": + return "ulong"; + case "system.sbyte": + return "sbyte"; + case "system.single": + return "float"; + case "system.double": + return "double"; + case "system.decimal": + return "decimal"; + } + } - switch (lowerCaseString) - { - case "system.int16": - s = "short"; - break; - case "system.int32": - s = "int"; - break; - case "system.int64": - s = "long"; - break; - case "system.string": - s = "string"; - break; - case "system.object": - s = "object"; - break; - case "system.boolean": - s = "bool"; - break; - case "system.void": - s = "void"; - break; - case "system.char": - s = "char"; - break; - case "system.byte": - s = "byte"; - break; - case "system.uint16": - s = "ushort"; - break; - case "system.uint32": - s = "uint"; - break; - case "system.uint64": - s = "ulong"; - break; - case "system.sbyte": - s = "sbyte"; - break; - case "system.single": - s = "float"; - break; - case "system.double": - s = "double"; - break; - case "system.decimal": - s = "decimal"; - break; - default: // replace + with . for nested classes. // var sb = new StringBuilder(s.Length + 10); @@ -2919,8 +2907,6 @@ namespace Microsoft.CSharp sb.Append(CreateEscapedIdentifier(baseType.Substring(lastIndex))); return sb.ToString(); - } - return s; } private string GetTypeArgumentsOutput(CodeTypeReferenceCollection typeArguments) diff --git a/src/System.CodeDom/src/Microsoft/VisualBasic/VBCodeGenerator.cs b/src/System.CodeDom/src/Microsoft/VisualBasic/VBCodeGenerator.cs index 60f5a4f18d..a03d0b02be 100644 --- a/src/System.CodeDom/src/Microsoft/VisualBasic/VBCodeGenerator.cs +++ b/src/System.CodeDom/src/Microsoft/VisualBasic/VBCodeGenerator.cs @@ -1434,7 +1434,7 @@ namespace Microsoft.VisualBasic string eventName = e.Name; if (e.PrivateImplementationType != null) { - string impl = GetBaseTypeOutput(e.PrivateImplementationType); + string impl = GetBaseTypeOutput(e.PrivateImplementationType, preferBuiltInTypes: false); impl = impl.Replace('.', '_'); e.Name = impl + "_" + e.Name; } @@ -1561,7 +1561,7 @@ namespace Microsoft.VisualBasic string methodName = e.Name; if (e.PrivateImplementationType != null) { - string impl = GetBaseTypeOutput(e.PrivateImplementationType); + string impl = GetBaseTypeOutput(e.PrivateImplementationType, preferBuiltInTypes: false); impl = impl.Replace('.', '_'); e.Name = impl + "_" + e.Name; } @@ -1714,7 +1714,7 @@ namespace Microsoft.VisualBasic string propName = e.Name; if (e.PrivateImplementationType != null) { - string impl = GetBaseTypeOutput(e.PrivateImplementationType); + string impl = GetBaseTypeOutput(e.PrivateImplementationType, preferBuiltInTypes: false); impl = impl.Replace('.', '_'); e.Name = impl + "_" + e.Name; } @@ -2399,80 +2399,56 @@ namespace Microsoft.VisualBasic return name; } - private string GetBaseTypeOutput(CodeTypeReference typeRef) + private string GetBaseTypeOutput(CodeTypeReference typeRef, bool preferBuiltInTypes = true) { string baseType = typeRef.BaseType; - if (baseType.Length == 0) - { - return "Void"; - } - else if (string.Equals(baseType, "System.Byte", StringComparison.OrdinalIgnoreCase)) - { - return "Byte"; - } - else if (string.Equals(baseType, "System.SByte", StringComparison.OrdinalIgnoreCase)) - { - return "SByte"; - } - else if (string.Equals(baseType, "System.Int16", StringComparison.OrdinalIgnoreCase)) - { - return "Short"; - } - else if (string.Equals(baseType, "System.Int32", StringComparison.OrdinalIgnoreCase)) - { - return "Integer"; - } - else if (string.Equals(baseType, "System.Int64", StringComparison.OrdinalIgnoreCase)) - { - return "Long"; - } - else if (string.Equals(baseType, "System.UInt16", StringComparison.OrdinalIgnoreCase)) - { - return "UShort"; - } - else if (string.Equals(baseType, "System.UInt32", StringComparison.OrdinalIgnoreCase)) - { - return "UInteger"; - } - else if (string.Equals(baseType, "System.UInt64", StringComparison.OrdinalIgnoreCase)) - { - return "ULong"; - } - else if (string.Equals(baseType, "System.String", StringComparison.OrdinalIgnoreCase)) - { - return "String"; - } - else if (string.Equals(baseType, "System.DateTime", StringComparison.OrdinalIgnoreCase)) - { - return "Date"; - } - else if (string.Equals(baseType, "System.Decimal", StringComparison.OrdinalIgnoreCase)) - { - return "Decimal"; - } - else if (string.Equals(baseType, "System.Single", StringComparison.OrdinalIgnoreCase)) - { - return "Single"; - } - else if (string.Equals(baseType, "System.Double", StringComparison.OrdinalIgnoreCase)) - { - return "Double"; - } - else if (string.Equals(baseType, "System.Boolean", StringComparison.OrdinalIgnoreCase)) - { - return "Boolean"; - } - else if (string.Equals(baseType, "System.Char", StringComparison.OrdinalIgnoreCase)) - { - return "Char"; - } - else if (string.Equals(baseType, "System.Object", StringComparison.OrdinalIgnoreCase)) - { - return "Object"; + if (preferBuiltInTypes) + { + if (baseType.Length == 0) + { + return "Void"; + } + + string lowerCaseString = baseType.ToLowerInvariant(); + + switch (lowerCaseString) + { + case "system.byte": + return "Byte"; + case "system.sbyte": + return "SByte"; + case "system.int16": + return "Short"; + case "system.int32": + return "Integer"; + case "system.int64": + return "Long"; + case "system.uint16": + return "UShort"; + case "system.uint32": + return "UInteger"; + case "system.uint64": + return "ULong"; + case "system.string": + return "String"; + case "system.datetime": + return "Date"; + case "system.decimal": + return "Decimal"; + case "system.single": + return "Single"; + case "system.double": + return "Double"; + case "system.boolean": + return "Boolean"; + case "system.char": + return "Char"; + case "system.object": + return "Object"; + } } - else - { + var sb = new StringBuilder(baseType.Length + 10); if ((typeRef.Options & CodeTypeReferenceOptions.GlobalReference) != 0) { @@ -2525,7 +2501,6 @@ namespace Microsoft.VisualBasic } return sb.ToString(); - } } private string GetTypeOutputWithoutArrayPostFix(CodeTypeReference typeRef) diff --git a/src/System.CodeDom/tests/CSharpCodeGenerationTests.cs b/src/System.CodeDom/tests/CSharpCodeGenerationTests.cs index bc36ebccaf..3f5eb0848d 100644 --- a/src/System.CodeDom/tests/CSharpCodeGenerationTests.cs +++ b/src/System.CodeDom/tests/CSharpCodeGenerationTests.cs @@ -449,6 +449,14 @@ namespace System.CodeDom.Tests } [Fact] + public void ExplicitImplementation() + { + var m = new CodeMemberMethod() { Name = "MyMethod" }; + m.PrivateImplementationType = new CodeTypeReference(typeof(System.Int64)); + AssertEqual(m, @"void System.Int64.MyMethod() { }"); + } + + [Fact] public void Arrays_SingleDimensional_PrimitiveTypes() { var arrayMethod = new CodeMemberMethod(); |