@@ -241,19 +241,9 @@ protected override PropertySetAbstractValue VisitAssignmentOperation(IAssignment
241241 AnalysisEntity targetAnalysisEntity = null ;
242242 if ( operation . Target . Kind == OperationKind . FlowCaptureReference )
243243 {
244- PointsToAbstractValue lValuePointsToAbstractValue = this . GetPointsToAbstractValue ( operation . Target ) ;
245- if ( lValuePointsToAbstractValue . LValueCapturedOperations . Count == 1 )
244+ if ( this . TryUnwrapFlowCaptureReference ( operation . Target , out IOperation lValueOperation , OperationKind . PropertyReference , OperationKind . FieldReference ) )
246245 {
247- IOperation lValueOperation = lValuePointsToAbstractValue . LValueCapturedOperations . First ( ) ;
248- if ( lValueOperation . Kind == OperationKind . FieldReference
249- || lValueOperation . Kind == OperationKind . PropertyReference )
250- {
251- this . AnalysisEntityFactory . TryCreate ( lValueOperation , out targetAnalysisEntity ) ;
252- }
253- }
254- else
255- {
256- Debug . Fail ( "Can LValues FlowCaptureReferences have more than one operation?" ) ;
246+ this . AnalysisEntityFactory . TryCreate ( lValueOperation , out targetAnalysisEntity ) ;
257247 }
258248 }
259249 else
@@ -295,7 +285,14 @@ protected override PropertySetAbstractValue VisitAssignmentOperation(IAssignment
295285 }
296286 }
297287
298- if ( operation . Target is IPropertyReferenceOperation propertyReferenceOperation
288+ IPropertyReferenceOperation propertyReferenceOperation = operation . Target as IPropertyReferenceOperation ;
289+ if ( propertyReferenceOperation == null && operation . Target . Kind == OperationKind . FlowCaptureReference )
290+ {
291+ this . TryUnwrapFlowCaptureReference ( operation . Target , out IOperation lValue , OperationKind . PropertyReference ) ;
292+ propertyReferenceOperation = lValue as IPropertyReferenceOperation ;
293+ }
294+
295+ if ( propertyReferenceOperation != null
299296 && propertyReferenceOperation . Instance != null
300297 && this . TrackedTypeSymbols . Any ( s => propertyReferenceOperation . Instance . Type . GetBaseTypesAndThis ( ) . Contains ( s ) )
301298 && this . DataFlowAnalysisContext . PropertyMappers . TryGetPropertyMapper (
@@ -698,6 +695,37 @@ private void MergeInterproceduralResults(IOperation originalOperation)
698695 this . _visitedLambdas . Add ( lambdaOperation ) ;
699696 }
700697 }
698+
699+ /// <summary>
700+ /// Attempts to find the underlying IOperation that a flow capture reference refers to.
701+ /// </summary>
702+ /// <param name="flowCaptureReferenceOperation">Operation that may be a flow capture reference to look at.</param>
703+ /// <param name="unwrappedOperation">The found underlying operation, if any.</param>
704+ /// <param name="kinds">Kinds of operations to look for.</param>
705+ /// <returns>True if found, false otherwise.</returns>
706+ private bool TryUnwrapFlowCaptureReference ( IOperation flowCaptureReferenceOperation , out IOperation unwrappedOperation , params OperationKind [ ] kinds )
707+ {
708+ unwrappedOperation = null ;
709+ if ( flowCaptureReferenceOperation != null && flowCaptureReferenceOperation . Kind == OperationKind . FlowCaptureReference )
710+ {
711+ PointsToAbstractValue lValuePointsToAbstractValue = this . GetPointsToAbstractValue ( flowCaptureReferenceOperation ) ;
712+ if ( lValuePointsToAbstractValue . LValueCapturedOperations . Count == 1 )
713+ {
714+ IOperation lValueOperation = lValuePointsToAbstractValue . LValueCapturedOperations . First ( ) ;
715+ if ( kinds == null || kinds . Contains ( lValueOperation . Kind ) )
716+ {
717+ unwrappedOperation = lValueOperation ;
718+ return true ;
719+ }
720+ }
721+ else
722+ {
723+ Debug . Fail ( "Can LValues FlowCaptureReferences have more than one operation?" ) ;
724+ }
725+ }
726+
727+ return false ;
728+ }
701729 }
702730 }
703731}
0 commit comments