Ejemplo n.º 1
0
        private void ProcessFieldReferenceOperation(IFieldReferenceOperation fieldOp)
        {
            if (fieldOp.Instance == null)
            {
                // Static members are not supported now
                // TODO: Report a warning
                return;
            }

            var referenceModel = this.TryGetVariableFromOperation(fieldOp.Instance) as ReferenceModel;

            if (referenceModel == null)
            {
                // Compute the reference in a separate node if it is not a variable
                referenceModel = (ReferenceModel)this.Context.CreateTemporaryVariableModel(
                    this.Context.ModelManager.TryGetFactory(fieldOp.Instance.Type),
                    fieldOp.Instance.Type);
                var referenceNode = this.Context.PrependCurrentNode(fieldOp.Instance.Syntax, DisplayNodeConfig.Inherit);
                referenceNode.VariableModel = referenceModel;
            }

            var fields = this.Context.ModelManager.TypeContext.GetFieldDefinitions(fieldOp.Field);

            if (this.Context.CurrentNode.VariableModel == null && this.Context.CurrentNode.Operation == null)
            {
                // Start by filling the left side of the assignment, if not filled already
                // (by a variable or an operation)
                this.Context.CurrentNode.Operation = new HeapOperation(
                    SpecialOperationKind.FieldWrite,
                    referenceModel,
                    fields);
            }
            else
            {
                Contract.Assert(this.Context.CurrentNode.ValueModel == null);

                // Otherwise, fill the right side of the assignment
                var readOp = new HeapOperation(SpecialOperationKind.FieldRead, referenceModel, fields);

                if (this.Context.CurrentNode.Operation == null)
                {
                    this.Context.CurrentNode.Operation = readOp;
                }
                else
                {
                    // If there is already an operation (such as field write), put the read to a new node
                    var readResult = this.Context.CreateTemporaryVariableModel(
                        this.Context.ModelManager.TryGetFactory(fieldOp.Type),
                        fieldOp.Type);
                    var readNode = this.Context.PrependCurrentNode(
                        fieldOp.Syntax,
                        DisplayNodeConfig.Inherit,
                        isFinal: true);
                    readNode.VariableModel = readResult;
                    readNode.Operation     = readOp;
                    this.Context.CurrentNode.ValueModel = readResult;
                }
            }
        }
Ejemplo n.º 2
0
        private IEnumerable <Operation> TranslateHeapOperations(
            ITypeModel variableModel,
            ITypeModel valueModel,
            HeapOperation heapOp)
        {
            if (heapOp.Kind == SpecialOperationKind.FieldRead)
            {
                if (variableModel == null)
                {
                    yield break;
                }

                var translatedReference = this.TranslateVariable(heapOp.Reference.AssignmentLeft.Single());
                var variables           = variableModel.AssignmentLeft;
                Contract.Assert(variables.Count == heapOp.Fields.Length);

                for (int i = 0; i < variables.Count; i++)
                {
                    Contract.Assert(variables[i].Sort == heapOp.Fields[i].Sort);

                    yield return(new FieldRead(
                                     this.TranslateVariable(variables[i]),
                                     translatedReference,
                                     heapOp.Fields[i]));
                }
            }
            else
            {
                Contract.Assert(heapOp.Kind == SpecialOperationKind.FieldWrite);

                if (valueModel == null)
                {
                    yield break;
                }

                var translatedReference = this.TranslateVariable(heapOp.Reference.AssignmentLeft.Single());
                var values = valueModel.AssignmentRight;
                Contract.Assert(values.Count == heapOp.Fields.Length);

                for (int i = 0; i < values.Count; i++)
                {
                    Contract.Assert(values[i].Sort == heapOp.Fields[i].Sort);

                    yield return(new FieldWrite(
                                     translatedReference,
                                     heapOp.Fields[i],
                                     this.TranslateExpression(values[i])));
                }
            }
        }