/// <summary> /// Try to Clone this context with additional set variables. /// </summary> public Result <TypeResolver, IError> TryCloneWithScopedStep( VariableName vn, TypeReference typeReference, TypeReference expectedScopedStepOutputType, IFreezableStep scopedStep, ErrorLocation errorLocation) { var newTypeResolver = Copy(); var r1 = newTypeResolver.TryAddType(vn, typeReference); if (r1.IsFailure) { return(r1.ConvertFailure <TypeResolver>().MapError(x => x.WithLocation(errorLocation))); } var r2 = newTypeResolver.TryAddTypeHierarchy(expectedScopedStepOutputType, scopedStep); if (r2.IsFailure) { return(r2.ConvertFailure <TypeResolver>()); } return(newTypeResolver); }
/// <summary> /// Create a new Freezable Sequence /// </summary> public static IFreezableStep CreateFreezableSequence( IEnumerable <IFreezableStep> steps, IFreezableStep finalStep, TextLocation?location) { var dict = new StepParameterDict { { new StepParameterReference.Named(nameof(Sequence <object> .InitialSteps)), new FreezableStepProperty.StepList(steps.ToImmutableList(), location) }, { new StepParameterReference.Named(nameof(Sequence <object> .FinalStep)), new FreezableStepProperty.Step(finalStep, location) }, }; var fpd = new FreezableStepData(dict, location); return(new CompoundFreezableStep( "Sequence", fpd, location )); }
/// <inheritdoc /> public override Result <TypeResolver, IError> TryGetScopedTypeResolver( TypeResolver baseContext, IFreezableStep scopedStep) { return(baseContext.TryCloneWithScopedStep( Variable, TypeReference.Actual.String, TypeReference.Actual.String, scopedStep, new ErrorLocation(this) )); }
/// <inheritdoc /> public override Result <TypeResolver, IError> TryGetScopedTypeResolver( TypeResolver baseContext, IFreezableStep scopedStep) { return(baseContext.TryCloneWithScopedStep( Variable, TypeReference.Create(typeof(T)), TypeReference.Unit.Instance, scopedStep, new ErrorLocation(this) )); }
/// <inheritdoc /> public override Result <TypeResolver, IError> TryGetScopedTypeResolver( TypeResolver baseTypeResolver, IFreezableStep scopedStep) { return(baseTypeResolver.TryCloneWithScopedStep( Variable, TypeReference.Actual.Integer, TypeReference.Unit.Instance, scopedStep, new ErrorLocation(this) )); }
/// <summary> /// Create a new Freezable EntityGetValue /// </summary> public static IFreezableStep CreateFreezableArrayAccess( IFreezableStep entityOrArray, IFreezableStep indexer, TextLocation?location) { var entityGetValueDict = new StepParameterDict { { new StepParameterReference.Named(nameof(EntityGetValue <int> .Entity)), new FreezableStepProperty.Step(entityOrArray, location) }, { new StepParameterReference.Named(nameof(EntityGetValue <int> .Property)), new FreezableStepProperty.Step(indexer, location) }, }; var entityGetValueData = new FreezableStepData(entityGetValueDict, location); var entityGetValueStep = new CompoundFreezableStep( "EntityGetValue", entityGetValueData, location ); var elementAtIndexDict = new StepParameterDict { { new StepParameterReference.Named(nameof(ElementAtIndex <object> .Array)), new FreezableStepProperty.Step(entityOrArray, location) }, { new StepParameterReference.Named(nameof(ElementAtIndex <object> .Index)), new FreezableStepProperty.Step(indexer, location) }, }; var elementAtData = new FreezableStepData(elementAtIndexDict, location); var elementAtStep = new CompoundFreezableStep( "ElementAtIndex", elementAtData, location ); var result = new OptionFreezableStep(new[] { entityGetValueStep, elementAtStep }, location); return(result); }
/// <summary> /// Create a freezable Not step. /// </summary> public static IFreezableStep CreateFreezableNot(IFreezableStep boolean, TextLocation location) { var dict = new StepParameterDict { { new StepParameterReference.Named(nameof(Not.Boolean)), new FreezableStepProperty.Step(boolean, location) }, }; var fpd = new FreezableStepData(dict, location); var step = new CompoundFreezableStep(nameof(Not), fpd, location); return(step); }
/// <summary> /// Tries to create a new TypeResolver. /// </summary> public static Result <TypeResolver, IError> TryCreate( StepFactoryStore stepFactoryStore, TypeReference expectedStepOutputType, IFreezableStep topLevelStep) { var typeResolver = new TypeResolver(stepFactoryStore); var r = typeResolver.TryAddTypeHierarchy(expectedStepOutputType, topLevelStep); if (r.IsFailure) { return(r.ConvertFailure <TypeResolver>()); } return(typeResolver); }
/// <summary> /// Try to add this step and all its children to this TypeResolver. /// </summary> public Result <Unit, IError> TryAddTypeHierarchy( TypeReference expectedType, IFreezableStep topLevelStep) { int?numberUnresolved = null; while (true) { var unresolvableVariableNames = new List <VariableName>(); var errors = new List <IError>(); var result = topLevelStep.GetVariablesSet(expectedType, this); if (result.IsFailure) { return(result.ConvertFailure <Unit>()); } foreach (var(variableName, typeReference) in result.Value) { if (typeReference is TypeReference.Unknown) { unresolvableVariableNames.Add(variableName); } else { var addResult = TryAddType(variableName, typeReference); if (addResult.IsFailure) { errors.Add(addResult.Error.WithLocation(ErrorLocation.EmptyLocation)); } } } if (errors.Any()) { return(Result.Failure <Unit, IError>(ErrorList.Combine(errors))); } if (!unresolvableVariableNames.Any()) { break; //We've resolved everything. Yey! } if (numberUnresolved == null || numberUnresolved > unresolvableVariableNames.Count) { numberUnresolved = unresolvableVariableNames .Count; //We have improved this number and can try again } else { var error = ErrorList.Combine( unresolvableVariableNames.Distinct() .Select( x => new SingleError( ErrorLocation.EmptyLocation, ErrorCode.CouldNotResolveVariable, x.Name ) ) ); return(Result.Failure <Unit, IError>(error)); } } return(Unit.Default); }
/// <summary> /// Add a FreezableErrorLocation /// </summary> public static IError WithLocation(this IErrorBuilder errorBuilder, IFreezableStep step) => errorBuilder.WithLocation(new ErrorLocation(step.StepName, step.TextLocation));