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> .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); }
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); }