bool IDfirNodeVisitor <bool> .VisitExplicitBorrowNode(ExplicitBorrowNode explicitBorrowNode)
        {
            if (explicitBorrowNode.AlwaysCreateReference && explicitBorrowNode.AlwaysBeginLifetime)
            {
                bool     mutable        = explicitBorrowNode.BorrowMode == BorrowMode.Mutable;
                Lifetime borrowLifetime = explicitBorrowNode.OutputTerminals.First().DefineLifetimeThatIsBoundedByDiagram();
                TypeVariableReference borrowLifetimeType = _typeVariableSet.CreateReferenceToLifetimeType(borrowLifetime);

                foreach (var terminalPair in explicitBorrowNode.InputTerminals.Zip(explicitBorrowNode.OutputTerminals))
                {
                    Terminal inputTerminal = terminalPair.Key, outputTerminal = terminalPair.Value;
                    TypeVariableReference inputTypeVariable = _typeVariableSet.CreateReferenceToNewTypeVariable();
                    _nodeFacade[inputTerminal] = new SimpleTerminalFacade(inputTerminal, inputTypeVariable);
                    TypeVariableReference outputReferenceType = _typeVariableSet.CreateReferenceToReferenceType(mutable, inputTypeVariable, borrowLifetimeType);
                    _nodeFacade[outputTerminal] = new SimpleTerminalFacade(outputTerminal, outputReferenceType);
                }
            }
            else
            {
                // TODO
                throw new NotImplementedException();
            }

            return(true);
        }
        internal static void CreateTunnelNodeFacade(Tunnel tunnel)
        {
            AutoBorrowNodeFacade nodeFacade      = AutoBorrowNodeFacade.GetNodeFacade(tunnel);
            TypeVariableSet      typeVariableSet = tunnel.DfirRoot.GetTypeVariableSet();

            TypeVariableReference typeVariable;

            bool executesConditionally = tunnel.ParentStructure.DoesStructureExecuteConditionally();

            if (executesConditionally && tunnel.Direction == Direction.Output)
            {
                Terminal valueInput  = tunnel.InputTerminals.ElementAt(0),
                         valueOutput = tunnel.OutputTerminals.ElementAt(0);

                typeVariable            = typeVariableSet.CreateReferenceToNewTypeVariable();
                nodeFacade[valueOutput] = new SimpleTerminalFacade(valueOutput, typeVariable);
                nodeFacade[valueInput]  = new TunnelTerminalFacade(valueInput, nodeFacade[valueOutput]);
            }
            else
            {
                List <Constraint> constraints = new List <Constraint>();
                if (tunnel.Direction == Direction.Output)
                {
                    // TODO: for multi-diagram structures, each diagram should share a lifetime related to the entire structure
                    LifetimeGraphIdentifier parentLifetimeGraph = tunnel.InputTerminals[0].ParentDiagram.GetLifetimeGraphIdentifier();
                    constraints.Add(new OutlastsLifetimeGraphConstraint(parentLifetimeGraph));
                }
                typeVariable = typeVariableSet.CreateReferenceToNewTypeVariable(constraints);
                foreach (Terminal terminal in tunnel.Terminals)
                {
                    nodeFacade[terminal] = new SimpleTerminalFacade(terminal, typeVariable);
                }
            }
        }
            private void InsertStringToSliceAheadOfTerminal(Terminal sliceReceiver, out VariableReference stringReferenceVariable, out Terminal stringReferenceTerminal)
            {
                FunctionalNode stringToSlice                = new FunctionalNode(sliceReceiver.ParentDiagram, Signatures.StringToSliceType);
                Terminal       stringToSliceInput           = stringToSlice.InputTerminals[0],
                               stringToSliceOutput          = stringToSlice.OutputTerminals[0];
                VariableReference sliceReceiverTrueVariable = sliceReceiver.GetTrueVariable();

                TypeVariableSet       typeVariableSet = stringToSliceInput.GetTypeVariableSet();
                TypeVariableReference stringSliceReferenceType = sliceReceiverTrueVariable.TypeVariableReference;
                TypeVariableReference u, lifetime;
                bool m;

                typeVariableSet.TryDecomposeReferenceType(stringSliceReferenceType, out u, out lifetime, out m);
                TypeVariableReference stringReferenceType = typeVariableSet.CreateReferenceToReferenceType(
                    false,
                    typeVariableSet.CreateReferenceToLiteralType(PFTypes.String),
                    lifetime);

                AutoBorrowNodeFacade stringToSliceFacade = AutoBorrowNodeFacade.GetNodeFacade(stringToSlice);

                stringToSliceFacade[stringToSliceInput]  = new SimpleTerminalFacade(stringToSliceInput, stringReferenceType);
                stringToSliceFacade[stringToSliceOutput] = new SimpleTerminalFacade(stringToSliceOutput, default(TypeVariableReference));

                sliceReceiver.ConnectedTerminal.ConnectTo(stringToSliceInput);
                stringToSliceOutput.WireTogether(sliceReceiver, SourceModelIdSource.NoSourceModelId);

                stringToSliceOutput.GetFacadeVariable().MergeInto(sliceReceiverTrueVariable);
                stringReferenceVariable = stringToSliceInput.GetFacadeVariable();
                stringReferenceTerminal = stringToSliceInput;
            }
        bool IDfirNodeVisitor <bool> .VisitIterateTunnel(IterateTunnel iterateTunnel)
        {
            Terminal iteratorInput = iterateTunnel.InputTerminals.ElementAt(0),
                     itemOutput    = iterateTunnel.OutputTerminals.ElementAt(0);
            LifetimeTypeVariableGroup lifetimeTypeVariableGroup = LifetimeTypeVariableGroup.CreateFromTerminal(iteratorInput);

            TypeVariableReference loopLifetimeReference          = _typeVariableSet.CreateReferenceToLifetimeType(itemOutput.GetDiagramLifetime());
            TypeVariableReference itemTypeVariable               = _typeVariableSet.CreateReferenceToNewTypeVariable();
            TypeVariableReference implementsIteratorTypeVariable = _typeVariableSet.CreateReferenceToNewTypeVariable(
                new Constraint[] { new IteratorTraitConstraint(itemTypeVariable) });
            ReferenceInputTerminalLifetimeGroup group = CreateTerminalLifetimeGroup(InputReferenceMutability.RequireMutable, lifetimeTypeVariableGroup);

            group.AddTerminalFacade(iteratorInput, implementsIteratorTypeVariable, default(TypeVariableReference));

            _nodeFacade[itemOutput] = new SimpleTerminalFacade(itemOutput, itemTypeVariable);

            TypeVariableReference intermediateTypeVariable = _typeVariableSet.CreateReferenceToOptionType(itemTypeVariable);
            VariableReference     intermediateVariable     = iterateTunnel.GetVariableSet().CreateNewVariable(
                iterateTunnel.ParentStructure.ParentDiagram.GetLifetimeGraphIdentifier().Id,
                intermediateTypeVariable,
                false);

            intermediateVariable.Name = iterateTunnel.IntermediateValueName;
            iterateTunnel.IntermediateValueVariable = intermediateVariable;

            iterateTunnel.IteratorNextFunctionType = new FunctionType(
                Signatures.IteratorNextType,
                new TypeVariableReference[]
            {
                implementsIteratorTypeVariable,
                itemTypeVariable,
                group.LifetimeType
            });
            return(true);
        }
        bool IDfirNodeVisitor <bool> .VisitDropNode(DropNode dropNode)
        {
            Terminal valueInput = dropNode.InputTerminals.ElementAt(0);
            TypeVariableReference dataTypeVariable = _typeVariableSet.CreateReferenceToNewTypeVariable();

            _nodeFacade[valueInput] = new SimpleTerminalFacade(valueInput, dataTypeVariable);
            return(true);
        }
Esempio n. 6
0
        private void CreateDefaultFacadeForOutputNodeTerminal(Node outputNode, NIType outputTerminalType)
        {
            AutoBorrowNodeFacade outputNodeFacade = AutoBorrowNodeFacade.GetNodeFacade(outputNode);
            Terminal             outputTerminal   = outputNode.OutputTerminals[0];

            outputNodeFacade[outputTerminal] = new SimpleTerminalFacade(
                outputTerminal,
                outputNode.GetTypeVariableSet().CreateTypeVariableReferenceFromNIType(outputTerminalType));
        }
Esempio n. 7
0
        public static TerminateLifetimeNode CreateTerminateLifetimeWithFacades(Diagram parentDiagram, int inputs, int outputs)
        {
            var terminateLifetime = new TerminateLifetimeNode(parentDiagram, inputs, outputs);
            AutoBorrowNodeFacade terminateLifetimeFacade = AutoBorrowNodeFacade.GetNodeFacade(terminateLifetime);

            foreach (var terminal in terminateLifetime.Terminals)
            {
                terminateLifetimeFacade[terminal] = new SimpleTerminalFacade(terminal, default(TypeVariableReference));
            }
            return(terminateLifetime);
        }
Esempio n. 8
0
        internal static void InsertDropForVariable(Diagram parentDiagram, LiveVariable liveUnboundedLifetimeVariable, ITypeUnificationResultFactory unificationResultFactory)
        {
            var                  drop          = new DropNode(parentDiagram);
            Terminal             inputTerminal = drop.InputTerminals[0];
            AutoBorrowNodeFacade nodeFacade    = AutoBorrowNodeFacade.GetNodeFacade(drop);

            nodeFacade[inputTerminal] = new SimpleTerminalFacade(
                inputTerminal,
                parentDiagram.GetTypeVariableSet().CreateReferenceToNewTypeVariable());

            liveUnboundedLifetimeVariable.ConnectToTerminalAsInputAndUnifyVariables(inputTerminal, unificationResultFactory);
        }
        bool IDfirNodeVisitor <bool> .VisitUnwrapOptionTunnel(UnwrapOptionTunnel unwrapOptionTunnel)
        {
            Terminal optionInput     = unwrapOptionTunnel.InputTerminals[0],
                     unwrappedOutput = unwrapOptionTunnel.OutputTerminals[0];
            TypeVariableReference innerTypeVariable = _typeVariableSet.CreateReferenceToNewTypeVariable();

            _nodeFacade[optionInput] = new SimpleTerminalFacade(
                optionInput,
                _typeVariableSet.CreateReferenceToOptionType(innerTypeVariable));
            _nodeFacade[unwrappedOutput] = new SimpleTerminalFacade(unwrappedOutput, innerTypeVariable);
            return(true);
        }
        bool IDfirNodeVisitor <bool> .VisitOptionPatternStructureSelector(OptionPatternStructureSelector optionPatternStructureSelector)
        {
            Terminal selectorInput      = optionPatternStructureSelector.InputTerminals[0],
                     selectorSomeOutput = optionPatternStructureSelector.OutputTerminals[0];

            TypeVariableReference innerTypeVariable  = _typeVariableSet.CreateReferenceToNewTypeVariable(),
                                  outerTypeReference = _typeVariableSet.CreateReferenceToOptionType(innerTypeVariable);

            _nodeFacade[selectorInput]      = new SimpleTerminalFacade(selectorInput, outerTypeReference);
            _nodeFacade[selectorSomeOutput] = new SimpleTerminalFacade(selectorSomeOutput, innerTypeVariable);
            return(true);
        }
        public void CreateBorrowAndTerminateLifetimeNodes(LifetimeVariableAssociation lifetimeVariableAssociation)
        {
            if (_borrowRequired)
            {
                Node                 parentNode         = _facades.First().Terminal.ParentNode;
                BorrowMode           borrowMode         = _mutableBorrow ? BorrowMode.Mutable : BorrowMode.Immutable;
                int                  borrowInputCount   = _facades.Count;
                Diagram              inputParentDiagram = _facades.First().Terminal.ParentDiagram;
                var                  explicitBorrow     = new ExplicitBorrowNode(inputParentDiagram, borrowMode, borrowInputCount, true, false);
                AutoBorrowNodeFacade borrowNodeFacade   = AutoBorrowNodeFacade.GetNodeFacade(explicitBorrow);
                foreach (var terminal in explicitBorrow.Terminals)
                {
                    borrowNodeFacade[terminal] = new SimpleTerminalFacade(terminal, default(TypeVariableReference));
                }

                int index = 0;
                foreach (var facade in _facades)
                {
                    Terminal          input = facade.Terminal;
                    VariableReference ownerVariable = input.GetFacadeVariable(), borrowVariable;
                    ((AutoborrowingInputTerminalFacade)facade).AddPostBorrowCoercion(ref input, out borrowVariable);
                    InsertBorrowAheadOfTerminal(input, explicitBorrow, index, ownerVariable, borrowVariable);
                    ++index;
                }

                List <TerminateLifetimeOutputTerminalFacade> terminates = new List <TerminateLifetimeOutputTerminalFacade>();
                foreach (var terminal in parentNode.OutputTerminals)
                {
                    var terminateFacade = _nodeFacade[terminal] as TerminateLifetimeOutputTerminalFacade;
                    if (terminateFacade != null && _facades.Contains(terminateFacade.InputFacade))
                    {
                        terminates.Add(terminateFacade);
                    }
                }

                if (terminates.Count == borrowInputCount)
                {
                    Diagram outputParentDiagram = terminates.First().Terminal.ParentDiagram;
                    var     terminateLifetime   = TerminateLifetimeNodeHelpers.CreateTerminateLifetimeWithFacades(outputParentDiagram, borrowInputCount, borrowInputCount);

                    index = 0;
                    foreach (var terminate in terminates)
                    {
                        InsertTerminateLifetimeBehindTerminal(terminate.Terminal, terminateLifetime, index, lifetimeVariableAssociation);
                        ++index;
                    }
                }
                else if (terminates.Count > 0)
                {
                    throw new InvalidOperationException("Mismatched terminates and borrows; not sure what to do");
                }
            }
        }
        bool IDfirNodeVisitor <bool> .VisitTerminateLifetimeTunnel(TerminateLifetimeTunnel terminateLifetimeTunnel)
        {
            Terminal valueOutput = terminateLifetimeTunnel.OutputTerminals.ElementAt(0);
            var      valueFacade = new SimpleTerminalFacade(valueOutput, default(TypeVariableReference));

            _nodeFacade[valueOutput] = valueFacade;

            NationalInstruments.Dfir.BorderNode beginLifetimeBorderNode = (NationalInstruments.Dfir.BorderNode)terminateLifetimeTunnel.BeginLifetimeTunnel;
            Terminal beginLifetimeTerminal = beginLifetimeBorderNode.GetOuterTerminal(0);

            valueFacade.FacadeVariable.MergeInto(beginLifetimeTerminal.GetFacadeVariable());
            return(true);
        }
        bool IDfirNodeVisitor <bool> .VisitVariantConstructorNode(VariantConstructorNode variantConstructorNode)
        {
            Terminal inputTerminal  = variantConstructorNode.InputTerminals[0],
                     outputTerminal = variantConstructorNode.OutputTerminals[0];
            NIType elementType      = variantConstructorNode.VariantType.GetFields().ElementAt(variantConstructorNode.SelectedFieldIndex).GetDataType();

            _nodeFacade[inputTerminal] = new SimpleTerminalFacade(
                inputTerminal,
                _typeVariableSet.CreateTypeVariableReferenceFromNIType(elementType));
            _nodeFacade[outputTerminal] = new SimpleTerminalFacade(
                outputTerminal,
                _typeVariableSet.CreateTypeVariableReferenceFromNIType(variantConstructorNode.VariantType));
            return(true);
        }
Esempio n. 14
0
        private T ConnectNewNodeToOutputTerminal <T>(Node outputTerminalOwner, Func <Diagram, T> createNode) where T : Node
        {
            var nodeToConnect = createNode(outputTerminalOwner.ParentDiagram);
            AutoBorrowNodeFacade nodeToConnectFacade = AutoBorrowNodeFacade.GetNodeFacade(nodeToConnect);
            Terminal             inputTerminal       = nodeToConnect.InputTerminals[0];

            nodeToConnectFacade[inputTerminal] = new SimpleTerminalFacade(
                inputTerminal,
                outputTerminalOwner.GetTypeVariableSet().CreateReferenceToNewTypeVariable());
            Terminal outputTerminal = outputTerminalOwner.OutputTerminals[0];

            new LiveVariable(outputTerminal.GetTrueVariable(), outputTerminal)
            .ConnectToTerminalAsInputAndUnifyVariables(inputTerminal, _unificationResultFactory);
            return(nodeToConnect);
        }
        bool IDfirNodeVisitor <bool> .VisitStructConstructorNode(StructConstructorNode structConstructorNode)
        {
            NIType structType = structConstructorNode.Type;

            foreach (var pair in structConstructorNode.InputTerminals.Zip(structType.GetFields()))
            {
                Terminal inputTerminal = pair.Key;
                _nodeFacade[inputTerminal] = new SimpleTerminalFacade(
                    inputTerminal,
                    _typeVariableSet.CreateTypeVariableReferenceFromNIType(pair.Value.GetDataType()));
            }
            _nodeFacade[structConstructorNode.OutputTerminals[0]] = new SimpleTerminalFacade(
                structConstructorNode.OutputTerminals[0],
                _typeVariableSet.CreateTypeVariableReferenceFromNIType(structType));
            return(true);
        }
        bool IDfirNodeVisitor <bool> .VisitBorrowTunnel(BorrowTunnel borrowTunnel)
        {
            // T -> &'a (mode) T
            Terminal valueInput   = borrowTunnel.InputTerminals.ElementAt(0),
                     borrowOutput = borrowTunnel.OutputTerminals.ElementAt(0);
            TypeVariableReference dataTypeVariable = _typeVariableSet.CreateReferenceToNewTypeVariable();
            Lifetime innerLifetime = borrowOutput.GetDiagramLifetime();
            TypeVariableReference referenceType = _typeVariableSet.CreateReferenceToReferenceType(
                borrowTunnel.BorrowMode == BorrowMode.Mutable,
                dataTypeVariable,
                _typeVariableSet.CreateReferenceToLifetimeType(innerLifetime));

            _nodeFacade[valueInput]   = new SimpleTerminalFacade(valueInput, dataTypeVariable);
            _nodeFacade[borrowOutput] = new SimpleTerminalFacade(borrowOutput, referenceType);
            return(true);
        }
        bool IDfirNodeVisitor <bool> .VisitDecomposeTupleNode(DecomposeTupleNode decomposeTupleNode)
        {
            TypeVariableReference[]             elementTypes       = new TypeVariableReference[decomposeTupleNode.OutputTerminals.Count];
            TypeVariableReference               mutabilityType     = default(TypeVariableReference);
            ReferenceInputTerminalLifetimeGroup inputTerminalGroup = null;

            if (decomposeTupleNode.DecomposeMode == DecomposeMode.Borrow)
            {
                mutabilityType = _typeVariableSet.CreateReferenceToMutabilityType();
                var lifetimeVariableGroup = LifetimeTypeVariableGroup.CreateFromNode(decomposeTupleNode);
                inputTerminalGroup = _nodeFacade.CreateInputLifetimeGroup(
                    InputReferenceMutability.Polymorphic,
                    lifetimeVariableGroup.LazyNewLifetime,
                    lifetimeVariableGroup.LifetimeType);
            }

            for (int i = 0; i < decomposeTupleNode.OutputTerminals.Count; ++i)
            {
                Terminal outputTerminal                  = decomposeTupleNode.OutputTerminals[i];
                TypeVariableReference elementType        = _typeVariableSet.CreateReferenceToNewTypeVariable();
                TypeVariableReference outputTerminalType = decomposeTupleNode.DecomposeMode == DecomposeMode.Borrow
                    ? _typeVariableSet.CreateReferenceToPolymorphicReferenceType(
                    mutabilityType,
                    elementType,
                    inputTerminalGroup.LifetimeType)
                    : elementType;
                _nodeFacade[outputTerminal] = new SimpleTerminalFacade(outputTerminal, outputTerminalType);
                elementTypes[i]             = elementType;
            }

            TypeVariableReference tupleType = _typeVariableSet.CreateReferenceToTupleType(elementTypes);
            Terminal inputTerminal          = decomposeTupleNode.InputTerminals[0];

            if (decomposeTupleNode.DecomposeMode == DecomposeMode.Borrow)
            {
                inputTerminalGroup.AddTerminalFacade(
                    inputTerminal,
                    tupleType,
                    mutabilityType);
            }
            else
            {
                _nodeFacade[inputTerminal] = new SimpleTerminalFacade(inputTerminal, tupleType);
            }
            return(true);
        }
        public void Execute(DfirRoot dfirRoot, CompileCancellationToken cancellationToken)
        {
            LiveVariable liveUnboundedLifetimeVariable;

            while (_lifetimeVariableAssociation.TryGetLiveVariableWithUnboundedLifetime(out liveUnboundedLifetimeVariable))
            {
                Diagram              parentDiagram = liveUnboundedLifetimeVariable.Terminal.ParentDiagram;
                var                  drop          = new DropNode(parentDiagram);
                Terminal             inputTerminal = drop.InputTerminals[0];
                AutoBorrowNodeFacade nodeFacade    = AutoBorrowNodeFacade.GetNodeFacade(drop);
                nodeFacade[inputTerminal] = new SimpleTerminalFacade(inputTerminal, default(TypeVariableReference));

                Wire.Create(parentDiagram, liveUnboundedLifetimeVariable.Terminal, inputTerminal);
                inputTerminal.GetFacadeVariable().MergeInto(liveUnboundedLifetimeVariable.Variable);
                _lifetimeVariableAssociation.MarkVariableConsumed(liveUnboundedLifetimeVariable.Variable);
            }
        }
        bool IDfirNodeVisitor <bool> .VisitBuildTupleNode(BuildTupleNode buildTupleNode)
        {
            TypeVariableReference[] elementTypes = new TypeVariableReference[buildTupleNode.InputTerminals.Count];
            for (int i = 0; i < buildTupleNode.InputTerminals.Count; ++i)
            {
                Terminal inputTerminal = buildTupleNode.InputTerminals[i];
                // TODO: constrain these to be unbounded lifetime
                TypeVariableReference elementType = _typeVariableSet.CreateReferenceToNewTypeVariable();
                _nodeFacade[inputTerminal] = new SimpleTerminalFacade(inputTerminal, elementType);
                elementTypes[i]            = elementType;
            }
            TypeVariableReference tupleType = _typeVariableSet.CreateReferenceToTupleType(elementTypes);
            Terminal outputTerminal         = buildTupleNode.OutputTerminals[0];

            _nodeFacade[outputTerminal] = new SimpleTerminalFacade(outputTerminal, tupleType);
            return(true);
        }
        bool IDfirNodeVisitor <bool> .VisitLoopConditionTunnel(LoopConditionTunnel loopConditionTunnel)
        {
            // TODO: how to determine the mutability of the outer loop condition variable?
            Terminal loopConditionInput  = loopConditionTunnel.InputTerminals.ElementAt(0),
                     loopConditionOutput = loopConditionTunnel.OutputTerminals.ElementAt(0);

            TypeVariableReference boolType = _typeVariableSet.CreateTypeVariableReferenceFromNIType(NITypes.Boolean);

            _nodeFacade[loopConditionInput] = new SimpleTerminalFacade(loopConditionInput, boolType);
            Lifetime innerLifetime = loopConditionOutput.GetDiagramLifetime();
            TypeVariableReference boolReferenceType = _typeVariableSet.CreateReferenceToReferenceType(
                true,
                boolType,
                _typeVariableSet.CreateReferenceToLifetimeType(innerLifetime));

            _nodeFacade[loopConditionOutput] = new SimpleTerminalFacade(loopConditionOutput, boolReferenceType);
            return(true);
        }
        bool IDfirNodeVisitor <bool> .VisitIterateTunnel(IterateTunnel iterateTunnel)
        {
            Terminal iteratorInput = iterateTunnel.InputTerminals.ElementAt(0),
                     itemOutput    = iterateTunnel.OutputTerminals.ElementAt(0);
            LifetimeTypeVariableGroup lifetimeTypeVariableGroup = LifetimeTypeVariableGroup.CreateFromTerminal(iteratorInput);

            TypeVariableReference loopLifetimeReference          = _typeVariableSet.CreateReferenceToLifetimeType(itemOutput.GetDiagramLifetime());
            TypeVariableReference itemTypeVariable               = _typeVariableSet.CreateReferenceToNewTypeVariable();
            TypeVariableReference implementsIteratorTypeVariable = _typeVariableSet.CreateReferenceToNewTypeVariable(
                new Constraint[] { new IteratorTraitConstraint(itemTypeVariable) });

            _nodeFacade
            .CreateInputLifetimeGroup(InputReferenceMutability.RequireMutable, lifetimeTypeVariableGroup.LazyNewLifetime, lifetimeTypeVariableGroup.LifetimeType)
            .AddTerminalFacade(iteratorInput, implementsIteratorTypeVariable, default(TypeVariableReference));

            _nodeFacade[itemOutput] = new SimpleTerminalFacade(itemOutput, itemTypeVariable);
            return(true);
        }
Esempio n. 22
0
        public static DecomposeStructNode CreateDecomposeStructNodeWithFacades(Diagram parentDiagram, NIType structType)
        {
            var decomposeStructNode              = new DecomposeStructNode(parentDiagram, structType);
            AutoBorrowNodeFacade nodeFacade      = AutoBorrowNodeFacade.GetNodeFacade(decomposeStructNode);
            TypeVariableSet      typeVariableSet = parentDiagram.GetTypeVariableSet();

            foreach (var pair in decomposeStructNode.OutputTerminals.Zip(structType.GetFields()))
            {
                Terminal outputTerminal = pair.Key;
                NIType   elementType    = pair.Value.GetDataType();
                TypeVariableReference elementTypeVariable = typeVariableSet.CreateTypeVariableReferenceFromNIType(elementType);
                nodeFacade[outputTerminal] = new SimpleTerminalFacade(outputTerminal, elementTypeVariable);
            }

            TypeVariableReference structTypeVariable = typeVariableSet.CreateTypeVariableReferenceFromNIType(structType);
            Terminal inputTerminal = decomposeStructNode.InputTerminals[0];

            nodeFacade[inputTerminal] = new SimpleTerminalFacade(inputTerminal, structTypeVariable);
            return(decomposeStructNode);
        }
        bool IDfirNodeVisitor <bool> .VisitLockTunnel(LockTunnel lockTunnel)
        {
            Terminal lockInput       = lockTunnel.InputTerminals.ElementAt(0),
                     referenceOutput = lockTunnel.OutputTerminals.ElementAt(0);
            LifetimeTypeVariableGroup lifetimeTypeVariableGroup = LifetimeTypeVariableGroup.CreateFromTerminal(lockInput);
            TypeVariableReference     dataVariableType          = _typeVariableSet.CreateReferenceToNewTypeVariable();
            TypeVariableReference     lockType = _typeVariableSet.CreateReferenceToLockingCellType(dataVariableType);

            CreateTerminalLifetimeGroup(InputReferenceMutability.AllowImmutable, lifetimeTypeVariableGroup)
            .AddTerminalFacade(lockInput, lockType, default(TypeVariableReference));

            Lifetime innerLifetime = referenceOutput.GetDiagramLifetime();
            TypeVariableReference referenceType = _typeVariableSet.CreateReferenceToReferenceType(
                true,
                lockType,
                _typeVariableSet.CreateReferenceToLifetimeType(innerLifetime));

            _nodeFacade[referenceOutput] = new SimpleTerminalFacade(referenceOutput, referenceType);
            return(true);
        }
        bool IDfirNodeVisitor <bool> .VisitVariantMatchStructureSelector(VariantMatchStructureSelector variantMatchStructureSelector)
        {
            var fieldTypes = new Dictionary <string, TypeVariableReference>();
            int fieldIndex = 0;

            foreach (var outputTerminal in variantMatchStructureSelector.OutputTerminals)
            {
                string fieldName = $"_{fieldIndex}";
                TypeVariableReference fieldType = _typeVariableSet.CreateReferenceToNewTypeVariable();
                fieldTypes[fieldName]       = fieldType;
                _nodeFacade[outputTerminal] = new SimpleTerminalFacade(outputTerminal, fieldType);
                ++fieldIndex;
            }

            TypeVariableReference fieldedType = _typeVariableSet.CreateReferenceToIndefiniteFieldedType(fieldTypes);
            Terminal inputTerminal            = variantMatchStructureSelector.InputTerminals[0];

            _nodeFacade[inputTerminal] = new SimpleTerminalFacade(inputTerminal, fieldedType);
            return(true);
        }
        bool IDfirNodeVisitor <bool> .VisitConstant(Constant constant)
        {
            Terminal valueOutput = constant.OutputTerminals.ElementAt(0);
            TypeVariableReference constantTypeReference;

            if (constant.DataType.IsRebarReferenceType())
            {
                constantTypeReference = _typeVariableSet.CreateReferenceToReferenceType(
                    false,
                    // TODO: this is not always correct; need a more general way of turning NITypes into TypeVariableReferences
                    _typeVariableSet.CreateTypeVariableReferenceFromNIType(constant.DataType.GetReferentType()),
                    // Assume for now that the reference will be in Lifetime.Static
                    _typeVariableSet.CreateReferenceToLifetimeType(Lifetime.Static));
            }
            else
            {
                constantTypeReference = _typeVariableSet.CreateTypeVariableReferenceFromNIType(constant.DataType);
            }
            _nodeFacade[valueOutput] = new SimpleTerminalFacade(valueOutput, constantTypeReference);
            return(true);
        }
        bool IDfirNodeVisitor <bool> .VisitStructFieldAccessorNode(StructFieldAccessorNode structFieldAccessorNode)
        {
            TypeVariableReference mutabilityType = _typeVariableSet.CreateReferenceToMutabilityType();
            var lifetimeVariableGroup            = LifetimeTypeVariableGroup.CreateFromNode(structFieldAccessorNode);
            ReferenceInputTerminalLifetimeGroup inputTerminalGroup = CreateTerminalLifetimeGroup(
                InputReferenceMutability.Polymorphic,
                lifetimeVariableGroup);

            var fieldTypes = new Dictionary <string, TypeVariableReference>();

            foreach (var terminalPair in structFieldAccessorNode.OutputTerminals.Zip(structFieldAccessorNode.FieldNames))
            {
                string fieldName = terminalPair.Value;
                TypeVariableReference fieldType;
                if (string.IsNullOrEmpty(fieldName))
                {
                    fieldType = _typeVariableSet.CreateReferenceToNewTypeVariable();
                }
                else if (!fieldTypes.TryGetValue(fieldName, out fieldType))
                {
                    fieldType             = _typeVariableSet.CreateReferenceToNewTypeVariable();
                    fieldTypes[fieldName] = fieldType;
                }
                TypeVariableReference terminalTypeVariable = _typeVariableSet.CreateReferenceToPolymorphicReferenceType(
                    mutabilityType,
                    fieldType,
                    inputTerminalGroup.LifetimeType);
                Terminal outputTerminal = terminalPair.Key;
                _nodeFacade[outputTerminal] = new SimpleTerminalFacade(outputTerminal, terminalTypeVariable);
            }

            TypeVariableReference fieldedType = _typeVariableSet.CreateReferenceToIndefiniteFieldedType(fieldTypes);

            inputTerminalGroup.AddTerminalFacade(
                structFieldAccessorNode.StructInputTerminal,
                fieldedType,
                mutabilityType);

            return(true);
        }
Esempio n. 27
0
        private static void CreateFacadesForDecomposeTupleNode(this DecomposeTupleNode decomposeTupleNode, TypeVariableSet typeVariableSet)
        {
            if (decomposeTupleNode.DecomposeMode == DecomposeMode.Borrow)
            {
                throw new NotSupportedException();
            }
            TypeVariableReference[] elementTypes = new TypeVariableReference[decomposeTupleNode.OutputTerminals.Count];
            AutoBorrowNodeFacade    nodeFacade   = AutoBorrowNodeFacade.GetNodeFacade(decomposeTupleNode);

            for (int i = 0; i < decomposeTupleNode.OutputTerminals.Count; ++i)
            {
                Terminal outputTerminal           = decomposeTupleNode.OutputTerminals[i];
                TypeVariableReference elementType = typeVariableSet.CreateReferenceToNewTypeVariable();
                nodeFacade[outputTerminal] = new SimpleTerminalFacade(outputTerminal, elementType);
                elementTypes[i]            = elementType;
            }

            TypeVariableReference tupleType = typeVariableSet.CreateReferenceToTupleType(elementTypes);
            Terminal inputTerminal          = decomposeTupleNode.InputTerminals[0];

            nodeFacade[inputTerminal] = new SimpleTerminalFacade(inputTerminal, tupleType);
        }
        protected override void VisitWire(Wire wire)
        {
            TypeVariableReference wireTypeVariable;
            var constraints = new List <Constraint>();

            if (wire.SinkTerminals.HasMoreThan(1))
            {
                constraints.Add(new SimpleTraitConstraint("Copy"));
            }
            wireTypeVariable = _typeVariableSet.CreateReferenceToNewTypeVariable(constraints);

            AutoBorrowNodeFacade wireFacade = AutoBorrowNodeFacade.GetNodeFacade(wire);

            foreach (var terminal in wire.Terminals)
            {
                wireFacade[terminal] = new SimpleTerminalFacade(terminal, wireTypeVariable);
            }
            Terminal sourceTerminal, firstSinkTerminal;

            if (wire.TryGetSourceTerminal(out sourceTerminal) && (firstSinkTerminal = wire.SinkTerminals.FirstOrDefault()) != null)
            {
                wireFacade[firstSinkTerminal].FacadeVariable.MergeInto(wireFacade[sourceTerminal].FacadeVariable);
            }
        }
Esempio n. 29
0
        private void DecomposeMethodCall(MethodCallNode methodCallNode, bool isYielding, bool mayPanic)
        {
            NIType outputType;
            // TODO: try to use something like Unit or Void
            NIType emptyOutputType = NITypes.Boolean;

            switch (methodCallNode.OutputTerminals.Count)
            {
            case 0:
                outputType = emptyOutputType;
                break;

            case 1:
                outputType = methodCallNode.OutputTerminals[0].GetTrueVariable().Type;
                break;

            default:
                outputType = methodCallNode.OutputTerminals.Select(t => t.GetTrueVariable().Type).DefineTupleType();
                break;
            }

            AutoBorrowNodeFacade methodCallNodeFacade = AutoBorrowNodeFacade.GetNodeFacade(methodCallNode);
            AwaitNode            awaitNode            = null;

            if (isYielding)
            {
                CreateMethodCallPromise createMethodCallPromise       = new CreateMethodCallPromise(methodCallNode.ParentDiagram, methodCallNode.Signature, methodCallNode.TargetName);
                AutoBorrowNodeFacade    createMethodCallPromiseFacade = AutoBorrowNodeFacade.GetNodeFacade(createMethodCallPromise);
                foreach (var terminalPair in methodCallNode.InputTerminals.Zip(createMethodCallPromise.InputTerminals))
                {
                    Terminal methodCallTerminal = terminalPair.Key, createMethodCallPromiseTerminal = terminalPair.Value;
                    methodCallTerminal.ConnectedTerminal.ConnectTo(createMethodCallPromiseTerminal);
                    createMethodCallPromiseFacade[createMethodCallPromiseTerminal] = methodCallNodeFacade[methodCallTerminal];
                }

                Terminal methodCallOutputTerminal = methodCallNode.OutputTerminals.FirstOrDefault();
                NIType   awaitOutputType          = mayPanic ? outputType.CreatePanicResult() : outputType;
                NIType   promiseType     = awaitOutputType.CreateMethodCallPromise();
                Terminal promiseTerminal = createMethodCallPromise.OutputTerminals[0];
                createMethodCallPromiseFacade[promiseTerminal] = new SimpleTerminalFacade(
                    promiseTerminal,
                    createMethodCallPromise.GetTypeVariableSet().CreateTypeVariableReferenceFromNIType(promiseType));

                awaitNode = ConnectNewNodeToOutputTerminalWithOutputFacade(createMethodCallPromise, diagram => new AwaitNode(diagram), awaitOutputType);
                VariableSet           variableSet            = awaitNode.GetVariableSet();
                TypeVariableReference outputTypeVariable     = awaitNode.OutputTerminal.GetTrueVariable().TypeVariableReference;
                TypeVariableReference pollResultTypeVariable = variableSet.TypeVariableSet.CreateReferenceToOptionType(outputTypeVariable);
                awaitNode.PollResultVariable = variableSet.CreateNewVariable(
                    diagramId: 0,
                    variableType: pollResultTypeVariable,
                    mutable: false);
            }

            Node outputNode = awaitNode;

            if (mayPanic)
            {
                Node panicOrContinueInput = awaitNode;
                if (!isYielding)
                {
                    // Create PanickingMethodCall as input to PanicOrContinue
                    throw new NotImplementedException("Calling non-yielding panicking methods not supported yet.");
                }
                outputNode = ConnectNewNodeToOutputTerminalWithOutputFacade(
                    panicOrContinueInput,
                    diagram => new PanicOrContinueNode(diagram),
                    outputType);
            }

            Terminal outputNodeTerminal = outputNode.OutputTerminals[0];

            switch (methodCallNode.OutputTerminals.Count)
            {
            case 0:
                // no method call output terminals; drop the result of the await
                InsertDropTransform.InsertDropForVariable(outputNode.ParentDiagram, LiveVariable.FromTerminal(outputNodeTerminal), _unificationResultFactory);
                break;

            case 1:
                ConnectOutputTerminal(methodCallNode.OutputTerminals[0], outputNodeTerminal);
                break;

            default:
            {
                // for >1 method call output terminals, decompose the tuple result of the await and match each
                // decomposed terminal to a method call terminal
                DecomposeTupleNode decomposeTupleNode = InsertDropTransform.InsertDecompositionForTupleVariable(
                    methodCallNode.ParentDiagram,
                    LiveVariable.FromTerminal(outputNodeTerminal),
                    _unificationResultFactory);
                foreach (var pair in methodCallNode.OutputTerminals.Zip(decomposeTupleNode.OutputTerminals))
                {
                    Terminal methodCallTerminal = pair.Key, decomposeTupleTerminal = pair.Value;
                    ConnectOutputTerminal(methodCallTerminal, decomposeTupleTerminal);
                }
                break;
            }
            }

            methodCallNode.RemoveFromGraph();
        }
Esempio n. 30
0
        public static void CreateFacadesForFunctionSignatureNode(this Node node, NIType nodeFunctionSignature)
        {
            int inputIndex = 0, outputIndex = 0;
            var genericTypeParameters  = new Dictionary <NIType, TypeVariableReference>();
            var lifetimeFacadeGroups   = new Dictionary <NIType, ReferenceInputTerminalLifetimeGroup>();
            var lifetimeVariableGroups = new Dictionary <NIType, LifetimeTypeVariableGroup>();

            TypeVariableSet      typeVariableSet = node.GetTypeVariableSet();
            AutoBorrowNodeFacade nodeFacade      = AutoBorrowNodeFacade.GetNodeFacade(node);

            TypeVariableReference[] signatureTypeParameters;
            if (nodeFunctionSignature.IsOpenGeneric())
            {
                Func <NIType, TypeVariableReference> createLifetimeTypeReference = type =>
                {
                    var group = LifetimeTypeVariableGroup.CreateFromNode(node);
                    lifetimeVariableGroups[type] = group;
                    return(group.LifetimeType);
                };
                genericTypeParameters = typeVariableSet.CreateTypeVariablesForGenericParameters(nodeFunctionSignature, createLifetimeTypeReference);

                signatureTypeParameters = nodeFunctionSignature.GetGenericParameters().Select(p => genericTypeParameters[p]).ToArray();
            }
            else
            {
                signatureTypeParameters = new TypeVariableReference[0];
            }
            var functionalNode = node as FunctionalNode;

            if (functionalNode != null)
            {
                functionalNode.FunctionType = new FunctionType(nodeFunctionSignature, signatureTypeParameters);
            }

            foreach (NIType parameter in nodeFunctionSignature.GetParameters())
            {
                NIType parameterDataType = parameter.GetDataType();
                bool   isInput = parameter.GetInputParameterPassingRule() != NIParameterPassingRule.NotAllowed,
                       isOutput = parameter.GetOutputParameterPassingRule() != NIParameterPassingRule.NotAllowed;
                Terminal inputTerminal = null, outputTerminal = null;
                if (isInput)
                {
                    inputTerminal = node.InputTerminals[inputIndex];
                    ++inputIndex;
                }
                if (isOutput)
                {
                    outputTerminal = node.OutputTerminals[outputIndex];
                    ++outputIndex;
                }
                if (isInput && isOutput)
                {
                    if (parameterDataType.IsRebarReferenceType())
                    {
                        CreateFacadesForInoutReferenceParameter(
                            typeVariableSet,
                            nodeFacade,
                            parameterDataType,
                            inputTerminal,
                            outputTerminal,
                            genericTypeParameters,
                            lifetimeFacadeGroups,
                            lifetimeVariableGroups);
                    }
                    else
                    {
                        throw new NotSupportedException("Inout parameters must be reference types.");
                    }
                }
                else if (isOutput)
                {
                    TypeVariableReference typeVariableReference = typeVariableSet.CreateTypeVariableReferenceFromNIType(parameterDataType, genericTypeParameters);
                    nodeFacade[outputTerminal] = new SimpleTerminalFacade(outputTerminal, typeVariableReference);
                }
                else if (isInput)
                {
                    if (parameterDataType.IsRebarReferenceType())
                    {
                        CreateFacadesForInoutReferenceParameter(
                            typeVariableSet,
                            nodeFacade,
                            parameterDataType,
                            inputTerminal,
                            null,
                            genericTypeParameters,
                            lifetimeFacadeGroups,
                            lifetimeVariableGroups);
                    }
                    else
                    {
                        TypeVariableReference typeVariableReference = typeVariableSet.CreateTypeVariableReferenceFromNIType(parameterDataType, genericTypeParameters);
                        nodeFacade[inputTerminal] = new SimpleTerminalFacade(inputTerminal, typeVariableReference);
                    }
                }
                else
                {
                    throw new NotSupportedException("Parameter is neither input nor output");
                }
            }
        }