public void CreateTypeVariableReferenceFromVectorOfNonCopyNonCloneType_TypeVariableDoesNotHaveCloneTrait() { var typeVariableSet = new TypeVariableSet(); TypeVariableReference vectorType = typeVariableSet.CreateTypeVariableReferenceFromNIType(DataTypes.FileHandleType.CreateVector()); AssertTypeVariableReferenceDoesNotHaveParameterlessTrait(typeVariableSet, vectorType, "Clone"); }
protected override TypeVariableReference ComputeTypeToUnifyWith(VariableReference inputFacadeVariable, out bool setExpectedMutable) { setExpectedMutable = false; TypeVariableReference other = inputFacadeVariable.TypeVariableReference; TypeVariableReference u, l; bool otherIsMutableReference; bool otherIsReference = TypeVariableSet.TryDecomposeReferenceType(other, out u, out l, out otherIsMutableReference); TypeVariableReference underlyingType = otherIsReference ? u : other; NIType literalType; bool underlyingTypeIsLiteral = TypeVariableSet.TryGetLiteralType(underlyingType, out literalType); bool inputCoercesToStringSlice = underlyingTypeIsLiteral && (literalType == PFTypes.String || literalType == DataTypes.StringSliceType); bool needsBorrow = !otherIsReference || !underlyingTypeIsLiteral || literalType != DataTypes.StringSliceType; TypeVariableReference lifetimeType = otherIsReference ? l : TypeVariableSet.CreateReferenceToLifetimeType(_group.BorrowLifetime); if (needsBorrow) { _stringToSliceNeeded = true; _group.SetBorrowRequired(false); } // If the input is allowed to coerce to a str, we can unify with str; // otherwise, unify with the underlying type to get a type mismatch. TypeVariableReference toUnifyUnderlyingType = inputCoercesToStringSlice ? TypeVariableSet.CreateReferenceToLiteralType(DataTypes.StringSliceType) : underlyingType; return(TypeVariableSet.CreateReferenceToReferenceType( false, toUnifyUnderlyingType, lifetimeType)); }
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; }
protected override void VisitNode(Node node) { TypeVariableSet typeVariableSet = node.GetTypeVariableSet(); AutoBorrowNodeFacade nodeFacade = AutoBorrowNodeFacade.GetNodeFacade(node); var primitive = node as PrimitiveTypeNode; var selfTypeNode = node as SelfTypeNode; if (primitive != null) { nodeFacade[primitive.OutputTerminal] = new SimpleTerminalFacade( primitive.OutputTerminal, typeVariableSet.CreateTypeVariableReferenceFromNIType(primitive.Type)); return; } if (selfTypeNode != null) { foreach (Terminal inputTerminal in selfTypeNode.InputTerminals) { TypeVariableReference typeVariable = typeVariableSet.CreateReferenceToNewTypeVariable(); nodeFacade[inputTerminal] = new SimpleTerminalFacade(inputTerminal, typeVariable); } return; } throw new NotSupportedException($"Unsupported node type: {node.GetType().Name}"); }
public void CreateTypeVariableReferenceFromOptionOfNonCopyType_TypeVariableReferenceDoesNotHaveCopyTrait() { var typeVariableSet = new TypeVariableSet(); TypeVariableReference optionType = typeVariableSet.CreateTypeVariableReferenceFromNIType(NITypes.String.CreateOption()); AssertTypeVariableReferenceDoesNotHaveParameterlessTrait(typeVariableSet, optionType, "Copy"); }
private static void CreateFacadesForInoutReferenceParameter( TypeVariableSet typeVariableSet, AutoBorrowNodeFacade nodeFacade, NIType parameterDataType, Terminal inputTerminal, Terminal outputTerminal, Dictionary <NIType, TypeVariableReference> genericTypeParameters, Dictionary <NIType, ReferenceInputTerminalLifetimeGroup> lifetimeFacadeGroups, Dictionary <NIType, LifetimeTypeVariableGroup> lifetimeVariableGroups) { NIType lifetimeType = parameterDataType.GetReferenceLifetimeType(); bool isMutable = parameterDataType.IsMutableReferenceType(); InputReferenceMutability mutability = parameterDataType.GetInputReferenceMutabilityFromType(); var lifetimeGroup = lifetimeVariableGroups[lifetimeType]; ReferenceInputTerminalLifetimeGroup facadeGroup; if (!lifetimeFacadeGroups.TryGetValue(lifetimeType, out facadeGroup)) { facadeGroup = nodeFacade.CreateInputLifetimeGroup(mutability, lifetimeGroup.LazyNewLifetime, lifetimeGroup.LifetimeType); } // TODO: should not add outputTerminal here if borrow cannot be auto-terminated // i.e., if there are in-only or out-only parameters that share lifetimeType TypeVariableReference referentTypeVariableReference = typeVariableSet.CreateTypeVariableReferenceFromNIType(parameterDataType.GetReferentType(), genericTypeParameters); TypeVariableReference mutabilityTypeVariableReference = mutability == InputReferenceMutability.Polymorphic ? genericTypeParameters[parameterDataType.GetReferenceMutabilityType()] : default(TypeVariableReference); facadeGroup.AddTerminalFacade(inputTerminal, referentTypeVariableReference, mutabilityTypeVariableReference, outputTerminal); }
public override void UnifyWithConnectedWireTypeAsNodeInput(VariableReference wireFacadeVariable, TerminalTypeUnificationResults unificationResults) { TypeVariableSet typeVariableSet = Terminal.GetTypeVariableSet(); ITypeUnificationResult inputUnificationResult = unificationResults.GetTypeUnificationResult(Terminal, TrueVariable.TypeVariableReference, wireFacadeVariable.TypeVariableReference); typeVariableSet.Unify(TrueVariable.TypeVariableReference, wireFacadeVariable.TypeVariableReference, inputUnificationResult); TrueVariable.MergeInto(wireFacadeVariable); string constructorName; TypeVariableReference innerType, optionType; if (typeVariableSet.TryDecomposeConstructorType(TrueVariable.TypeVariableReference, out constructorName, out innerType) && constructorName == "Option") { optionType = TrueVariable.TypeVariableReference; } else { optionType = typeVariableSet.CreateReferenceToConstructorType("Option", TrueVariable.TypeVariableReference); } TypeVariableReference outputTypeReference = _outputTerminalFacade.TrueVariable.TypeVariableReference; ITypeUnificationResult outputUnificationResult = unificationResults.GetTypeUnificationResult(_outputTerminalFacade.Terminal, outputTypeReference, optionType); typeVariableSet.Unify(outputTypeReference, optionType, outputUnificationResult); }
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); } } }
public void CreateTypeVariableReferenceFromOptionOfCopyType_TypeVariableReferenceHasCopyTrait() { var typeVariableSet = new TypeVariableSet(); TypeVariableReference optionType = typeVariableSet.CreateTypeVariableReferenceFromNIType(NITypes.Int32.CreateOption()); AssertTypeVariableReferenceHasParameterlessTrait(typeVariableSet, optionType, "Copy"); }
public void CreateTypeVariableReferenceFromVectorOfCopyType_TypeVariableHasCloneTrait() { var typeVariableSet = new TypeVariableSet(); TypeVariableReference vectorType = typeVariableSet.CreateTypeVariableReferenceFromNIType(NITypes.Int32.CreateVector()); AssertTypeVariableReferenceHasParameterlessTrait(typeVariableSet, vectorType, "Clone"); }
public void CreateTypeVariableReferenceFromStringSliceType_TypeVariableReferenceHasExpectedTraits() { var typeVariableSet = new TypeVariableSet(); TypeVariableReference stringSliceType = typeVariableSet.CreateTypeVariableReferenceFromNIType(DataTypes.StringSliceType); AssertTypeVariableReferenceHasParameterlessTrait(typeVariableSet, stringSliceType, "Display"); }
public void CreateTypeVariableReferenceFromSharedType_TypeVariableHasCloneAndDropTraits() { var typeVariableSet = new TypeVariableSet(); TypeVariableReference sharedType = typeVariableSet.CreateTypeVariableReferenceFromNIType(NITypes.String.CreateShared()); AssertTypeVariableReferenceHasParameterlessTrait(typeVariableSet, sharedType, "Clone"); AssertTypeVariableReferenceHasParameterlessTrait(typeVariableSet, sharedType, "Drop"); }
public void CreateTypeVariableReferenceFromBooleanType_TypeVariableReferenceHasExpectedTraits() { var typeVariableSet = new TypeVariableSet(); TypeVariableReference booleanType = typeVariableSet.CreateTypeVariableReferenceFromNIType(NITypes.Boolean); AssertTypeVariableReferenceHasParameterlessTrait(typeVariableSet, booleanType, "Display"); AssertTypeVariableReferenceHasParameterlessTrait(typeVariableSet, booleanType, "Clone"); AssertTypeVariableReferenceHasParameterlessTrait(typeVariableSet, booleanType, "Copy"); }
public void CreateTypeVariableReferenceFromIntegerType_TypeVariableReferenceHasExpectedTraits() { var typeVariableSet = new TypeVariableSet(); TypeVariableReference integerType = typeVariableSet.CreateTypeVariableReferenceFromNIType(NITypes.Int32); AssertTypeVariableReferenceHasParameterlessTrait(typeVariableSet, integerType, "Display"); AssertTypeVariableReferenceHasParameterlessTrait(typeVariableSet, integerType, "Clone"); AssertTypeVariableReferenceHasParameterlessTrait(typeVariableSet, integerType, "Copy"); }
private LifetimeTypeVariableGroup(Diagram diagram) { _variableSet = diagram.GetVariableSet(); _typeVariableSet = _variableSet.TypeVariableSet; LifetimeGraphTree lifetimeGraphTree = diagram.DfirRoot.GetLifetimeGraphTree(); LifetimeGraphIdentifier diagramGraphIdentifier = diagram.GetLifetimeGraphIdentifier(); LazyNewLifetime = new Lazy <Lifetime>(() => lifetimeGraphTree.CreateLifetimeThatIsBoundedByLifetimeGraph(diagramGraphIdentifier)); LifetimeType = _typeVariableSet.CreateReferenceToLifetimeType(LazyNewLifetime); }
public void CreateTypeVariableReferenceFromRangeIteratorType_TypeVariableReferenceHasExpectedIteratorTrait() { var typeVariableSet = new TypeVariableSet(); TypeVariableReference rangeIteratorType = typeVariableSet.CreateTypeVariableReferenceFromNIType(DataTypes.RangeIteratorType); TypeVariableReference iteratorTraitType; Assert.IsTrue(typeVariableSet.TryGetImplementedTrait(rangeIteratorType, "Iterator", out iteratorTraitType)); Assert.IsTrue(typeVariableSet.GetTypeParameters(iteratorTraitType).First().RenderNIType().IsInt32()); }
public void LiteralTypeAndConstructorType_Unify_TypeMismatchReported() { TypeVariableSet typeVariableSet = new TypeVariableSet(); TypeVariableReference literalReference = typeVariableSet.CreateTypeVariableReferenceFromNIType(NITypes.Int32), constructorReference = typeVariableSet.CreateTypeVariableReferenceFromNIType(NITypes.Int32.CreateVector()); var testTypeUnificationResult = new TestTypeUnificationResult(); typeVariableSet.Unify(constructorReference, literalReference, testTypeUnificationResult); Assert.IsTrue(testTypeUnificationResult.TypeMismatch); }
public void TwoDifferentLiteralTypes_Unify_TypeMismatchReported() { TypeVariableSet typeVariableSet = new TypeVariableSet(); TypeVariableReference literalReference1 = typeVariableSet.CreateTypeVariableReferenceFromNIType(NITypes.Int32), literalReference2 = typeVariableSet.CreateTypeVariableReferenceFromNIType(NITypes.Boolean); var testTypeUnificationResult = new TestTypeUnificationResult(); typeVariableSet.Unify(literalReference2, literalReference1, testTypeUnificationResult); Assert.IsTrue(testTypeUnificationResult.TypeMismatch); }
public void LiteralTypeAndTypeVariable_Unify_BothBecomeLiteralType() { TypeVariableSet typeVariableSet = new TypeVariableSet(); TypeVariableReference literalReference = typeVariableSet.CreateTypeVariableReferenceFromNIType(NITypes.Int32); TypeVariableReference typeVariable = typeVariableSet.CreateReferenceToNewTypeVariable(); typeVariableSet.Unify(typeVariable, literalReference, new TestTypeUnificationResult()); Assert.IsTrue(literalReference.RenderNIType().IsInt32()); Assert.IsTrue(typeVariable.RenderNIType().IsInt32()); }
public void TwoConstructorTypesWithSameConstructorName_Unify_InnerTypesAreUnified() { TypeVariableSet typeVariableSet = new TypeVariableSet(); TypeVariableReference innerTypeVariable = typeVariableSet.CreateReferenceToNewTypeVariable(); TypeVariableReference constructorType1 = typeVariableSet.CreateReferenceToOptionType(innerTypeVariable); TypeVariableReference constructorType2 = typeVariableSet.CreateReferenceToOptionType( typeVariableSet.CreateTypeVariableReferenceFromNIType(NITypes.Int32)); typeVariableSet.Unify(constructorType1, constructorType2, new TestTypeUnificationResult()); Assert.IsTrue(innerTypeVariable.RenderNIType().IsInt32()); }
public static TerminateLifetimeNode CreateTerminateLifetimeWithFacades(Diagram parentDiagram, int inputs, int outputs) { var terminateLifetime = new TerminateLifetimeNode(parentDiagram, inputs, outputs); AutoBorrowNodeFacade terminateLifetimeFacade = AutoBorrowNodeFacade.GetNodeFacade(terminateLifetime); TypeVariableSet typeVariableSet = parentDiagram.GetTypeVariableSet(); foreach (var terminal in terminateLifetime.Terminals) { terminateLifetimeFacade[terminal] = new SimpleTerminalFacade(terminal, typeVariableSet.CreateReferenceToNewTypeVariable()); } return(terminateLifetime); }
public void TwoConstructorTypesWithDifferentConstructorNames_Unify_TypeMismatchReported() { TypeVariableSet typeVariableSet = new TypeVariableSet(); TypeVariableReference constructorType1 = typeVariableSet.CreateReferenceToOptionType( typeVariableSet.CreateTypeVariableReferenceFromNIType(NITypes.Int32)); TypeVariableReference constructorType2 = typeVariableSet.CreateReferenceToLockingCellType( typeVariableSet.CreateTypeVariableReferenceFromNIType(NITypes.Int32)); var typeUnificationResult = new TestTypeUnificationResult(); typeVariableSet.Unify(constructorType1, constructorType2, typeUnificationResult); Assert.IsTrue(typeUnificationResult.TypeMismatch); }
public void TwoTypeVariables_Unify_BothBecomeSingleTypeVariable() { TypeVariableSet typeVariableSet = new TypeVariableSet(); TypeVariableReference literalReference = typeVariableSet.CreateTypeVariableReferenceFromNIType(NITypes.Int32); TypeVariableReference typeVariable1 = typeVariableSet.CreateReferenceToNewTypeVariable(), typeVariable2 = typeVariableSet.CreateReferenceToNewTypeVariable(); typeVariableSet.Unify(typeVariable2, typeVariable1, new TestTypeUnificationResult()); typeVariableSet.Unify(typeVariable1, literalReference, new TestTypeUnificationResult()); Assert.IsTrue(typeVariable1.RenderNIType().IsInt32()); Assert.IsTrue(typeVariable2.RenderNIType().IsInt32()); }
public void TwoConstructorTypesWithSameConstructorNameAndDifferentInnerTypes_Unify_TypeMismatchReported() { TypeVariableSet typeVariableSet = new TypeVariableSet(); TypeVariableReference constructorType1 = typeVariableSet.CreateReferenceToConstructorType("Vector", typeVariableSet.CreateReferenceToLiteralType(PFTypes.Int32)); TypeVariableReference constructorType2 = typeVariableSet.CreateReferenceToConstructorType("Vector", typeVariableSet.CreateReferenceToLiteralType(PFTypes.Boolean)); var typeUnificationResult = new TestTypeUnificationResult(); typeVariableSet.Unify(constructorType1, constructorType2, typeUnificationResult); Assert.IsTrue(typeUnificationResult.TypeMismatch); }
public void TypeVariableWithCopyConstraintAndNonCopyableType_Unify_FailedConstraintReported() { TypeVariableSet typeVariableSet = new TypeVariableSet(); TypeVariableReference literalReference = typeVariableSet.CreateReferenceToReferenceType( true, typeVariableSet.CreateTypeVariableReferenceFromNIType(NITypes.Int32), typeVariableSet.CreateReferenceToLifetimeType(Lifetime.Static)); var constraint = new SimpleTraitConstraint("Copy"); TypeVariableReference typeVariable = typeVariableSet.CreateReferenceToNewTypeVariable(constraint.ToEnumerable()); var testTypeUnificationResult = new TestTypeUnificationResult(); typeVariableSet.Unify(typeVariable, literalReference, testTypeUnificationResult); Assert.IsTrue(testTypeUnificationResult.FailedConstraints.Contains(constraint)); }
protected override void VisitDfirRoot(DfirRoot dfirRoot) { base.VisitDfirRoot(dfirRoot); _typeVariableSet = dfirRoot.GetTypeVariableSet(); var variableSet = new VariableSet(_typeVariableSet); dfirRoot.SetVariableSet(variableSet); int rootDiagramLifetimeId = 0; foreach (DataItem dataItem in dfirRoot.DataItems) { // TODO: eventually we want to reuse each DataItem's variable for its DataAccessors' terminals. TypeVariableReference dataTypeVariable = _typeVariableSet.CreateTypeVariableReferenceFromNIType(dataItem.DataType); dataItem.SetVariable(variableSet.CreateNewVariable(rootDiagramLifetimeId, dataTypeVariable, true)); } }
public void AddTerminalFacade(Terminal inputTerminal, TypeVariableReference referentTypeReference, TypeVariableReference mutabilityTypeReference, Terminal terminateLifetimeOutputTerminal = null) { TypeVariableReference referenceType; TypeVariableSet typeVariableSet = inputTerminal.GetTypeVariableSet(); if (_mutability == InputReferenceMutability.Polymorphic) { referenceType = typeVariableSet.CreateReferenceToPolymorphicReferenceType( mutabilityTypeReference, referentTypeReference, LifetimeType); } else { referenceType = typeVariableSet.CreateReferenceToReferenceType( (_mutability != InputReferenceMutability.AllowImmutable), referentTypeReference, LifetimeType); } if (_lazyBorrowLifetime.IsValueCreated) { throw new InvalidOperationException("Cannot add borrowed variables after creating new lifetime."); } NIType literalReferentType; bool isStringSliceReference = typeVariableSet.TryGetLiteralType(referentTypeReference, out literalReferentType) && literalReferentType == DataTypes.StringSliceType; TerminalFacade terminalFacade; if (isStringSliceReference) { terminalFacade = new StringSliceReferenceInputTerminalFacade(inputTerminal, this, referenceType); } else { terminalFacade = new ReferenceInputTerminalFacade(inputTerminal, _mutability, this, referenceType); } _nodeFacade[inputTerminal] = terminalFacade; _facades.Add(terminalFacade); if (terminateLifetimeOutputTerminal != null) { var outputFacade = new TerminateLifetimeOutputTerminalFacade(terminateLifetimeOutputTerminal, terminalFacade); _nodeFacade[terminateLifetimeOutputTerminal] = outputFacade; } }
protected override void VisitDfirRoot(DfirRoot dfirRoot) { base.VisitDfirRoot(dfirRoot); TypeVariableSet typeVariableSet = dfirRoot.GetTypeVariableSet(); dfirRoot.SetVariableSet(new VariableSet(typeVariableSet)); // Tech debt: none of this should be here. // When I first put in type inference for TypeDiagrams, I reused the VariableSet/TypeVariableSet stuff // for Function diagrams because it was convenient, even though TypeDiagrams don't need variables at all. // Later, to fix a bug, I required that creating a new VariableReference would require knowing the LifetimeGraphIdentifier // of the diagram that defines the VariableReference, which meant that a TypeDiagram's DfirRoot.BlockDiagram // would need a LifetimeGraphIdentifier. // // Removing this would require doing TypeDiagram type inference using just TypeVariableSet, and associating // TypeVariableReferences with Terminals without VariableReferences. dfirRoot.BlockDiagram.SetLifetimeGraphIdentifier(default(LifetimeGraphIdentifier)); }
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); }
public override void UnifyWithConnectedWireTypeAsNodeInput(VariableReference wireFacadeVariable, ITypeUnificationResultFactory unificationResultFactory) { TypeVariableSet typeVariableSet = Terminal.GetTypeVariableSet(); Terminal.UnifyTerminalTypeWith(TrueVariable.TypeVariableReference, wireFacadeVariable.TypeVariableReference, unificationResultFactory); TrueVariable.MergeInto(wireFacadeVariable); TypeVariableReference optionType; if (typeVariableSet.GetTypeName(TrueVariable.TypeVariableReference) == "Option") { optionType = TrueVariable.TypeVariableReference; } else { optionType = typeVariableSet.CreateReferenceToOptionType(TrueVariable.TypeVariableReference); } TypeVariableReference outputTypeReference = _outputTerminalFacade.TrueVariable.TypeVariableReference; _outputTerminalFacade.Terminal.UnifyTerminalTypeWith(outputTypeReference, optionType, unificationResultFactory); }