Skip to content

MarshalInfo should parse field assignment in constructors #17

@monkey0506

Description

@monkey0506

Describe the issue

The methods in the MarshalInfo class in the incremental-generator branch are responsible for parsing user-supplied MarshalAsAttributes. While parsing a readonly field is supported, the current code requires an inline initializer for that field value to be parsed. The answer posted to the question GetOperation returning null for VariableDeclaratorSyntax, VariableDeclarationSyntax, and FieldDeclarationSyntax - Stack Overflow provides details on how a field assignment in the constructor can be parsed as well.

Proposed solution

The relevant ISimpleAssignmentOperation (derived from an AssignmentExpressionSyntax with Kind of SimpleAssignmentExpression which has a ConstructorDeclarationSyntax ancestor node and which has a Target of IFieldReferenceOperation to the readonly field in question) can be utilized to parse the assigned value, in the same way that the inline assignment is parsed.

// pseudo-code

IEnumerable<AssignmentExpressionSyntax> allAssignments = ...;
var assignmentsToEvaluate = assignments.Where
(
    x => x.IsKind(SyntaxNode.SimpleAssignmentExpression) &&
    x.Ancestors().OfType<ConstructorDeclarationSyntax>().Any() &&
    !x.Ancestors().OfType<ConditionalExpressionSyntax>().Any()
).Select
(
    x => (Syntax: x, Operation: (IAssignmentOperation)semanticModel.GetOperation(x))
).Where
(
    x => x.Operation is ISimpleAssignmentOperation &&
    x.Operation.Target is IFieldReferenceOperation fieldRef &&
    SymbolEqualityComparer.Default.Equals(fieldRef, fieldToCheck)
)
if (!assignmentsToEvaluate.Any())
{
    // break/continue/return
}
var assignment = assignmentsToEvaluate.Last();
// parse assignment.Operation.Value (e.g., IArrayInitializaterOperation, IConversionOperation, IObjectCreationOperation)

Additional considerations

Inline assignment of related readonly fields is currently parsed manually. This will be addressed by #16.

Care will need to be taken to ensure that the ISimpleAssignmentOperation is not a descendant of an IConditionalOperation/ConditionalExpressionSyntax. After this issue is addressed, it should theoretically be possible to parse conditions which have a ConstantValue. Conditional expressions that do not have a ConstantValue cannot be parsed through static analysis. Initially, this issue should expressly disallow evaluating any assignments that exist inside of a conditional expression branch.

Metadata

Metadata

Assignees

Labels

obsoleteThis issue has been made obsolete by other changes

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions