Skip to content

Commit 9e03a9a

Browse files
authored
Add string ctor to MemberNotNull/When (#42712)
1 parent 5356fbf commit 9e03a9a

File tree

10 files changed

+517
-161
lines changed

10 files changed

+517
-161
lines changed

src/Compilers/CSharp/Portable/Symbols/Attributes/AttributeData.cs

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -256,25 +256,37 @@ static internal void DecodeSkipLocalsInitAttribute<T>(CSharpCompilation compilat
256256
static internal void DecodeMemberNotNullAttribute<T>(TypeSymbol type, ref DecodeWellKnownAttributeArguments<AttributeSyntax, CSharpAttributeData, AttributeLocation> arguments)
257257
where T : WellKnownAttributeData, IMemberNotNullAttributeTarget, new()
258258
{
259-
var membersArray = arguments.Attribute.CommonConstructorArguments[0];
260-
if (membersArray.IsNull)
259+
var value = arguments.Attribute.CommonConstructorArguments[0];
260+
if (value.IsNull)
261261
{
262262
return;
263263
}
264264

265-
var builder = ArrayBuilder<string>.GetInstance();
266-
foreach (var member in membersArray.Values)
265+
if (value.Kind != TypedConstantKind.Array)
267266
{
268-
var memberName = member.DecodeValue<string>(SpecialType.System_String);
267+
string? memberName = value.DecodeValue<string>(SpecialType.System_String);
269268
if (memberName is object)
270269
{
271-
builder.Add(memberName);
270+
arguments.GetOrCreateData<T>().AddNotNullMember(memberName);
272271
ReportBadNotNullMemberIfNeeded(type, arguments, memberName);
273272
}
274273
}
274+
else
275+
{
276+
var builder = ArrayBuilder<string>.GetInstance();
277+
foreach (var member in value.Values)
278+
{
279+
var memberName = member.DecodeValue<string>(SpecialType.System_String);
280+
if (memberName is object)
281+
{
282+
builder.Add(memberName);
283+
ReportBadNotNullMemberIfNeeded(type, arguments, memberName);
284+
}
285+
}
275286

276-
arguments.GetOrCreateData<T>().AddNotNullMember(builder);
277-
builder.Free();
287+
arguments.GetOrCreateData<T>().AddNotNullMember(builder);
288+
builder.Free();
289+
}
278290
}
279291

280292
private static void ReportBadNotNullMemberIfNeeded(TypeSymbol type, DecodeWellKnownAttributeArguments<AttributeSyntax, CSharpAttributeData, AttributeLocation> arguments, string memberName)
@@ -294,26 +306,38 @@ private static void ReportBadNotNullMemberIfNeeded(TypeSymbol type, DecodeWellKn
294306
static internal void DecodeMemberNotNullWhenAttribute<T>(TypeSymbol type, ref DecodeWellKnownAttributeArguments<AttributeSyntax, CSharpAttributeData, AttributeLocation> arguments)
295307
where T : WellKnownAttributeData, IMemberNotNullAttributeTarget, new()
296308
{
297-
var membersArray = arguments.Attribute.CommonConstructorArguments[1];
298-
if (membersArray.IsNull)
309+
var value = arguments.Attribute.CommonConstructorArguments[1];
310+
if (value.IsNull)
299311
{
300312
return;
301313
}
302314

303-
var builder = ArrayBuilder<string>.GetInstance();
304-
foreach (var member in membersArray.Values)
315+
var sense = arguments.Attribute.CommonConstructorArguments[0].DecodeValue<bool>(SpecialType.System_Boolean);
316+
if (value.Kind != TypedConstantKind.Array)
305317
{
306-
var memberName = member.DecodeValue<string>(SpecialType.System_String);
318+
var memberName = value.DecodeValue<string>(SpecialType.System_String);
307319
if (memberName is object)
308320
{
309-
builder.Add(memberName);
321+
arguments.GetOrCreateData<T>().AddNotNullWhenMember(sense, memberName);
310322
ReportBadNotNullMemberIfNeeded(type, arguments, memberName);
311323
}
312324
}
325+
else
326+
{
327+
var builder = ArrayBuilder<string>.GetInstance();
328+
foreach (var member in value.Values)
329+
{
330+
var memberName = member.DecodeValue<string>(SpecialType.System_String);
331+
if (memberName is object)
332+
{
333+
builder.Add(memberName);
334+
ReportBadNotNullMemberIfNeeded(type, arguments, memberName);
335+
}
336+
}
313337

314-
var sense = arguments.Attribute.CommonConstructorArguments[0].DecodeValue<bool>(SpecialType.System_Boolean);
315-
arguments.GetOrCreateData<T>().AddNotNullWhenMember(sense, builder);
316-
builder.Free();
338+
arguments.GetOrCreateData<T>().AddNotNullWhenMember(sense, builder);
339+
builder.Free();
340+
}
317341
}
318342

319343
private DeclarativeSecurityAction DecodeSecurityAttributeAction(Symbol targetSymbol, CSharpCompilation compilation, AttributeSyntax? nodeOpt, out bool hasErrors, DiagnosticBag diagnostics)

src/Compilers/CSharp/Portable/Symbols/Attributes/SourceAttributeData.cs

Lines changed: 113 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -206,60 +206,67 @@ internal override int GetTargetAttributeSignatureIndex(Symbol targetSymbol, Attr
206206
TypeSymbol? lazySystemType = null;
207207

208208
ImmutableArray<ParameterSymbol> parameters = ctor.Parameters;
209-
bool foundMatch = false;
210209

211-
for (int i = 0; i < description.Signatures.Length; i++)
210+
for (int signatureIndex = 0; signatureIndex < description.Signatures.Length; signatureIndex++)
211+
{
212+
byte[] targetSignature = description.Signatures[signatureIndex];
213+
214+
if (matches(targetSignature, parameters, ref lazySystemType))
215+
{
216+
return signatureIndex;
217+
}
218+
}
219+
220+
return -1;
221+
222+
bool matches(byte[] targetSignature, ImmutableArray<ParameterSymbol> parameters, ref TypeSymbol? lazySystemType)
212223
{
213-
byte[] targetSignature = description.Signatures[i];
214224
if (targetSignature[0] != (byte)SignatureAttributes.Instance)
215225
{
216-
continue;
226+
return false;
217227
}
218228

219229
byte parameterCount = targetSignature[1];
220230
if (parameterCount != parameters.Length)
221231
{
222-
continue;
232+
return false;
223233
}
224234

225235
if ((SignatureTypeCode)targetSignature[2] != SignatureTypeCode.Void)
226236
{
227-
continue;
237+
return false;
228238
}
229239

230-
foundMatch = (targetSignature.Length == 3);
231-
int k = 0;
232-
for (int j = 3; j < targetSignature.Length; j++)
240+
int parameterIndex = 0;
241+
for (int signatureByteIndex = 3; signatureByteIndex < targetSignature.Length; signatureByteIndex++)
233242
{
234-
if (k >= parameters.Length)
243+
if (parameterIndex >= parameters.Length)
235244
{
236-
break;
245+
return false;
237246
}
238247

239-
TypeSymbol parameterType = parameters[k].Type;
248+
TypeSymbol parameterType = parameters[parameterIndex].Type;
240249
SpecialType specType = parameterType.SpecialType;
241-
byte targetType = targetSignature[j];
250+
byte targetType = targetSignature[signatureByteIndex];
242251

243252
if (targetType == (byte)SignatureTypeCode.TypeHandle)
244253
{
245-
j++;
254+
signatureByteIndex++;
246255

247256
if (parameterType.Kind != SymbolKind.NamedType && parameterType.Kind != SymbolKind.ErrorType)
248257
{
249-
foundMatch = false;
250-
break;
258+
return false;
251259
}
252260

253261
var namedType = (NamedTypeSymbol)parameterType;
254-
AttributeDescription.TypeHandleTargetInfo targetInfo = AttributeDescription.TypeHandleTargets[targetSignature[j]];
262+
AttributeDescription.TypeHandleTargetInfo targetInfo = AttributeDescription.TypeHandleTargets[targetSignature[signatureByteIndex]];
255263

256264
// Compare name and containing symbol name. Uses HasNameQualifier
257265
// extension method to avoid string allocations.
258266
if (!string.Equals(namedType.MetadataName, targetInfo.Name, System.StringComparison.Ordinal) ||
259267
!namedType.HasNameQualifier(targetInfo.Namespace))
260268
{
261-
foundMatch = false;
262-
break;
269+
return false;
263270
}
264271

265272
targetType = (byte)targetInfo.Underlying;
@@ -269,116 +276,155 @@ internal override int GetTargetAttributeSignatureIndex(Symbol targetSymbol, Attr
269276
specType = parameterType.GetEnumUnderlyingType()!.SpecialType;
270277
}
271278
}
272-
else if (parameterType.IsArray())
279+
else if (targetType != (byte)SignatureTypeCode.SZArray && parameterType.IsArray())
273280
{
281+
if (targetSignature[signatureByteIndex - 1] != (byte)SignatureTypeCode.SZArray)
282+
{
283+
return false;
284+
}
285+
274286
specType = ((ArrayTypeSymbol)parameterType).ElementType.SpecialType;
275287
}
276288

277289
switch (targetType)
278290
{
279291
case (byte)SignatureTypeCode.Boolean:
280-
foundMatch = specType == SpecialType.System_Boolean;
281-
k += 1;
292+
if (specType != SpecialType.System_Boolean)
293+
{
294+
return false;
295+
}
296+
parameterIndex += 1;
282297
break;
283298

284299
case (byte)SignatureTypeCode.Char:
285-
foundMatch = specType == SpecialType.System_Char;
286-
k += 1;
300+
if (specType != SpecialType.System_Char)
301+
{
302+
return false;
303+
}
304+
parameterIndex += 1;
287305
break;
288306

289307
case (byte)SignatureTypeCode.SByte:
290-
foundMatch = specType == SpecialType.System_SByte;
291-
k += 1;
308+
if (specType != SpecialType.System_SByte)
309+
{
310+
return false;
311+
}
312+
parameterIndex += 1;
292313
break;
293314

294315
case (byte)SignatureTypeCode.Byte:
295-
foundMatch = specType == SpecialType.System_Byte;
296-
k += 1;
316+
if (specType != SpecialType.System_Byte)
317+
{
318+
return false;
319+
}
320+
parameterIndex += 1;
297321
break;
298322

299323
case (byte)SignatureTypeCode.Int16:
300-
foundMatch = specType == SpecialType.System_Int16;
301-
k += 1;
324+
if (specType != SpecialType.System_Int16)
325+
{
326+
return false;
327+
}
328+
parameterIndex += 1;
302329
break;
303330

304331
case (byte)SignatureTypeCode.UInt16:
305-
foundMatch = specType == SpecialType.System_UInt16;
306-
k += 1;
332+
if (specType != SpecialType.System_UInt16)
333+
{
334+
return false;
335+
}
336+
parameterIndex += 1;
307337
break;
308338

309339
case (byte)SignatureTypeCode.Int32:
310-
foundMatch = specType == SpecialType.System_Int32;
311-
k += 1;
340+
if (specType != SpecialType.System_Int32)
341+
{
342+
return false;
343+
}
344+
parameterIndex += 1;
312345
break;
313346

314347
case (byte)SignatureTypeCode.UInt32:
315-
foundMatch = specType == SpecialType.System_UInt32;
316-
k += 1;
348+
if (specType != SpecialType.System_UInt32)
349+
{
350+
return false;
351+
}
352+
parameterIndex += 1;
317353
break;
318354

319355
case (byte)SignatureTypeCode.Int64:
320-
foundMatch = specType == SpecialType.System_Int64;
321-
k += 1;
356+
if (specType != SpecialType.System_Int64)
357+
{
358+
return false;
359+
}
360+
parameterIndex += 1;
322361
break;
323362

324363
case (byte)SignatureTypeCode.UInt64:
325-
foundMatch = specType == SpecialType.System_UInt64;
326-
k += 1;
364+
if (specType != SpecialType.System_UInt64)
365+
{
366+
return false;
367+
}
368+
parameterIndex += 1;
327369
break;
328370

329371
case (byte)SignatureTypeCode.Single:
330-
foundMatch = specType == SpecialType.System_Single;
331-
k += 1;
372+
if (specType != SpecialType.System_Single)
373+
{
374+
return false;
375+
}
376+
parameterIndex += 1;
332377
break;
333378

334379
case (byte)SignatureTypeCode.Double:
335-
foundMatch = specType == SpecialType.System_Double;
336-
k += 1;
380+
if (specType != SpecialType.System_Double)
381+
{
382+
return false;
383+
}
384+
parameterIndex += 1;
337385
break;
338386

339387
case (byte)SignatureTypeCode.String:
340-
foundMatch = specType == SpecialType.System_String;
341-
k += 1;
388+
if (specType != SpecialType.System_String)
389+
{
390+
return false;
391+
}
392+
parameterIndex += 1;
342393
break;
343394

344395
case (byte)SignatureTypeCode.Object:
345-
foundMatch = specType == SpecialType.System_Object;
346-
k += 1;
396+
if (specType != SpecialType.System_Object)
397+
{
398+
return false;
399+
}
400+
parameterIndex += 1;
347401
break;
348402

349403
case (byte)SerializationTypeCode.Type:
350-
if (lazySystemType is null)
404+
lazySystemType ??= GetSystemType(targetSymbol);
405+
406+
if (!TypeSymbol.Equals(parameterType, lazySystemType, TypeCompareKind.ConsiderEverything))
351407
{
352-
lazySystemType = GetSystemType(targetSymbol);
408+
return false;
353409
}
354-
355-
foundMatch = TypeSymbol.Equals(parameterType, lazySystemType, TypeCompareKind.ConsiderEverything2);
356-
k += 1;
410+
parameterIndex += 1;
357411
break;
358412

359413
case (byte)SignatureTypeCode.SZArray:
360414
// Skip over and check the next byte
361-
foundMatch = parameterType.IsArray();
415+
if (!parameterType.IsArray())
416+
{
417+
return false;
418+
}
362419
break;
363420

364421
default:
365-
return -1;
366-
}
367-
368-
if (!foundMatch)
369-
{
370-
break;
422+
return false;
371423
}
372424
}
373425

374-
if (foundMatch)
375-
{
376-
return i;
377-
}
426+
return true;
378427
}
379-
380-
Debug.Assert(!foundMatch);
381-
return -1;
382428
}
383429

384430
/// <summary>

0 commit comments

Comments
 (0)