private static bool TypeConformToBase(IList <ICompiledType> derivedTypeList, IList <ICompiledType> baseTypeList, IErrorList errorList, ISource sourceLocation) { bool Success = false; IErrorList DirectErrorList = new ErrorList(); for (int derivedIndex = 0; derivedIndex < derivedTypeList.Count; derivedIndex++) { ICompiledType DerivedType = derivedTypeList[derivedIndex]; for (int baseIndex = 0; baseIndex < baseTypeList.Count; baseIndex++) { ICompiledType BaseType = baseTypeList[baseIndex]; if (derivedIndex == 0 && baseIndex == 0) { Success |= ConvertedTypeConformToBase(DerivedType, BaseType, DirectErrorList, sourceLocation); } else { Success |= ConvertedTypeConformToBase(DerivedType, BaseType, ErrorList.Ignored, ErrorList.NoLocation); } } } if (!Success) { errorList.AddErrors(DirectErrorList); } return(Success); }
/// <summary></summary> protected virtual bool InferTemplates(ref bool exit, IList <ISource> unresolvedSourceList, IErrorList errorList) { bool Success = true; List <ISource> FailedSourceList = new List <ISource>(); for (int i = 0; i < RuleTemplateList.Count; i++) { IRuleTemplate Rule = RuleTemplateList[i]; /*if (Rule is IQueryOverloadTypeConformanceRuleTemplate AsRuleTemplate) * { * * }*/ foreach (ISource Source in unresolvedSourceList) { if (!Rule.NodeType.IsAssignableFrom(Source.GetType())) { continue; } bool IsNoDestinationSet = Rule.IsNoDestinationSet(Source); if (IsNoDestinationSet) { bool AreAllSourcesReady = Rule.AreAllSourcesReady(Source, out IDictionary <ISourceTemplate, object> DataList); bool NoError = Rule.ErrorList.IsEmpty; if (!AreAllSourcesReady && !FailedSourceList.Contains(Source)) { FailedSourceList.Add(Source); } if (AreAllSourcesReady && NoError) { if (Rule.CheckConsistency(Source, DataList, out object data)) { Debug.Assert(Rule.ErrorList.IsEmpty); Rule.Apply(Source, data); Debug.Assert(Rule.AreAllDestinationsSet(Source)); exit = false; } else { Debug.Assert(!Rule.ErrorList.IsEmpty); errorList.AddErrors(Rule.ErrorList); Success = false; } } } } } return(Success); }
/// <summary> /// Execute all rules until the source list is exhausted. /// </summary> /// <param name="errorList">List of errors found.</param> /// <param name="passName">The pass name.</param> /// <returns>True if there is no source left to process.</returns> public virtual bool Solve(IErrorList errorList, string passName) { bool Success; bool?LastTryResult = null; for (;;) { foreach (IRuleTemplate Rule in RuleTemplateList) { Rule.Clear(); } IErrorList TryErrorList = new ErrorList(); bool TryResult = SolveWithRetry(TryErrorList, passName); if (Retries == 0) { errorList.AddErrors(TryErrorList); Success = TryResult; break; } // Errors can differ, but success or failure must not. if (!LastTryResult.HasValue) { LastTryResult = TryResult; } Debug.Assert(TryResult == LastTryResult.Value); // Reset sources so we restart inference from a fresh state. ResetSources(); ShuffleRules(RuleTemplateList, Retries); if (Retries <= 0) { throw new InvalidOperationException("Invalid inference retries count."); } Retries--; } Debug.Assert(Success || !errorList.IsEmpty); return(Success); }
private static bool FunctionTypeConformToPropertyType(IFunctionType derivedType, IPropertyType baseType, IErrorList errorList, ISource sourceLocation) { bool Result = true; Debug.Assert(derivedType.ResolvedBaseType.IsAssigned); Debug.Assert(baseType.ResolvedBaseType.IsAssigned); Result &= TypeConformToBase(derivedType.ResolvedBaseType.Item, baseType.ResolvedBaseType.Item, errorList, sourceLocation, isConversionAllowed: false); if (baseType.PropertyKind != BaseNode.UtilityType.ReadOnly) { errorList.AddError(new ErrorTypeKindConformance(sourceLocation, derivedType, baseType)); Result = false; } IErrorList AllOverloadErrorList = new ErrorList(); bool MatchingDerivedOverload = false; foreach (IQueryOverloadType DerivedOverload in derivedType.OverloadList) { IErrorList OverloadErrorList = new ErrorList(); if (!QueryOverloadHasPropertyConformingBase(DerivedOverload, baseType, OverloadErrorList, sourceLocation)) { Debug.Assert(!OverloadErrorList.IsEmpty); AllOverloadErrorList.AddError(OverloadErrorList.At(0)); } else { MatchingDerivedOverload = true; } } if (!MatchingDerivedOverload) { errorList.AddErrors(AllOverloadErrorList); errorList.AddError(new ErrorTypeKindConformance(sourceLocation, derivedType, baseType)); Result = false; } return(Result); }
private static bool ProcedureTypeConformToProcedureType(IProcedureType derivedType, IProcedureType baseType, IErrorList errorList, ISource sourceLocation) { bool Result = true; Debug.Assert(derivedType.ResolvedBaseType.IsAssigned); Debug.Assert(baseType.ResolvedBaseType.IsAssigned); Result &= TypeConformToBase(derivedType.ResolvedBaseType.Item, baseType.ResolvedBaseType.Item, errorList, sourceLocation, isConversionAllowed: false); IErrorList AllOverloadErrorList = new ErrorList(); foreach (ICommandOverloadType BaseOverload in baseType.OverloadList) { bool MatchingDerivedOverload = false; foreach (ICommandOverloadType DerivedOverload in derivedType.OverloadList) { IErrorList OverloadErrorList = new ErrorList(); if (!CommandOverloadConformToBase(DerivedOverload, BaseOverload, OverloadErrorList, DerivedOverload)) { Debug.Assert(!OverloadErrorList.IsEmpty); AllOverloadErrorList.AddError(OverloadErrorList.At(0)); } else { MatchingDerivedOverload = true; } } if (!MatchingDerivedOverload) { errorList.AddErrors(AllOverloadErrorList); errorList.AddError(new ErrorOverloadMismatchConformance(sourceLocation, derivedType, baseType)); Result = false; } } return(Result); }