Ejemplo n.º 1
0
 public override CodeNode VisitLoadFieldLocal(LoadFieldLocalNode node)
 {
     _Writer.WriteStartElement("LoadFieldLocal");
     _Writer.WriteAttributeString("FieldIndex", node.FieldIndex.ToString());
     _Writer.WriteEndElement();
     return(node);
 }
Ejemplo n.º 2
0
        CodeNode GenerateAssignment(KeyValuePair <FieldLayoutAttribute, PropertyInfo> pair)
        {
            var fieldType = pair.Key.FieldType;
            StringFieldLayoutAttribute stringLayout = pair.Key as StringFieldLayoutAttribute;
            ArrayFieldLayoutAttribute  arrayLayout  = pair.Key as ArrayFieldLayoutAttribute;

            //if it is an array, defer to GenerateArrayAssignment
            if (arrayLayout != null)
            {
                // TODO: Why do we need these fieldType checks at all?
                if (fieldType == typeof(string))
                {
                    // TODO: Accept string arrays
                    throw new InvalidOperationException(Resources.NoStringArrays);
                }
                if (fieldType == typeof(BitArray))
                {
                    throw new InvalidOperationException(Resources.NoBitArrayArrays);
                }
                return(GenerateArrayAssignment(pair));
            }

            var initNodes = new List <CodeNode>();

            bool localWasPresent = true;

            if (_FieldLocalsTouched.Add(pair.Key.FieldIndex))
            {
                localWasPresent = false;
                //add a create local node
                initNodes.Add(new CreateFieldLocalForWritingNode(pair.Key.FieldIndex, pair.Key.FieldType));
                _FieldLocalsTouched.Add(pair.Key.FieldIndex);
            }

            //find out if there is an optional field flag that we need to manage
            FieldLayoutAttribute        optionalFieldLayout          = null;
            FlaggedFieldLayoutAttribute currentAsOptionalFieldLayout = pair.Key as FlaggedFieldLayoutAttribute;

            if (currentAsOptionalFieldLayout != null)
            {
                optionalFieldLayout = _Fields[currentAsOptionalFieldLayout.FlagIndex].Key;
                if (_FieldLocalsTouched.Add(currentAsOptionalFieldLayout.FlagIndex))
                {
                    initNodes.Add(new CreateFieldLocalForWritingNode(currentAsOptionalFieldLayout.FlagIndex, optionalFieldLayout.FieldType));
                }
            }

            //this will hold a node that will write in the case we have no value to write
            CodeNode noValueWriteContingency = null;
            //this will hold the source of the write that will happen above
            CodeNode noValueWriteContingencySource = null;

            //Decide what to do if we don't have a value to write.
            //This will happen if we don't store the value in a property, it is "missing" from the property source, or something else
            //TODO: should these have a different precedence?
            if (pair.Key.MissingValue != null)
            {
                //if we have a missing value, set that as the write source
                noValueWriteContingencySource = new LoadMissingValueNode(pair.Key.MissingValue, fieldType);
            }
            else if (localWasPresent || optionalFieldLayout != null)
            {
                //if the local was present when we started, that means it was initialized by another field. We can safely write it
                //Similarly, if this is marked as an optional field, we can still write whatever the value of the local is (cheat)
                noValueWriteContingencySource = new LoadFieldLocalNode(pair.Key.FieldIndex);
            }
            else if (fieldType.IsValueType)
            {
                //if T is a value type, we're up a creek with nothing to write.
                //this is obviously not a good place, so throw in the converter
                noValueWriteContingency = new ThrowInvalidOperationNode(string.Format(Resources.NonNullableField, pair.Key.FieldIndex, _Type));
            }
            else
            {
                //otherwise, we can try to write null (unless it is a fixed-length string, which should have a default instead)
                if (stringLayout != null && stringLayout.Length > 0)
                {
                    //TODO: move this check into StdfStringLayout if we can, along with a check that the missing value length matches
                    throw new NotSupportedException(Resources.FixedLengthStringMustHaveDefault);
                }
                noValueWriteContingencySource = new LoadNullNode();
            }

            //create the write node and the no-value contingency if we don't already have one
            CodeNode writeNode;

            if (stringLayout != null && stringLayout.Length > 0)
            {
                noValueWriteContingency = noValueWriteContingency ?? new WriteFixedStringNode(stringLayout.Length, noValueWriteContingencySource);
                writeNode = new WriteFixedStringNode(stringLayout.Length, new LoadFieldLocalNode(pair.Key.FieldIndex));
            }
            else
            {
                noValueWriteContingency = noValueWriteContingency ?? new WriteTypeNode(fieldType, noValueWriteContingencySource);
                writeNode = new WriteTypeNode(fieldType, new LoadFieldLocalNode(pair.Key.FieldIndex));
            }
            //return the crazy node
            //TODO: refactor this better, this sucks
            return(new WriteFieldNode(pair.Key.FieldIndex, fieldType,
                                      initialization: new BlockNode(initNodes),
                                      sourceProperty: pair.Value,
                                      writeOperation: writeNode,
                                      noValueWriteContingency: noValueWriteContingency,
                                      optionalFieldIndex: optionalFieldLayout == null ? null : (int?)optionalFieldLayout.FieldIndex,
                                      optionalFieldMask: optionalFieldLayout == null ? (byte)0 : currentAsOptionalFieldLayout.FlagMask));
        }
Ejemplo n.º 3
0
 public virtual CodeNode VisitLoadFieldLocal(LoadFieldLocalNode node)
 {
     return(node);
 }
Ejemplo n.º 4
0
 public override CodeNode VisitLoadFieldLocal(LoadFieldLocalNode node)
 {
     Log($"Loading local var for field {node.FieldIndex}.");
     ILGen.Ldloc(_FieldLocals[node.FieldIndex]);
     return(node);
 }
 public override CodeNode VisitLoadFieldLocal(LoadFieldLocalNode node)
 {
     ILGen.Ldloc(_FieldLocals[node.FieldIndex]);
     return(node);
 }