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)); }
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); }
public void CreateTypeVariableReferenceFromVectorOfCopyType_TypeVariableHasCloneTrait() { var typeVariableSet = new TypeVariableSet(); TypeVariableReference vectorType = typeVariableSet.CreateTypeVariableReferenceFromNIType(NITypes.Int32.CreateVector()); AssertTypeVariableReferenceHasParameterlessTrait(typeVariableSet, vectorType, "Clone"); }
public void CreateTypeVariableReferenceFromVectorOfNonCopyNonCloneType_TypeVariableDoesNotHaveCloneTrait() { var typeVariableSet = new TypeVariableSet(); TypeVariableReference vectorType = typeVariableSet.CreateTypeVariableReferenceFromNIType(DataTypes.FileHandleType.CreateVector()); AssertTypeVariableReferenceDoesNotHaveParameterlessTrait(typeVariableSet, vectorType, "Clone"); }
public void CreateTypeVariableReferenceFromOptionOfNonCopyType_TypeVariableReferenceDoesNotHaveCopyTrait() { var typeVariableSet = new TypeVariableSet(); TypeVariableReference optionType = typeVariableSet.CreateTypeVariableReferenceFromNIType(NITypes.String.CreateOption()); AssertTypeVariableReferenceDoesNotHaveParameterlessTrait(typeVariableSet, optionType, "Copy"); }
bool IDfirNodeVisitor <bool> .VisitDataAccessor(DataAccessor dataAccessor) { TypeVariableReference dataTypeVariable = _typeVariableSet.CreateTypeVariableReferenceFromNIType(dataAccessor.DataItem.DataType); _nodeFacade[dataAccessor.Terminal] = new SimpleTerminalFacade(dataAccessor.Terminal, dataTypeVariable); return(true); }
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); }
public void CreateTypeVariableReferenceFromOptionOfCopyType_TypeVariableReferenceHasCopyTrait() { var typeVariableSet = new TypeVariableSet(); TypeVariableReference optionType = typeVariableSet.CreateTypeVariableReferenceFromNIType(NITypes.Int32.CreateOption()); AssertTypeVariableReferenceHasParameterlessTrait(typeVariableSet, optionType, "Copy"); }
public void CreateTypeVariableReferenceFromStringSliceType_TypeVariableReferenceHasExpectedTraits() { var typeVariableSet = new TypeVariableSet(); TypeVariableReference stringSliceType = typeVariableSet.CreateTypeVariableReferenceFromNIType(DataTypes.StringSliceType); AssertTypeVariableReferenceHasParameterlessTrait(typeVariableSet, stringSliceType, "Display"); }
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; }
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); }
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); }
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 CreateTypeVariableReferenceFromSharedType_TypeVariableHasCloneAndDropTraits() { var typeVariableSet = new TypeVariableSet(); TypeVariableReference sharedType = typeVariableSet.CreateTypeVariableReferenceFromNIType(NITypes.String.CreateShared()); AssertTypeVariableReferenceHasParameterlessTrait(typeVariableSet, sharedType, "Clone"); AssertTypeVariableReferenceHasParameterlessTrait(typeVariableSet, sharedType, "Drop"); }
bool IDfirNodeVisitor <bool> .VisitDropNode(DropNode dropNode) { Terminal valueInput = dropNode.InputTerminals.ElementAt(0); TypeVariableReference dataTypeVariable = _typeVariableSet.CreateReferenceToNewTypeVariable(); _nodeFacade[valueInput] = new SimpleTerminalFacade(valueInput, dataTypeVariable); return(true); }
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"); }
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"); }
internal ITypeUnificationResult GetTypeUnificationResult(Terminal terminal, TypeVariableReference terminalTypeVariable, TypeVariableReference unifyWith) { TerminalUnificationResult unificationResult; if (!_unificationResults.TryGetValue(terminal, out unificationResult)) { _unificationResults[terminal] = unificationResult = new TerminalUnificationResult(terminalTypeVariable, unifyWith); } return(new TerminalTypeUnificationResult(unificationResult)); }
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 StringSliceReferenceInputTerminalFacade( Terminal terminal, ReferenceInputTerminalLifetimeGroup group, TypeVariableReference referenceTypeReference) : base(terminal) { _group = group; FacadeVariable = terminal.CreateNewVariable(); TrueVariable = terminal.CreateNewVariable(referenceTypeReference); }
public ReferenceInputTerminalLifetimeGroup( AutoBorrowNodeFacade nodeFacade, InputReferenceMutability mutability, Lazy <Lifetime> lazyNewLifetime, TypeVariableReference lifetimeType) { _nodeFacade = nodeFacade; _mutability = mutability; _lazyBorrowLifetime = lazyNewLifetime; LifetimeType = lifetimeType; }
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 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 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 TunnelTerminalFacade(Terminal terminal, TerminalFacade outputTerminalFacade) : base(terminal) { LifetimeGraphIdentifier innerDiagramLifetimeGraph = Terminal.ParentDiagram.GetLifetimeGraphIdentifier(); var constraint = new OutlastsLifetimeGraphConstraint(innerDiagramLifetimeGraph); TypeVariableReference inputTypeReference = terminal.GetTypeVariableSet().CreateReferenceToNewTypeVariable(new List <Constraint>() { constraint }); TrueVariable = terminal.CreateNewVariable(inputTypeReference); _outputTerminalFacade = outputTerminalFacade; }
public ReferenceInputTerminalFacade( Terminal terminal, InputReferenceMutability mutability, ReferenceInputTerminalLifetimeGroup group, TypeVariableReference referenceTypeReference) : base(terminal) { _mutability = mutability; _group = group; FacadeVariable = terminal.CreateNewVariable(); TrueVariable = terminal.CreateNewVariable(referenceTypeReference); }
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 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()); }
protected override void VisitWire(Wire wire) { TypeVariableReference wireTypeVariable = wire.GetTypeVariableSet() .CreateReferenceToNewTypeVariable(Enumerable.Empty <Constraint>()); AutoBorrowNodeFacade wireFacade = AutoBorrowNodeFacade.GetNodeFacade(wire); foreach (var terminal in wire.Terminals) { wireFacade[terminal] = new SimpleTerminalFacade(terminal, wireTypeVariable); } }