Skip to content

Support more well-known attributes in local functions#41299

Merged
RikkiGibson merged 8 commits intodotnet:features/local-function-attributesfrom
RikkiGibson:lfa-misc-attributes
Jan 31, 2020
Merged

Support more well-known attributes in local functions#41299
RikkiGibson merged 8 commits intodotnet:features/local-function-attributesfrom
RikkiGibson:lfa-misc-attributes

Conversation

@RikkiGibson
Copy link
Member

Related to #38801

@RikkiGibson RikkiGibson marked this pull request as ready for review January 30, 2020 01:07
@RikkiGibson RikkiGibson requested a review from a team as a code owner January 30, 2020 01:07
// Note that this doesn't affect BaseMethodWrapperSymbol for example because the implementation has no locals.
public sealed override bool AreLocalsZeroed => !(BaseMethod is SourceMethodSymbol sourceMethod) || sourceMethod.AreLocalsZeroed;

internal override bool RequiresSecurityObject => InheritsBaseMethodAttributes && BaseMethod.RequiresSecurityObject;
Copy link
Contributor

@cston cston Jan 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

override [](start = 17, length = 8)

sealed for each override. #Closed

line: 13
";

var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.RegularPreview);
Copy link
Contributor

@cston cston Jan 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CreateCompilationWithMscorlib45 [](start = 30, length = 31)

CreateCompilation? #Closed


var compilation = CreateCompilationWithMscorlib45(
source,
references: new MetadataReference[] { SystemRef },
Copy link
Contributor

@cston cston Jan 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CreateCompilation(source, ... here and in other added tests? #Closed

}";

var expected = @"
name: LocalFunctionCaller
Copy link
Contributor

@cston cston Jan 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LocalFunctionCaller [](start = 6, length = 19)

Should this report "local1" instead?
This is consistent with the name used when calling a member method with [CallerMemberName] from a local function. #Closed

}
}
";
var compilation = CreateCompilationWithMscorlib40(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.RegularPreview);
Copy link
Contributor

@cston cston Jan 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CreateCompilationWithMscorlib40 [](start = 30, length = 31)

CreateCompilation? #Resolved

}

[Fact]
public void LocalFunctionParamsArray_ParamArrayAttribute()
Copy link
Contributor

@cston cston Jan 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ParamArrayAttribute [](start = 45, length = 19)

There is no ParamArrayAttribute in the test. If that's intentional, consider removing _ParamArrayAttribute from the test name. #Resolved

get { return ImmutableArray<CustomModifier>.Empty; }
}

internal override MarshalPseudoCustomAttributeData MarshallingInformation
Copy link
Contributor

@AlekseyTs AlekseyTs Jan 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

internal override MarshalPseudoCustomAttributeData MarshallingInformation [](start = 12, length = 73)

It is not clear what motivated this change. #Closed

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because I deleted the implementation in SynthesizedParameterSymbolBase, it was necessary to provide an implementation in each subtype.


In reply to: 373183931 [](ancestors = 373183931)

p.Name,
attributes: inheritAttributes ? p.GetAttributes() : default,
hasEnumeratorCancellationAttribute: inheritAttributes && p.IsSourceParameterWithEnumeratorCancellationAttribute()));
p.RefCustomModifiers,
Copy link
Contributor

@AlekseyTs AlekseyTs Jan 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p.RefCustomModifiers [](start = 20, length = 20)

Should these be substituted? It looks like we didn't pass these before. Do we have a test with a scenario where this change makes a difference? #Closed

{
Debug.Assert(!refCustomModifiers.IsDefault);
Debug.Assert(!attributes.IsDefault);
Debug.Assert(!refCustomModifiers.IsEmpty || baseParameterForAttributes is object);
Copy link
Contributor

@AlekseyTs AlekseyTs Jan 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

!refCustomModifiers.IsEmpty || baseParameterForAttributes is object [](start = 25, length = 67)

It is not obvious why is this the right thing to assert #Closed

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this condition is false, it means there was no good reason to create this as a SynthesizedComplexParameterSymbol instead of a SynthesizedParameterSymbol.


In reply to: 373192152 [](ancestors = 373192152)

oldParam.RefKind,
oldParam.Name,
oldParam.RefCustomModifiers,
(oldParam as SynthesizedComplexParameterSymbol)?.BaseParameterForAttributes));
Copy link
Contributor

@AlekseyTs AlekseyTs Jan 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(oldParam as SynthesizedComplexParameterSymbol) [](start = 20, length = 47)

Are there scenarios when this is not null? Do we have a test "backing" this change? #Closed

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think any test is affected by this change. This is used for SynthesizedEntryPointSymbol, SynthesizedImplementationMethod, and SynthesizedSealedPropertyAccessor. Actually, this seems like a behavior change where for example a synthesized sealed accessor may start to contain attributes from a base accessor from source, when it didn't before. So perhaps the right thing to do here is to just revert the change.


In reply to: 373194840 [](ancestors = 373194840)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If for all scenarios that can happen today oldParam is never a SynthesizedComplexParameterSymbol, I would add an assert to confirm this fact and pass null.


In reply to: 373204933 [](ancestors = 373204933,373194840)

case DebugInfoInjector { Previous: var previous } injector:
var newPrevious = RemoveDynamicAnalysisInjectors(previous);
return (object)newPrevious != previous ? new DebugInfoInjector(newPrevious) : injector;
if ((object)newPrevious == Instrumenter.NoOp)
Copy link
Contributor

@AlekseyTs AlekseyTs Jan 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(object)newPrevious == Instrumenter.NoOp [](start = 24, length = 40)

I think it would be better to check if (object)newPrevious == previous first #Closed

Console.WriteLine(""name: "" + callerName);
}

log();
Copy link
Contributor

@AlekseyTs AlekseyTs Jan 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

log(); [](start = 12, length = 6)

Consider also testing scenario with nesting into a lambda #Closed

Assert.Empty(localFn1.GetReturnTypeAttributes());

var param = localFn1.Parameters.Single();
Assert.Empty(param.GetAttributes());
Copy link
Contributor

@AlekseyTs AlekseyTs Jan 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assert.Empty(param.GetAttributes()); [](start = 16, length = 36)

Is this intentional? Did we explicitly decide to not synthesize the attribute? #Closed

Copy link
Member Author

@RikkiGibson RikkiGibson Jan 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is pre-existing behavior for local functions with params parameters. I'm not sure if this happened by accident or if it was a deliberate decision. /cc @agocke in case you recall handling this scenario in local functions.


In reply to: 373203102 [](ancestors = 373203102)

@AlekseyTs
Copy link
Contributor

AlekseyTs commented Jan 30, 2020

Done with review pass (iteration 6) #Closed

private readonly ImmutableArray<CSharpAttributeData> _attributes;

// The parameter containing attributes to inherit into this synthesized parameter, if any.
internal SourceComplexParameterSymbol? BaseParameterForAttributes { get; }
Copy link
Contributor

@cston cston Jan 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

internal [](start = 8, length = 8)

Could this be a private readonly field? #Resolved

Copy link
Contributor

@AlekseyTs AlekseyTs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (iteration 8)

@RikkiGibson RikkiGibson merged commit 8422f4f into dotnet:features/local-function-attributes Jan 31, 2020
@RikkiGibson RikkiGibson deleted the lfa-misc-attributes branch January 31, 2020 02:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants