Пример #1
0
        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);
        }
Пример #2
0
 private ReferenceInputTerminalLifetimeGroup CreateTerminalLifetimeGroup(
     InputReferenceMutability mutability,
     LifetimeTypeVariableGroup variableGroup)
 {
     return(_nodeFacade.CreateInputLifetimeGroup(
                mutability,
                variableGroup.LazyNewLifetime,
                variableGroup.LifetimeType));
 }
Пример #3
0
        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);
        }
        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);
        }
Пример #5
0
        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);
        }
Пример #6
0
        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);
        }
Пример #7
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");
                }
            }
        }
        bool IDfirNodeVisitor <bool> .VisitFunctionalNode(FunctionalNode functionalNode)
        {
            int inputIndex = 0, outputIndex = 0;
            var genericTypeParameters  = new Dictionary <NIType, TypeVariableReference>();
            var lifetimeFacadeGroups   = new Dictionary <NIType, ReferenceInputTerminalLifetimeGroup>();
            var lifetimeVariableGroups = new Dictionary <NIType, LifetimeTypeVariableGroup>();

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

            foreach (NIType parameter in functionalNode.Signature.GetParameters())
            {
                NIType parameterDataType = parameter.GetDataType();
                bool   isInput = parameter.GetInputParameterPassingRule() != NIParameterPassingRule.NotAllowed,
                       isOutput = parameter.GetOutputParameterPassingRule() != NIParameterPassingRule.NotAllowed;
                Terminal inputTerminal = null, outputTerminal = null;
                if (isInput)
                {
                    inputTerminal = functionalNode.InputTerminals[inputIndex];
                    ++inputIndex;
                }
                if (isOutput)
                {
                    outputTerminal = functionalNode.OutputTerminals[outputIndex];
                    ++outputIndex;
                }
                if (isInput && isOutput)
                {
                    if (parameterDataType.IsRebarReferenceType())
                    {
                        CreateFacadesForInoutReferenceParameter(
                            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(
                            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");
                }
            }
            return(true);
        }