Exemplo n.º 1
0
 /// <summary>
 /// Get index of deconstruction result or tuple element
 /// Returns -1 on failure.
 /// </summary>
 int FindIndex(ILInstruction inst, out Action <DeconstructInstruction> delayedActions)
 {
     delayedActions = null;
     if (inst.MatchLdLoc(out var v))
     {
         if (!deconstructionResultsLookup.TryGetValue(v, out int index))
         {
             return(-1);
         }
         return(index);
     }
     if (inst.MatchLdFld(out _, out _))
     {
         if (!TupleTransform.MatchTupleFieldAccess((LdFlda)((LdObj)inst).Target, out var tupleType, out var target, out int index))
         {
             return(-1);
         }
         // Item fields are one-based, we use zero-based indexing.
         index--;
         // normalize tuple type
         tupleType = TupleType.FromUnderlyingType(context.TypeSystem, tupleType);
         if (!target.MatchLdLoca(out v))
         {
             return(-1);
         }
         if (this.tupleVariable == null)
         {
             this.tupleVariable         = v;
             this.tupleType             = (TupleType)tupleType;
             this.deconstructionResults = new ILVariable[this.tupleType.Cardinality];
         }
         if (this.tupleType.Cardinality < 2)
         {
             return(-1);
         }
         if (v != tupleVariable || !this.tupleType.Equals(tupleType))
         {
             return(-1);
         }
         if (this.deconstructionResults[index] == null)
         {
             var freshVar = new ILVariable(VariableKind.StackSlot, this.tupleType.ElementTypes[index])
             {
                 Name = "E_" + index
             };
             delayedActions += _ => context.Function.Variables.Add(freshVar);
             this.deconstructionResults[index] = freshVar;
         }
         delayedActions += _ => {
             inst.ReplaceWith(new LdLoc(this.deconstructionResults[index]));
         };
         return(index);
     }
     return(-1);
 }