Skip to content

Commit 7068f4b

Browse files
authored
[build] Enable string operations globalization code analyzers. (dotnet#879)
Context: dotnet/android#6271 Context: https://developercommunity.visualstudio.com/t/XamarinAndroid-binding-compiling-proble/1477963 Context: https://www.learncroatian.eu/blog/the-croatian-letters If you attempt to build an Android Binding project on Windows within a Bosnian, Croatian, or Serbian locale, the build may break as the delegate type names created by 56955d9 may not be valid C#, e.g.: delegate IntPtr _JniMarshal_PP_Ljava/Lang/String; (IntPtr jnienv, IntPtr klass) It *should* be declaringn a `_JniMarshal_PP_L` type, *not* `_JniMarshal_PP_Ljava/Lang/String;`, the latter of which results in numerous C# errors: error CS1003: Syntax error, '(' expected error CS1001: Identifier expected error CS1001: Identifier expected error CS1003: Syntax error, ',' expected error CS1003: Syntax error, ',' expected error CS1001: Identifier expected error CS1026: ) expected The problem is caused by the interplay of two factors: 1. Commit 56955d9 uses the culture-sensitive [`string.StartsWith(string)`][0] method to determine if a JNI type name starts with `L`: if (jni_name.StartsWith ("L") || jni_name.StartsWith ("[")) return "L"; 2. In the `bs`, `hr`, and `sr` locales, the strings `Lj` and `lj` are treated as a single letter, *distinct from* `L` or `l`. In those locales, this expression is *false*, not true: "Ljava/lang/String;".StartsWith ("L") // false in bs, hr, sr; true everywhere else Additionally, this issue only arises when Java package names starting with `java` are used, e.g. `Ljava/lang/Object;`. Java types from packages that *don't* start with `java` don't encounter this bug. Fix this issue by enabling the [CA1307][1] and [CA1309][2] rules, previously disabled in commit ac914ce. These code analysis rules require the use of string methods which use the [`StringComparison`][3] enumeration, for which we then specify `StringComparison.Ordinal`, which is *not* culture-sensitive. One complication with enabling these rules is that the .NET 6+ version of these rules are stricter and require overloads that do not exist in .NET Framework or .NET Standard to fix the violations. Enabling these rules in `.editorconfig` affects all `$(TargetFrameworkMoniker)`s; we will instead use `Directory.Build.props` to only enable them for non-.NET 6+ builds. Finally, add a new `.yaml` step that shuts down the cached `dotnet` MSBuild processes between invocations, to fix the error that has been happening on Windows - NET Core: error MSB3027: Could not copy "obj\\Release\Java.Interop.BootstrapTasks.dll" to "D:\a\1\s\bin\BuildRelease\Java.Interop.BootstrapTasks.dll". Exceeded retry count of 10. Failed. [D:\a\1\s\build-tools\Java.Interop.BootstrapTasks\Java.Interop.BootstrapTasks.csproj] error MSB3021: Unable to copy file "obj\\Release\Java.Interop.BootstrapTasks.dll" to "D:\a\1\s\bin\BuildRelease\Java.Interop.BootstrapTasks.dll". The process cannot access the file 'D:\a\1\s\bin\BuildRelease\Java.Interop.BootstrapTasks.dll' because it is being used by another process. [D:\a\1\s\build-tools\Java.Interop.BootstrapTasks\Java.Interop.BootstrapTasks.csproj] [0]: https://docs.microsoft.com/en-us/dotnet/api/system.string.startswith?view=net-5.0#System_String_StartsWith_System_String_ [1]: https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1307 [2]: https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1309 [3]: https://docs.microsoft.com/en-us/dotnet/api/system.stringcomparison?view=net-5.0
1 parent 3e6a623 commit 7068f4b

File tree

45 files changed

+112
-94
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+112
-94
lines changed

.editorconfig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -332,9 +332,9 @@ dotnet_diagnostic.CA1200.severity = none # Avoid using cref tags with a prefix
332332
dotnet_diagnostic.CA1303.severity = none # Do not pass literals as localized parameters
333333
dotnet_diagnostic.CA1304.severity = none # Specify CultureInfo
334334
dotnet_diagnostic.CA1305.severity = none # Specify IFormatProvider
335-
dotnet_diagnostic.CA1307.severity = none # Specify StringComparison
335+
#dotnet_diagnostic.CA1307.severity = none # Specify StringComparison - Controlled via Directory.Build.props
336336
dotnet_diagnostic.CA1308.severity = none # Normalize strings to uppercase
337-
dotnet_diagnostic.CA1309.severity = none # Use ordinal stringcomparison
337+
#dotnet_diagnostic.CA1309.severity = none # Use ordinal stringcomparison - Controlled via Directory.Build.props
338338
dotnet_diagnostic.CA1401.severity = none # P/Invokes should not be visible
339339
dotnet_diagnostic.CA1417.severity = none # Do not use 'OutAttribute' on string parameters for P/Invokes
340340
dotnet_diagnostic.CA1501.severity = none # Avoid excessive inheritance

Directory.Build.props

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
<AppendTargetFrameworkToOutputPath Condition=" '$(AppendTargetFrameworkToOutputPath)' == '' ">False</AppendTargetFrameworkToOutputPath>
4141
<BaseIntermediateOutputPath Condition=" '$(BaseIntermediateOutputPath)' == '' ">obj\</BaseIntermediateOutputPath>
4242
</PropertyGroup>
43-
<PropertyGroup Condition=" '$(TargetFramework)' == 'net6.0' ">
43+
<PropertyGroup Condition=" ( '$(TargetFramework)' != '' AND !$(TargetFramework.StartsWith('nets'))) AND (!$(TargetFramework.StartsWith('net4'))) ">
4444
<JIBuildingForNetCoreApp>True</JIBuildingForNetCoreApp>
4545
</PropertyGroup>
4646
<PropertyGroup Condition=" '$(JIBuildingForNetCoreApp)' == 'True' ">
@@ -85,6 +85,15 @@
8585
<_RunJNIEnvGen Condition=" '$(JIBuildingForNetCoreApp)' != 'True' ">$(Runtime) "$(_JNIEnvGenPath)"</_RunJNIEnvGen>
8686
</PropertyGroup>
8787

88+
<!-- The net6.0 versions of these are stricter and require overloads not available in .NET Framework, so start with just .NET Framework -->
89+
<PropertyGroup Condition=" '$(JIBuildingForNetCoreApp)' != 'True' ">
90+
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
91+
<WarningsAsErrors>$(WarningsAsErrors);CA1307;CA1309;CA1310</WarningsAsErrors>
92+
</PropertyGroup>
93+
<PropertyGroup Condition=" '$(JIBuildingForNetCoreApp)' == 'True' ">
94+
<NoWarn>$(NoWarn);CA1307;CA1309;CA1310</NoWarn>
95+
</PropertyGroup>
96+
8897
<!-- Add Roslyn analyzers NuGet to all projects -->
8998
<ItemGroup Condition=" '$(DisableRoslynAnalyzers)' != 'True' ">
9099
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.0">

build-tools/automation/templates/core-build.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@ steps:
88
projects: Java.Interop.sln
99
arguments: '-c $(Build.Configuration) -target:Prepare -p:MaxJdkVersion=$(MaxJdkVersion)'
1010

11+
- task: DotNetCoreCLI@2
12+
displayName: Shut down existing build server
13+
inputs:
14+
command: custom
15+
custom: build-server
16+
arguments: shutdown
17+
1118
- task: DotNetCoreCLI@2
1219
displayName: Build Solution
1320
inputs:

build-tools/jnienv-gen/Generator.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,7 @@ public override string[] VerifyParameter (HandleStyle style, string variable)
773773
{
774774
if (managed != "IntPtr")
775775
return new string [0];
776-
var variableName = variable.StartsWith ("@")
776+
var variableName = variable.StartsWith ("@", StringComparison.Ordinal)
777777
? variable.Substring (1)
778778
: variable;
779779
return new[] {
@@ -851,7 +851,7 @@ public override string[] GetMarshalToManagedStatements (HandleStyle style, strin
851851

852852
public override string[] VerifyParameter (HandleStyle style, string variable)
853853
{
854-
var variableName = variable.StartsWith ("@")
854+
var variableName = variable.StartsWith ("@", StringComparison.Ordinal)
855855
? variable.Substring (1)
856856
: variable;
857857
return new[] {
@@ -940,7 +940,7 @@ public override string GetManagedToMarshalExpression (HandleStyle style, string
940940

941941
public override string[] VerifyParameter (HandleStyle style, string variable)
942942
{
943-
var variableName = variable.StartsWith ("@")
943+
var variableName = variable.StartsWith ("@", StringComparison.Ordinal)
944944
? variable.Substring (1)
945945
: variable;
946946
switch (style) {
@@ -1097,7 +1097,7 @@ public override string[] GetMarshalToManagedStatements (HandleStyle style, strin
10971097

10981098
public override string[] VerifyParameter (HandleStyle style, string variable)
10991099
{
1100-
var variableName = variable.StartsWith ("@")
1100+
var variableName = variable.StartsWith ("@", StringComparison.Ordinal)
11011101
? variable.Substring (1)
11021102
: variable;
11031103
switch (style) {

src/Java.Interop.Tools.Generator/Enumification/ConstantsParser.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System;
12
using System.Collections.Generic;
23
using System.IO;
34
using System.Linq;
@@ -24,7 +25,7 @@ public static List<ConstantEntry> FromEnumMapCsv (TextReader reader)
2425
// Read the enum csv file
2526
while ((s = reader.ReadLine ()) != null) {
2627
// Skip empty lines and comments
27-
if (string.IsNullOrEmpty (s) || s.StartsWith ("//"))
28+
if (string.IsNullOrEmpty (s) || s.StartsWith ("//", StringComparison.Ordinal))
2829
continue;
2930

3031
// Transient mode means remove the original field

src/Java.Interop.Tools.JavaCallableWrappers/Java.Interop.Tools.JavaCallableWrappers/JavaCallableWrapperGenerator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,7 @@ public Signature (string name, string signature, string connector, string manage
693693
Name = name;
694694

695695
var jnisig = signature;
696-
int closer = jnisig.IndexOf (")");
696+
int closer = jnisig.IndexOf (')');
697697
string ret = jnisig.Substring (closer + 1);
698698
retval = JavaNativeTypeManager.Parse (ret).Type;
699699
string jniparms = jnisig.Substring (1, closer - 1);

src/Java.Interop.Tools.JavaSource/Java.Interop.Tools.JavaSource/SourceJavadocToXmldocGrammar.HtmlBnfTerms.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,10 @@ static IEnumerable<XElement> GetParagraphs (ParseTreeNodeList children)
112112
int len = 0;
113113
int n = -1;
114114

115-
if ((n = s.IndexOf (UnixParagraph, i)) >= 0) {
115+
if ((n = s.IndexOf (UnixParagraph, i, StringComparison.Ordinal)) >= 0) {
116116
len = UnixParagraph.Length;
117117
}
118-
else if ((n = s.IndexOf (DosParagraph, i)) >= 0) {
118+
else if ((n = s.IndexOf (DosParagraph, i, StringComparison.Ordinal)) >= 0) {
119119
len = DosParagraph.Length;
120120
}
121121

src/Java.Interop.Tools.TypeNameMappings/Java.Interop.Tools.TypeNameMappings/JavaNativeTypeManager.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ public static JniTypeName Parse (string jniType)
5858

5959
public static IEnumerable<JniTypeName> FromSignature (string signature)
6060
{
61-
if (signature.StartsWith ("(")) {
62-
int e = signature.IndexOf (")");
61+
if (signature.StartsWith ("(", StringComparison.Ordinal)) {
62+
int e = signature.IndexOf (')');
6363
signature = signature.Substring (1, e >= 0 ? e-1 : signature.Length-1);
6464
}
6565
int i = 0;
@@ -102,7 +102,7 @@ public static JniTypeName ReturnTypeFromSignature (string signature)
102102
case 'J':
103103
return new JniTypeName { Type = "long", IsKeyword = true };
104104
case 'L': {
105-
var e = signature.IndexOf (";", index);
105+
var e = signature.IndexOf (';', index);
106106
if (e <= 0)
107107
throw new InvalidOperationException ("Missing reference type after 'L' at index " + i + "in: " + signature);
108108
var s = index;

src/Xamarin.Android.Tools.AnnotationSupport/AndroidAnnotationsSupport.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ static Stream FixAnnotationXML (Stream s)
6767
// them up before loading with a validating XML parser.
6868
var doc = new HtmlDocument ();
6969
doc.Load (s);
70-
if (doc.DocumentNode.FirstChild.InnerHtml.StartsWith ("<?xml"))
70+
if (doc.DocumentNode.FirstChild.InnerHtml.StartsWith ("<?xml", StringComparison.Ordinal))
7171
doc.DocumentNode.FirstChild.Remove ();
7272

7373
var ms = new MemoryStream ();

src/Xamarin.Android.Tools.Bytecode/ClassPath.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ XAttribute GetPlatform ()
129129

130130
bool IsGeneratedName (string parameterName)
131131
{
132-
return parameterName.StartsWith ("p") && parameterName.Length > 1 && Char.IsDigit (parameterName [1]);
132+
return parameterName.StartsWith ("p", StringComparison.Ordinal) && parameterName.Length > 1 && Char.IsDigit (parameterName [1]);
133133
}
134134

135135
IEnumerable<ClassFile> GetDescendants (ClassFile theClass, IList<ClassFile> classFiles)

src/Xamarin.Android.Tools.Bytecode/Kotlin/KotlinFixups.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ static void FixupExtensionMethod (MethodInfo method)
194194
// like "$this$toByteString", we change it to "obj" to be a bit nicer.
195195
var param = method.GetParameters ();
196196

197-
if (param.Length > 0 && param [0].Name.StartsWith ("$this$")) {
197+
if (param.Length > 0 && param [0].Name.StartsWith ("$this$", StringComparison.Ordinal)) {
198198
Log.Debug ($"Kotlin: Renaming extension parameter {method.DeclaringType?.ThisClass.Name.Value} - {method.Name} - {param [0].Name} -> obj");
199199
param [0].Name = "obj";
200200
}
@@ -288,7 +288,7 @@ static FieldInfo FindJavaFieldProperty (KotlinFile kotlinClass, KotlinProperty p
288288

289289
static MethodInfo FindJavaPropertyGetter (KotlinFile kotlinClass, KotlinProperty property, ClassFile klass)
290290
{
291-
var possible_methods = klass.Methods.Where (method => string.Compare (method.GetMethodNameWithoutSuffix (), $"get{property.Name}", true) == 0 &&
291+
var possible_methods = klass.Methods.Where (method => string.Compare (method.GetMethodNameWithoutSuffix (), $"get{property.Name}", StringComparison.OrdinalIgnoreCase) == 0 &&
292292
method.GetParameters ().Length == 0 &&
293293
TypesMatch (method.ReturnType, property.ReturnType, kotlinClass));
294294

@@ -297,7 +297,7 @@ static MethodInfo FindJavaPropertyGetter (KotlinFile kotlinClass, KotlinProperty
297297

298298
static MethodInfo FindJavaPropertySetter (KotlinFile kotlinClass, KotlinProperty property, ClassFile klass)
299299
{
300-
var possible_methods = klass.Methods.Where (method => string.Compare (method.GetMethodNameWithoutSuffix (), $"set{property.Name}", true) == 0 &&
300+
var possible_methods = klass.Methods.Where (method => string.Compare (method.GetMethodNameWithoutSuffix (), $"set{property.Name}", StringComparison.OrdinalIgnoreCase) == 0 &&
301301
property.ReturnType != null &&
302302
method.GetParameters ().Length == 1 &&
303303
method.ReturnType.BinaryName == "V" &&

src/Xamarin.Android.Tools.Bytecode/Kotlin/KotlinUtilities.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public static ParameterInfo[] GetFilteredParameters (this MethodInfo method)
5757
{
5858
// Kotlin adds this to some constructors but I cannot tell which ones,
5959
// so we'll just ignore them if we see them on the Java side
60-
return method.GetParameters ().Where (p => p.Type.BinaryName != "Lkotlin/jvm/internal/DefaultConstructorMarker;" && !p.Name.StartsWith ("$")).ToArray ();
60+
return method.GetParameters ().Where (p => p.Type.BinaryName != "Lkotlin/jvm/internal/DefaultConstructorMarker;" && !p.Name.StartsWith ("$", StringComparison.Ordinal)).ToArray ();
6161
}
6262

6363
public static string GetMethodNameWithoutSuffix (this MethodInfo method)
@@ -102,9 +102,9 @@ public static bool IsDefaultConstructorMarker (this MethodInfo method)
102102

103103
public static bool IsPubliclyVisible (this KotlinPropertyFlags flags) => flags.HasFlag (KotlinPropertyFlags.Public) || flags.HasFlag (KotlinPropertyFlags.Protected);
104104

105-
public static bool IsUnnamedParameter (this ParameterInfo parameter) => parameter.Name.Length > 1 && parameter.Name.StartsWith ("p") && int.TryParse (parameter.Name.Substring (1), out var _);
105+
public static bool IsUnnamedParameter (this ParameterInfo parameter) => parameter.Name.Length > 1 && parameter.Name.StartsWith ("p", StringComparison.Ordinal) && int.TryParse (parameter.Name.Substring (1), out var _);
106106

107-
public static bool IsUnnamedParameter (this KotlinValueParameter parameter) => parameter.Name.Length > 1 && parameter.Name.StartsWith ("p") && int.TryParse (parameter.Name.Substring (1), out var _);
107+
public static bool IsUnnamedParameter (this KotlinValueParameter parameter) => parameter.Name.Length > 1 && parameter.Name.StartsWith ("p", StringComparison.Ordinal) && int.TryParse (parameter.Name.Substring (1), out var _);
108108

109109
static Dictionary<string, string> type_map = new Dictionary<string, string> {
110110
{ "kotlin/Int", "I" },

src/Xamarin.SourceWriter/Models/CommentWriter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public CommentWriter (string value)
1616

1717
public virtual void Write (CodeWriter writer)
1818
{
19-
if (Value.StartsWith ("#pragma"))
19+
if (Value.StartsWith ("#pragma", StringComparison.Ordinal))
2020
writer.WriteLineNoIndent (Value);
2121
else
2222
writer.WriteLine (Value);

tests/Java.Interop-PerformanceTests/Java.Interop/TimingTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ static Action A (Action a)
293293
static string FormatFraction (double value, int width, int fractionWidth)
294294
{
295295
var v = value.ToString ("0.0" + new string ('#', fractionWidth - 1));
296-
var i = v.IndexOf (NumberFormatInfo.CurrentInfo.NumberDecimalSeparator);
296+
var i = v.IndexOf (NumberFormatInfo.CurrentInfo.NumberDecimalSeparator, StringComparison.Ordinal);
297297
var p = new string (' ', width - fractionWidth - i - 1);
298298
return p + v + new string (' ', width - p.Length - v.Length);
299299
}

tests/generator-Tests/Integration-Tests/BaseGeneratorTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ protected bool FileCompare (string file1, string file2)
9696
using (var hash = new Crc64 ()) {
9797
var f1hash = Convert.ToBase64String (hash.ComputeHash (f1));
9898
var f2hash = Convert.ToBase64String (hash.ComputeHash (f2));
99-
result = f1hash.Equals (f2hash);
99+
result = string.Equals (f1hash, f2hash, StringComparison.Ordinal);
100100
}
101101
}
102102

tools/generator/CodeGenerationOptions.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ string GetJniTypeCode (ISymbol symbol)
204204

205205
var jni_name = symbol.JniName;
206206

207-
if (jni_name.StartsWith ("L") || jni_name.StartsWith ("["))
207+
if (jni_name.StartsWith ("L", StringComparison.Ordinal) || jni_name.StartsWith ("[", StringComparison.Ordinal))
208208
return "L";
209209

210210
return symbol.JniName;
@@ -221,9 +221,9 @@ public string GetOutputName (string type)
221221
// Handle a few special cases
222222
if (type == "System.Void")
223223
return "void";
224-
if (type.StartsWith ("params "))
224+
if (type.StartsWith ("params ", StringComparison.Ordinal))
225225
return "params " + GetOutputName (type.Substring ("params ".Length));
226-
if (type.StartsWith ("global::"))
226+
if (type.StartsWith ("global::", StringComparison.Ordinal))
227227
Report.LogCodedErrorAndExit (Report.ErrorUnexpectedGlobal);
228228
if (!UseGlobal)
229229
return type;
@@ -249,7 +249,7 @@ public string GetSafeIdentifier (string name)
249249
// Sadly that is not true in reality, so we need to exclude non-symbols
250250
// when replacing the argument name with a valid identifier.
251251
// (ReturnValue.ToNative() takes an argument which could be either an expression or mere symbol.)
252-
if (name [name.Length-1] != ')' && !name.Contains ('.') && !name.StartsWith ("@")) {
252+
if (name [name.Length-1] != ')' && !name.Contains ('.') && !name.StartsWith ("@", StringComparison.Ordinal)) {
253253
if (!IdentifierValidator.IsValidIdentifier (name) ||
254254
Array.BinarySearch (TypeNameUtilities.reserved_keywords, name) >= 0) {
255255
name = name + "_";

tools/generator/CodeGenerator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,15 +311,15 @@ internal static void ProcessReferencedType (TypeDefinition td, CodeGenerationOpt
311311
return;
312312

313313
// We want to exclude "IBlahInvoker" types from this type registration.
314-
if (td.Name.EndsWith ("Invoker")) {
314+
if (td.Name.EndsWith ("Invoker", StringComparison.Ordinal)) {
315315
string n = td.FullName;
316316
n = n.Substring (0, n.Length - 7);
317317
var types = td.DeclaringType != null ? td.DeclaringType.Resolve ().NestedTypes : td.Module.Types;
318318
if (types.Any (t => t.FullName == n))
319319
return;
320320
//Console.Error.WriteLine ("WARNING: " + td.FullName + " survived");
321321
}
322-
if (td.Name.EndsWith ("Implementor")) {
322+
if (td.Name.EndsWith ("Implementor", StringComparison.Ordinal)) {
323323
string n = td.FullName;
324324
n = n.Substring (0, n.Length - 11);
325325
var types = td.DeclaringType != null ? td.DeclaringType.Resolve ().NestedTypes : td.Module.Types;

tools/generator/Java.Interop.Tools.Generator.CodeGeneration/CodeGenerator.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -877,7 +877,7 @@ public void WriteInterfaceInvoker (InterfaceGen @interface, string indent)
877877

878878
foreach (InterfaceGen iface in @interface.GetAllDerivedInterfaces ()) {
879879
WriteInterfacePropertyInvokers (@interface, iface.Properties.Where (p => !p.Getter.IsStatic && !p.Getter.IsInterfaceDefaultMethod), indent + "\t", members);
880-
WriteInterfaceMethodInvokers (@interface, iface.Methods.Where (m => !m.IsStatic && !m.IsInterfaceDefaultMethod && !@interface.IsCovariantMethod (m) && !(iface.FullName.StartsWith ("Java.Lang.ICharSequence") && m.Name.EndsWith ("Formatted"))), indent + "\t", members);
880+
WriteInterfaceMethodInvokers (@interface, iface.Methods.Where (m => !m.IsStatic && !m.IsInterfaceDefaultMethod && !@interface.IsCovariantMethod (m) && !(iface.FullName.StartsWith ("Java.Lang.ICharSequence", StringComparison.Ordinal) && m.Name.EndsWith ("Formatted", StringComparison.Ordinal))), indent + "\t", members);
881881
if (iface.FullName == "Java.Lang.ICharSequence")
882882
WriteCharSequenceEnumerator (indent + "\t");
883883
}
@@ -923,7 +923,7 @@ public void WriteInterfaceListenerEventsAndProperties (InterfaceGen @interface,
923923
foreach (var m in @interface.Methods) {
924924
string nameSpec = @interface.Methods.Count > 1 ? m.EventName ?? m.AdjustedName : String.Empty;
925925
string nameUnique = String.IsNullOrEmpty (nameSpec) ? name : nameSpec;
926-
if (nameUnique.StartsWith ("On"))
926+
if (nameUnique.StartsWith ("On", StringComparison.Ordinal))
927927
nameUnique = nameUnique.Substring (2);
928928
if (target.ContainsName (nameUnique))
929929
nameUnique += "Event";
@@ -959,9 +959,9 @@ public void WriteInterfaceListenerEventsAndProperties (InterfaceGen @interface,
959959
refs.Add (method.Name);
960960
string rm = null;
961961
string remove;
962-
if (method.Name.StartsWith ("Set"))
962+
if (method.Name.StartsWith ("Set", StringComparison.Ordinal))
963963
remove = string.Format ("__v => {0} (null)", method.Name);
964-
else if (method.Name.StartsWith ("Add") &&
964+
else if (method.Name.StartsWith ("Add", StringComparison.Ordinal) &&
965965
(rm = "Remove" + method.Name.Substring ("Add".Length)) != null &&
966966
methods.Where (m => m.Name == rm).Any ())
967967
remove = string.Format ("__v => {0} (__v)", rm);
@@ -990,8 +990,8 @@ public void WriteInterfaceListenerEventOrProperty (InterfaceGen @interface, Meth
990990
if (m.EventName == string.Empty)
991991
return;
992992
string nameSpec = @interface.Methods.Count > 1 ? m.AdjustedName : String.Empty;
993-
int idx = @interface.FullName.LastIndexOf (".");
994-
int start = @interface.Name.StartsWith ("IOn") ? 3 : 1;
993+
int idx = @interface.FullName.LastIndexOf ('.');
994+
int start = @interface.Name.StartsWith ("IOn", StringComparison.Ordinal) ? 3 : 1;
995995
string full_delegate_name = @interface.FullName.Substring (0, idx + 1) + @interface.Name.Substring (start, @interface.Name.Length - start - 8) + nameSpec;
996996
if (m.IsSimpleEventHandler)
997997
full_delegate_name = "EventHandler";
@@ -1586,7 +1586,7 @@ public void WriteProperty (Property property, GenBase gen, string indent, bool w
15861586
writer.WriteLine ("{0}}}", indent);
15871587
writer.WriteLine ();
15881588

1589-
if (property.Type.StartsWith ("Java.Lang.ICharSequence") && virtual_override != " override")
1589+
if (property.Type.StartsWith ("Java.Lang.ICharSequence", StringComparison.Ordinal) && virtual_override != " override")
15901590
WritePropertyStringVariant (property, indent);
15911591
}
15921592

@@ -1631,7 +1631,7 @@ public void WritePropertyAbstractDeclaration (Property property, string indent,
16311631
}
16321632
writer.WriteLine ("{0}}}", indent);
16331633
writer.WriteLine ();
1634-
if (property.Type.StartsWith ("Java.Lang.ICharSequence"))
1634+
if (property.Type.StartsWith ("Java.Lang.ICharSequence", StringComparison.Ordinal))
16351635
WritePropertyStringVariant (property, indent);
16361636
}
16371637

tools/generator/Java.Interop.Tools.Generator.CodeGeneration/EnumGenerator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ static void DoParseJniMember (string jniMember, out string package, out string t
8787
int endClass = jniMember.LastIndexOf ('.');
8888

8989
package = jniMember.Substring (0, endPackage).Replace ('/', '.');
90-
if (package.StartsWith ("I:"))
90+
if (package.StartsWith ("I:", StringComparison.Ordinal))
9191
package = package.Substring (2);
9292

9393
if (endClass >= 0) {

tools/generator/Java.Interop.Tools.Generator.Importers/CecilApiImporter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ public static Method CreateMethod (GenBase declaringType, MethodDefinition m)
216216
// Strip "Formatted" from ICharSequence-based method.
217217
var name_base = method.IsReturnCharSequence ? m.Name.Substring (0, m.Name.Length - "Formatted".Length) : m.Name;
218218

219-
method.Name = m.IsGetter ? (m.Name.StartsWith ("get_Is") && m.Name.Length > 6 && char.IsUpper (m.Name [6]) ? string.Empty : "Get") + name_base.Substring (4) : m.IsSetter ? (m.Name.StartsWith ("set_Is") && m.Name.Length > 6 && char.IsUpper (m.Name [6]) ? string.Empty : "Set") + name_base.Substring (4) : name_base;
219+
method.Name = m.IsGetter ? (m.Name.StartsWith ("get_Is", StringComparison.Ordinal) && m.Name.Length > 6 && char.IsUpper (m.Name [6]) ? string.Empty : "Get") + name_base.Substring (4) : m.IsSetter ? (m.Name.StartsWith ("set_Is", StringComparison.Ordinal) && m.Name.Length > 6 && char.IsUpper (m.Name [6]) ? string.Empty : "Set") + name_base.Substring (4) : name_base;
220220

221221
return method;
222222
}

0 commit comments

Comments
 (0)