private static bool ExceptionListConformToBase(IList <IIdentifier> derivedExceptionIdentifierList, IList <IIdentifier> baseExceptionIdentifierList, IErrorList errorList, ISource sourceLocation) { bool Result = true; if (derivedExceptionIdentifierList.Count > baseExceptionIdentifierList.Count) { errorList.AddError(new ErrorExceptionConformance(sourceLocation, derivedExceptionIdentifierList, baseExceptionIdentifierList)); Result = false; } bool AllIdentifiersMatch = true; for (int i = 0; i < derivedExceptionIdentifierList.Count; i++) { IIdentifier DerivedIdentifier = derivedExceptionIdentifierList[i]; bool Found = false; for (int j = 0; j < baseExceptionIdentifierList.Count; j++) { IIdentifier BaseIdentifier = baseExceptionIdentifierList[j]; Found |= DerivedIdentifier.ValidText.Item == BaseIdentifier.ValidText.Item; } AllIdentifiersMatch &= Found; } if (!AllIdentifiersMatch) { errorList.AddError(new ErrorExceptionConformance(sourceLocation, derivedExceptionIdentifierList, baseExceptionIdentifierList)); Result = false; } return(Result); }
/// <summary> /// Merges a class import with previous imports. /// </summary> /// <param name="importedClassTable">The already resolved imports.</param> /// <param name="mergedClassTable">The new classes to import.</param> /// <param name="importLocation">The import location.</param> /// <param name="mergedImportType">The import specification for all <paramref name="mergedClassTable"/>.</param> /// <param name="errorList">List of errors found.</param> /// <returns>True if the merge is successful.</returns> public static bool MergeClassTables(ISealableDictionary <string, IImportedClass> importedClassTable, ISealableDictionary <string, IImportedClass> mergedClassTable, IImport importLocation, BaseNode.ImportType mergedImportType, IErrorList errorList) { bool Success = true; foreach (KeyValuePair <string, IImportedClass> Entry in mergedClassTable) { string ClassName = Entry.Key; IImportedClass MergedClassItem = Entry.Value; // The merged class may have an import specification already, but if so it must match the one used here. // We can assume we use mergedImportType after this. if (MergedClassItem.IsTypeAssigned && MergedClassItem.ImportType != mergedImportType) { errorList.AddError(new ErrorImportTypeConflict(importLocation, ClassName)); Success = false; } // If a class is already imported with this name somehow. if (importedClassTable.ContainsKey(ClassName)) { // It must be the same class. IImportedClass ClassItem = importedClassTable[ClassName]; if (ClassItem.Item != MergedClassItem.Item) { errorList.AddError(new ErrorNameAlreadyUsed(importLocation, ClassName)); Success = false; continue; } // If the already existing imported class has a specification, it must match the one use for merge. if (ClassItem.IsTypeAssigned) { if (ClassItem.ImportType != mergedImportType) { errorList.AddError(new ErrorImportTypeConflict(importLocation, ClassName)); Success = false; continue; } } else { ClassItem.SetImportType(mergedImportType); } // If the import location isn't specified yet, use the imported library. if (!ClassItem.IsLocationAssigned) { ClassItem.SetImportLocation(importLocation); } } else { // New class, at least by name. Make sure it's not an already imported class using a different name. Success &= MergeClassTablesWithNewClass(importedClassTable, ClassName, MergedClassItem, importLocation, mergedImportType, errorList); } } Debug.Assert(Success || !errorList.IsEmpty); return(Success); }
private static bool PositionalArgumentsConformToParameters(IList <ISealableList <IParameter> > parameterTableList, IReadOnlyList <IExpressionType> arguments, IErrorList errorList, ISource source, out int selectedIndex) { ISealableList <IParameter> SelectedOverload = null; selectedIndex = -1; int MaximumAllowedArgumentCount = -1; for (int i = 0; i < parameterTableList.Count; i++) { PositionalArgumentMatching(parameterTableList, arguments, i, ref MaximumAllowedArgumentCount, ref SelectedOverload, ref selectedIndex); } if (MaximumAllowedArgumentCount >= 0 && MaximumAllowedArgumentCount < arguments.Count) { errorList.AddError(new ErrorTooManyArguments(source, arguments.Count, MaximumAllowedArgumentCount)); return(false); } if (SelectedOverload == null) { errorList.AddError(new ErrorInvalidExpression(source)); return(false); } Debug.Assert(SelectedOverload.Count >= arguments.Count); return(true); }
private static bool FormalGenericTypeConformToBase(IFormalGenericType derivedType, ICompiledType baseType, IErrorList errorList, ISource sourceLocation) { bool Result = true; Result &= derivedType.FormalGeneric.ResolvedConformanceTable.IsSealed; if (derivedType.FormalGeneric.ResolvedConformanceTable.Count > 0) { Result &= FormalGenericTypeConformToBaseWithConformance(derivedType, baseType, errorList, sourceLocation); } else if (baseType != ClassType.ClassAnyType && baseType != ClassType.ClassAnyReferenceType && baseType != ClassType.ClassAnyValueType) { errorList.AddError(new ErrorInsufficientConstraintConformance(sourceLocation, derivedType, baseType)); Result = false; } if (baseType.IsReference && !derivedType.IsReference) { errorList.AddError(new ErrorReferenceValueConformance(sourceLocation, derivedType, baseType)); Result = false; } if (baseType.IsValue && !derivedType.IsValue) { errorList.AddError(new ErrorReferenceValueConformance(sourceLocation, derivedType, baseType)); Result = false; } return(Result); }
private static bool TypeConformToFormalGenericType(ICompiledType derivedType, IFormalGenericType baseType, IErrorList errorList, ISource sourceLocation) { bool Result = true; Result &= baseType.FormalGeneric.ResolvedConformanceTable.IsSealed; foreach (KeyValuePair <ITypeName, ICompiledType> ConformingEntry in baseType.FormalGeneric.ResolvedConformanceTable) { ICompiledType ConformingType = ConformingEntry.Value; Result &= TypeConformToBase(derivedType, ConformingType, errorList, sourceLocation, isConversionAllowed: false); } if (!derivedType.IsReference && baseType.IsReference) { errorList.AddError(new ErrorReferenceValueConformance(sourceLocation, derivedType, baseType)); Result = false; } if (!derivedType.IsValue && baseType.IsValue) { errorList.AddError(new ErrorReferenceValueConformance(sourceLocation, derivedType, baseType)); Result = false; } return(Result); }
private static bool ProcedureTypeConformToIndexerType(IProcedureType derivedType, IIndexerType 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.IndexerKind != BaseNode.UtilityType.WriteOnly) { errorList.AddError(new ErrorTypeKindConformance(sourceLocation, derivedType, baseType)); Result = false; } bool MatchingOverload = false; foreach (ICommandOverloadType DerivedOverload in derivedType.OverloadList) { MatchingOverload |= ProcedureTypeConformToIndexerTypeOverloads(DerivedOverload, baseType, errorList, sourceLocation); } if (!MatchingOverload) { errorList.AddError(new ErrorTypeKindConformance(sourceLocation, derivedType, baseType)); Result = false; } return(Result); }
private static bool FunctionTypeConformToFunctionType(IFunctionType derivedType, IFunctionType baseType, IErrorList errorList, ISource sourceLocation) { bool Result = true; Debug.Assert(derivedType.ResolvedBaseType.IsAssigned); Debug.Assert(baseType.ResolvedBaseType.IsAssigned); if (!TypeConformToBase(derivedType.ResolvedBaseType.Item, baseType.ResolvedBaseType.Item, errorList, sourceLocation, isConversionAllowed: false)) { errorList.AddError(new ErrorBaseConformance(sourceLocation, derivedType, baseType)); Result = false; } foreach (IQueryOverloadType BaseOverload in baseType.OverloadList) { bool MatchingDerivedOverload = false; foreach (IQueryOverloadType DerivedOverload in derivedType.OverloadList) { MatchingDerivedOverload |= QueryOverloadConformToBase(DerivedOverload, BaseOverload, ErrorList.Ignored, ErrorList.NoLocation); } if (!MatchingDerivedOverload) { errorList.AddError(new ErrorOverloadMismatchConformance(sourceLocation, derivedType, baseType)); Result = false; } } return(Result); }
/// <summary> /// Initializes the list of classes belonging to the library. /// </summary> /// <param name="classTable">Valid class names.</param> /// <param name="errorList">List of errors found.</param> /// <returns>True if initialization succeeded.</returns> public virtual bool InitLibraryTables(ISealableDictionary <string, ISealableDictionary <string, IClass> > classTable, IErrorList errorList) { bool Success = true; foreach (IIdentifier ClassIdentifier in ClassIdentifierList) { // Verify the class identifier is a valid string. if (!StringValidation.IsValidIdentifier(ClassIdentifier, ClassIdentifier.Text, out string ValidClassIdentifier, out IErrorStringValidity StringError)) { Success = false; errorList.AddError(StringError); continue; } if (ValidClassIdentifier.ToUpperInvariant() == LanguageClasses.Any.Name.ToUpperInvariant()) { // 'Any' is implicit and just ignored. } else { // Check that the class name is known. if (!classTable.ContainsKey(ValidClassIdentifier)) { Success = false; errorList.AddError(new ErrorUnknownIdentifier(ClassIdentifier, ValidClassIdentifier)); continue; } ISealableDictionary <string, IClass> SourceNameTable = classTable[ValidClassIdentifier]; // And it's from the same source. if (!SourceNameTable.ContainsKey(ValidSourceName)) { Success = false; errorList.AddError(new ErrorUnknownIdentifier(ClassIdentifier, ValidClassIdentifier)); continue; } // The class must be imported only once. if (ImportedClassTable.ContainsKey(ValidClassIdentifier)) { Success = false; errorList.AddError(new ErrorIdentifierAlreadyListed(ClassIdentifier, ValidClassIdentifier)); continue; } // Add it, leaving the import mode open for now. IImportedClass Imported = new ImportedClass(SourceNameTable[ValidSourceName]); ImportedClassTable.Add(ValidClassIdentifier, Imported); #if COVERAGE string ImportString = Imported.ToString(); #endif } } Debug.Assert(Success || !errorList.IsEmpty); return(Success); }
private static bool IndexerTypeConformToProcedureType(IIndexerType 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); if (derivedType.IndexerKind == BaseNode.UtilityType.ReadOnly) { errorList.AddError(new ErrorTypeKindConformance(sourceLocation, derivedType, baseType)); Result = false; } if (baseType.OverloadList.Count > 1) { errorList.AddError(new ErrorTypeKindConformance(sourceLocation, derivedType, baseType)); Result = false; } ICommandOverloadType SingleOverload = baseType.OverloadList[0]; if (SingleOverload.ParameterList.Count != derivedType.IndexParameterList.Count + 1 || SingleOverload.ParameterEnd != BaseNode.ParameterEndStatus.Closed) { errorList.AddError(new ErrorTypeKindConformance(sourceLocation, derivedType, baseType)); Result = false; } for (int i = 0; i + 1 < SingleOverload.ParameterList.Count && i < derivedType.IndexParameterList.Count; i++) { IEntityDeclaration BaseParameter = SingleOverload.ParameterList[i]; IEntityDeclaration DerivedParameter = derivedType.IndexParameterList[i]; Debug.Assert(BaseParameter.ValidEntity.IsAssigned); Debug.Assert(BaseParameter.ValidEntity.Item.ResolvedEffectiveType.IsAssigned); Debug.Assert(DerivedParameter.ValidEntity.IsAssigned); Debug.Assert(DerivedParameter.ValidEntity.Item.ResolvedEffectiveType.IsAssigned); Result &= TypeConformToBase(DerivedParameter.ValidEntity.Item.ResolvedEffectiveType.Item, BaseParameter.ValidEntity.Item.ResolvedEffectiveType.Item, errorList, sourceLocation, isConversionAllowed: false); } if (SingleOverload.ParameterList.Count == derivedType.IndexParameterList.Count + 1) { Debug.Assert(derivedType.ResolvedEntityType.IsAssigned); IEntityDeclaration LastParameter = SingleOverload.ParameterList[derivedType.IndexParameterList.Count]; Debug.Assert(LastParameter.ValidEntity.IsAssigned); Debug.Assert(LastParameter.ValidEntity.Item.ResolvedEffectiveType.IsAssigned); Result &= TypeConformToBase(derivedType.ResolvedEntityType.Item, LastParameter.ValidEntity.Item.ResolvedEffectiveType.Item, errorList, sourceLocation, isConversionAllowed: false); } Result &= ExceptionListConformToBase(derivedType.SetExceptionIdentifierList, SingleOverload.ExceptionIdentifierList, errorList, sourceLocation); return(Result); }
/// <summary> /// Finds the matching nodes of a <see cref="IClassConstantExpression"/>. /// </summary> /// <param name="node">The agent expression to check.</param> /// <param name="errorList">The list of errors found.</param> /// <param name="resolvedResult">The expression result types upon return.</param> /// <param name="resolvedException">Exceptions the expression can throw upon return.</param> /// <param name="constantSourceList">Sources of the constant expression upon return, if any.</param> /// <param name="expressionConstant">The expression constant upon return.</param> /// <param name="resolvedFinalFeature">The feature if the end of the path is a feature.</param> /// <param name="resolvedFinalDiscrete">The discrete if the end of the path is a discrete.</param> /// <param name="resolvedClassTypeName">The class type name upon return.</param> /// <param name="resolvedClassType">The class name upon return.</param> public static bool ResolveCompilerReferences(IClassConstantExpression node, IErrorList errorList, out IResultType resolvedResult, out IResultException resolvedException, out ISealableList <IExpression> constantSourceList, out ILanguageConstant expressionConstant, out IConstantFeature resolvedFinalFeature, out IDiscrete resolvedFinalDiscrete, out ITypeName resolvedClassTypeName, out IClassType resolvedClassType) { resolvedResult = null; resolvedException = null; constantSourceList = new SealableList <IExpression>(); expressionConstant = NeutralLanguageConstant.NotConstant; resolvedFinalFeature = null; resolvedFinalDiscrete = null; resolvedClassTypeName = null; resolvedClassType = null; IIdentifier ClassIdentifier = (IIdentifier)node.ClassIdentifier; IIdentifier ConstantIdentifier = (IIdentifier)node.ConstantIdentifier; IClass EmbeddingClass = node.EmbeddingClass; string ValidClassText = ClassIdentifier.ValidText.Item; string ValidConstantText = ConstantIdentifier.ValidText.Item; ISealableDictionary <string, IImportedClass> ClassTable = EmbeddingClass.ImportedClassTable; if (!ClassTable.ContainsKey(ValidClassText)) { errorList.AddError(new ErrorUnknownIdentifier(ClassIdentifier, ValidClassText)); return(false); } IClass BaseClass = ClassTable[ValidClassText].Item; resolvedClassTypeName = BaseClass.ResolvedClassTypeName.Item; resolvedClassType = BaseClass.ResolvedClassType.Item; ITypeName ConstantTypeName; ICompiledType ConstantType; ISealableDictionary <IFeatureName, IDiscrete> DiscreteTable = BaseClass.DiscreteTable; ISealableDictionary <IFeatureName, IFeatureInstance> FeatureTable = BaseClass.FeatureTable; if (FeatureName.TableContain(DiscreteTable, ValidConstantText, out IFeatureName Key, out IDiscrete Discrete)) { if (!Expression.IsLanguageTypeAvailable(LanguageClasses.Number.Guid, node, out ITypeName NumberTypeName, out ICompiledType NumberType)) { errorList.AddError(new ErrorNumberTypeMissing(node)); return(false); } if (Discrete.NumericValue.IsAssigned) { constantSourceList.Add((IExpression)Discrete.NumericValue.Item); } else { expressionConstant = new DiscreteLanguageConstant(Discrete); } resolvedFinalDiscrete = Discrete; ConstantTypeName = NumberTypeName; ConstantType = NumberType; }
private static bool CheckAssignemntIdentifier(IErrorList errorList, ISealableDictionary <IFeatureName, IFeatureInstance> featureTable, ISealableDictionary <string, ICompiledFeature> assignedFeatureTable, IIdentifier identifierItem) { bool Success = true; string ValidIdentifierText = identifierItem.ValidText.Item; if (assignedFeatureTable.ContainsKey(ValidIdentifierText)) { errorList.AddError(new ErrorIdentifierAlreadyListed(identifierItem, ValidIdentifierText)); Success = false; } else { if (FeatureName.TableContain(featureTable, ValidIdentifierText, out IFeatureName Key, out IFeatureInstance FeatureItem)) { bool ValidFeature = false; if (FeatureItem.Feature is AttributeFeature AsAttributeFeature) { ValidFeature = true; } else if (FeatureItem.Feature is IPropertyFeature AsPropertyFeature) { bool IsHandled = false; switch (AsPropertyFeature.PropertyKind) { case BaseNode.UtilityType.ReadOnly: ValidFeature = !AsPropertyFeature.GetterBody.IsAssigned; IsHandled = true; break; case BaseNode.UtilityType.ReadWrite: ValidFeature = !(AsPropertyFeature.GetterBody.IsAssigned && !AsPropertyFeature.SetterBody.IsAssigned); IsHandled = true; break; case BaseNode.UtilityType.WriteOnly: ValidFeature = true; IsHandled = true; break; } Debug.Assert(IsHandled); } if (ValidFeature) { assignedFeatureTable.Add(ValidIdentifierText, FeatureItem.Feature); } else { errorList.AddError(new ErrorAttributeOrPropertyRequired(identifierItem, ValidIdentifierText)); Success = false; } }
private static bool IndexerTypeConformToIndexerType(IIndexerType derivedType, IIndexerType 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.IndexerKind == BaseNode.UtilityType.ReadOnly && derivedType.IndexerKind == BaseNode.UtilityType.WriteOnly) || (baseType.IndexerKind == BaseNode.UtilityType.WriteOnly && derivedType.IndexerKind == BaseNode.UtilityType.ReadOnly) || (baseType.IndexerKind == BaseNode.UtilityType.ReadWrite && derivedType.IndexerKind != BaseNode.UtilityType.ReadWrite)) { errorList.AddError(new ErrorGetterSetterConformance(sourceLocation, derivedType, baseType)); Result = false; } if (derivedType.IndexParameterList.Count != baseType.IndexParameterList.Count || derivedType.ParameterEnd != baseType.ParameterEnd) { errorList.AddError(new ErrorParameterMismatchConformance(sourceLocation, derivedType, baseType)); Result = false; } for (int i = 0; i < baseType.IndexParameterList.Count && i < derivedType.IndexParameterList.Count; i++) { IEntityDeclaration BaseParameter = baseType.IndexParameterList[i]; IEntityDeclaration DerivedParameter = derivedType.IndexParameterList[i]; Debug.Assert(DerivedParameter.ValidEntity.IsAssigned); Debug.Assert(DerivedParameter.ValidEntity.Item.ResolvedEffectiveType.IsAssigned); Debug.Assert(BaseParameter.ValidEntity.IsAssigned); Debug.Assert(BaseParameter.ValidEntity.Item.ResolvedEffectiveType.IsAssigned); Result &= TypeConformToBase(DerivedParameter.ValidEntity.Item.ResolvedEffectiveType.Item, BaseParameter.ValidEntity.Item.ResolvedEffectiveType.Item, errorList, sourceLocation, isConversionAllowed: false); } Debug.Assert(derivedType.ResolvedEntityType.IsAssigned); Debug.Assert(baseType.ResolvedEntityType.IsAssigned); Result &= TypeConformToBase(derivedType.ResolvedEntityType.Item, baseType.ResolvedEntityType.Item, errorList, sourceLocation, isConversionAllowed: false); /* * if (!TypesHaveIdenticalSignature(derivedType.ResolvedEntityType.Item, baseType.ResolvedEntityType.Item)) * { * //errorList.Add(new ConformanceError(sourceLocation)); * return false; * } */ Result &= ExceptionListConformToBase(derivedType.GetExceptionIdentifierList, baseType.GetExceptionIdentifierList, errorList, sourceLocation); Result &= ExceptionListConformToBase(derivedType.SetExceptionIdentifierList, baseType.SetExceptionIdentifierList, errorList, sourceLocation); return(Result); }
private static bool IndexerTypeConformToFunctionType(IIndexerType derivedType, IFunctionType 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 (derivedType.IndexerKind == BaseNode.UtilityType.WriteOnly) { errorList.AddError(new ErrorTypeKindConformance(sourceLocation, derivedType, baseType)); Result = false; } if (baseType.OverloadList.Count > 1) { errorList.AddError(new ErrorTypeKindConformance(sourceLocation, derivedType, baseType)); Result = false; } IQueryOverloadType SingleOverload = baseType.OverloadList[0]; if (SingleOverload.ParameterList.Count != derivedType.IndexParameterList.Count || SingleOverload.ResultList.Count != 1 || SingleOverload.ParameterEnd != derivedType.ParameterEnd) { errorList.AddError(new ErrorTypeKindConformance(sourceLocation, derivedType, baseType)); Result = false; } for (int i = 0; i < SingleOverload.ParameterList.Count && i < derivedType.IndexParameterList.Count; i++) { IEntityDeclaration BaseParameter = SingleOverload.ParameterList[i]; IEntityDeclaration DerivedParameter = derivedType.IndexParameterList[i]; Debug.Assert(DerivedParameter.ValidEntity.IsAssigned); Debug.Assert(DerivedParameter.ValidEntity.Item.ResolvedEffectiveType.IsAssigned); Debug.Assert(BaseParameter.ValidEntity.IsAssigned); Debug.Assert(BaseParameter.ValidEntity.Item.ResolvedEffectiveType.IsAssigned); Result &= TypeConformToBase(DerivedParameter.ValidEntity.Item.ResolvedEffectiveType.Item, BaseParameter.ValidEntity.Item.ResolvedEffectiveType.Item, errorList, sourceLocation, isConversionAllowed: false); } IEntityDeclaration OverloadResult = SingleOverload.ResultList[0]; Debug.Assert(OverloadResult.ValidEntity.IsAssigned); Debug.Assert(OverloadResult.ValidEntity.Item.ResolvedEffectiveType.IsAssigned); Debug.Assert(derivedType.ResolvedEntityType.IsAssigned); Result &= TypeConformToBase(OverloadResult.ValidEntity.Item.ResolvedEffectiveType.Item, derivedType.ResolvedEntityType.Item, errorList, sourceLocation, isConversionAllowed: false); Result &= ExceptionListConformToBase(derivedType.GetExceptionIdentifierList, SingleOverload.ExceptionIdentifierList, errorList, sourceLocation); return(Result); }
private bool CheckPrecursorSelected(ISealableDictionary <IFeatureName, InheritedInstanceInfo> byNameTable, ISealableDictionary <IFeatureName, IList <ICompiledFeature> > precursorSet, IErrorList errorList) { bool Success = true; bool IsKept = false; foreach (KeyValuePair <IFeatureName, IList <ICompiledFeature> > SetMemberEntry in precursorSet) { IFeatureName SetMemberKey = SetMemberEntry.Key; InheritedInstanceInfo CorrespondingInstance = byNameTable[SetMemberKey]; if (CorrespondingInstance.IsKept) { if (IsKept) { foreach (InstanceNameInfo Item in CorrespondingInstance.PrecursorInstanceList) { if (Item.Instance.IsKept) { errorList.AddError(new ErrorInheritanceConflict(Item.Location, Item.Name.Name)); Success = false; break; } } } else { IsKept = true; } } } if (!IsKept && precursorSet.Count > 1) { foreach (KeyValuePair <IFeatureName, IList <ICompiledFeature> > SetMemberEntry in precursorSet) { IFeatureName SetMemberKey = SetMemberEntry.Key; InheritedInstanceInfo CorrespondingInstance = byNameTable[SetMemberKey]; foreach (InstanceNameInfo Item in CorrespondingInstance.PrecursorInstanceList) { errorList.AddError(new ErrorMissingSelectedPrecursor(Item.Location, Item.Name.Name)); Success = false; break; } break; } Debug.Assert(!Success); } return(Success); }
/// <summary> /// Finds the matching nodes of a <see cref="IOldExpression"/>. /// </summary> /// <param name="node">The agent expression to check.</param> /// <param name="errorList">The list of errors found.</param> /// <param name="resolvedExpression">The result of the search.</param> public static bool ResolveCompilerReferences(IOldExpression node, IErrorList errorList, out ResolvedExpression resolvedExpression) { resolvedExpression = new ResolvedExpression(); IClass EmbeddingClass = node.EmbeddingClass; IQualifiedName Query = (IQualifiedName)node.Query; IList <IIdentifier> ValidPath = Query.ValidPath.Item; IClassType BaseType = EmbeddingClass.ResolvedClassType.Item; if (!Expression.IsLanguageTypeAvailable(LanguageClasses.Boolean.Guid, node, out ITypeName BooleanTypeName, out ICompiledType BooleanType)) { errorList.AddError(new ErrorBooleanTypeMissing(node)); return(false); } ISealableDictionary <string, IScopeAttributeFeature> LocalScope = Scope.CurrentScope(node); Debug.Assert(LocalScope != null); if (node.EmbeddingBody == null && node.EmbeddingAssertion == null) { errorList.AddError(new ErrorInvalidOldExpression(node)); return(false); } if (!ObjectType.GetQualifiedPathFinalType(EmbeddingClass, BaseType, LocalScope, ValidPath, 0, errorList, out ICompiledFeature FinalFeature, out IDiscrete FinalDiscrete, out ITypeName FinalTypeName, out ICompiledType FinalType, out bool InheritBySideAttribute)) { return(false); } if (FinalFeature == null) { errorList.AddError(new ErrorInvalidOldExpression(node)); return(false); } ObjectType.FillResultPath(EmbeddingClass, BaseType, LocalScope, ValidPath, 0, Query.ValidResultTypePath.Item); resolvedExpression.ResolvedFinalFeature = FinalFeature; resolvedExpression.ResolvedResult = new ResultType(FinalTypeName, FinalType, string.Empty); resolvedExpression.ResolvedException = new ResultException(); #if COVERAGE Debug.Assert(!node.IsComplex); #endif return(true); }
/// <summary> /// Validates an import and return the matching library. /// </summary> /// <param name="libraryTable">Table of valid library names and their sources, updated upon return.</param> /// <param name="matchingLibrary">The matching library upon return.</param> /// <param name="errorList">List of errors found.</param> /// <returns>True if library names are valid.</returns> public virtual bool CheckImportConsistency(ISealableDictionary <string, ISealableDictionary <string, ILibrary> > libraryTable, out ILibrary matchingLibrary, IErrorList errorList) { IErrorStringValidity StringError; string ValidFromIdentifier; IIdentifier ImportLibraryIdentifier = (IIdentifier)LibraryIdentifier; ISealableDictionary <string, ILibrary> SourceNameTable; matchingLibrary = null; if (!StringValidation.IsValidIdentifier(ImportLibraryIdentifier, LibraryIdentifier.Text, out string ValidLibraryIdentifier, out StringError)) { errorList.AddError(StringError); return(false); } // Match the library name and source name. if (!libraryTable.ContainsKey(ValidLibraryIdentifier)) { errorList.AddError(new ErrorUnknownIdentifier(ImportLibraryIdentifier, ValidLibraryIdentifier)); return(false); } SourceNameTable = libraryTable[ValidLibraryIdentifier]; if (FromIdentifier.IsAssigned) { IIdentifier ImportFromIdentifier = (IIdentifier)FromIdentifier.Item; if (!StringValidation.IsValidIdentifier(ImportFromIdentifier, FromIdentifier.Item.Text, out ValidFromIdentifier, out StringError)) { errorList.AddError(StringError); return(false); } } else { ValidFromIdentifier = string.Empty; } if (!SourceNameTable.ContainsKey(ValidFromIdentifier)) { errorList.AddError(new ErrorUnknownIdentifier(ImportLibraryIdentifier, ValidLibraryIdentifier)); return(false); } matchingLibrary = SourceNameTable[ValidFromIdentifier]; return(true); }
private static bool TupleTypeConformToTupleType(ITupleType derivedType, ITupleType baseType, IErrorList errorList, ISource sourceLocation) { bool Result = true; if (derivedType.EntityDeclarationList.Count < baseType.EntityDeclarationList.Count) { errorList.AddError(new ErrorFieldMismatchConformance(sourceLocation, derivedType, baseType)); Result = false; } for (int i = 0; i < derivedType.EntityDeclarationList.Count && i < baseType.EntityDeclarationList.Count; i++) { IEntityDeclaration BaseField = baseType.EntityDeclarationList[i]; IEntityDeclaration DerivedField = derivedType.EntityDeclarationList[i]; Debug.Assert(DerivedField.ValidEntity.IsAssigned); Debug.Assert(DerivedField.ValidEntity.Item.ResolvedEffectiveType.IsAssigned); Debug.Assert(BaseField.ValidEntity.IsAssigned); Debug.Assert(BaseField.ValidEntity.Item.ResolvedEffectiveType.IsAssigned); Result = TypeConformToBase(DerivedField.ValidEntity.Item.ResolvedEffectiveType.Item, BaseField.ValidEntity.Item.ResolvedEffectiveType.Item, errorList, sourceLocation, isConversionAllowed: false); } return(Result); }
private bool CompareEffectiveFlags(InheritedInstanceInfo importedInstance, IErrorList errorList, IClassType localClassType) { bool Result = true; importedInstance.IsKept = importedInstance.EffectiveInstance.Item.Instance.IsKept; importedInstance.IsDiscontinued = importedInstance.EffectiveInstance.Item.Instance.IsDiscontinued; // If the effective instance is a redefine. if (importedInstance.EffectiveInstance.Item.Ancestor == localClassType && importedInstance.EffectiveInstance.Item.Instance.Feature.ResolvedAgentType.IsAssigned) { ICompiledType DescendantFeatureType = importedInstance.EffectiveInstance.Item.Instance.Feature.ResolvedAgentType.Item; IList <InstanceNameInfo> InstanceList = importedInstance.PrecursorInstanceList; foreach (InstanceNameInfo Item in InstanceList) { if (Item == importedInstance.EffectiveInstance.Item) { continue; } ICompiledType AncestorFeatureType = Item.Instance.Feature.ResolvedAgentType.Item; if (!ObjectType.TypeConformToBase(DescendantFeatureType, AncestorFeatureType, errorList, (ISource)importedInstance.EffectiveInstance.Item.Instance.Feature, isConversionAllowed: false)) { errorList.AddError(new ErrorInheritanceConflict(Item.Location, Item.Name.Name)); Result = false; } } } return(Result); }
private bool IsSingleEffective(ISealableDictionary <IFeatureName, InheritedInstanceInfo> byNameTable, IErrorList errorList) { bool IsSingle = true; foreach (KeyValuePair <IFeatureName, InheritedInstanceInfo> ImportedEntry in byNameTable) { IFeatureName ImportedKey = ImportedEntry.Key; InheritedInstanceInfo ImportedInstance = ImportedEntry.Value; IList <InstanceNameInfo> InstanceList = ImportedInstance.PrecursorInstanceList; foreach (InstanceNameInfo Item in InstanceList) { if (!Item.Instance.IsForgotten) { if (!ImportedInstance.EffectiveInstance.IsAssigned) { ImportedInstance.EffectiveInstance.Item = Item; } else { errorList.AddError(new ErrorMultipleEffectiveFeature(Item.Location, Item.Name.Name)); IsSingle = false; break; } } } } return(IsSingle); }
/// <summary> /// Checks that a result of a list of overloads conform to a base type. /// </summary> /// <param name="overloadList">The list of overloads.</param> /// <param name="index">Index of the result in the possible results.</param> /// <param name="baseType">The base type.</param> /// <param name="location">The location where to report errors.</param> /// <param name="errorList">The list of errors found.</param> public static bool JoinedResultCheck(IList <IQueryOverloadType> overloadList, int index, ICompiledType baseType, ISource location, IErrorList errorList) { bool Success = true; IList <IParameter> SameIndexList = new List <IParameter>(); foreach (IQueryOverloadType Overload in overloadList) { ISealableList <IParameter> ResultTable = Overload.ResultTable; if (index < ResultTable.Count) { SameIndexList.Add(ResultTable[index]); } } for (int i = 0; i < SameIndexList.Count; i++) { IParameter CurrentParameter = SameIndexList[i]; ICompiledType CurrentParameterType = CurrentParameter.ResolvedParameter.ResolvedEffectiveType.Item; if (!ObjectType.TypeConformToBase(CurrentParameterType, baseType, isConversionAllowed: false)) { errorList.AddError(new ErrorNonConformingType(location)); Success = false; } } return(Success); }
/// <summary> /// Finds the matching nodes of a <see cref="IManifestCharacterExpression"/>. /// </summary> /// <param name="node">The agent expression to check.</param> /// <param name="errorList">The list of errors found.</param> /// <param name="resolvedResult">The expression result types upon return.</param> /// <param name="resolvedException">Exceptions the expression can throw upon return.</param> /// <param name="constantSourceList">Sources of the constant expression upon return, if any.</param> /// <param name="expressionConstant">The expression constant upon return.</param> public static bool ResolveCompilerReferences(IManifestCharacterExpression node, IErrorList errorList, out IResultType resolvedResult, out IResultException resolvedException, out ISealableList <IExpression> constantSourceList, out ILanguageConstant expressionConstant) { resolvedResult = null; resolvedException = null; constantSourceList = new SealableList <IExpression>(); expressionConstant = NeutralLanguageConstant.NotConstant; IClass EmbeddingClass = node.EmbeddingClass; string ValidText = node.ValidText.Item; Debug.Assert(ValidText.Length == 1); char ValidChar = ValidText[0]; if (!Expression.IsLanguageTypeAvailable(LanguageClasses.Character.Guid, node, out ITypeName CharacterTypeName, out ICompiledType CharacterType)) { errorList.AddError(new ErrorCharacterTypeMissing(node)); return(false); } resolvedResult = new ResultType(CharacterTypeName, CharacterType, string.Empty); resolvedException = new ResultException(); expressionConstant = new CharacterLanguageConstant(ValidChar); #if COVERAGE Debug.Assert(!node.IsComplex); #endif return(true); }
private static bool IsWithinGetter(ISource source, IErrorList errorList, out ITypeName resultTypeName, out ICompiledType resultType) { resultTypeName = null; resultType = null; if (source.EmbeddingOverload is IQueryOverload AsQueryOverload) { return(CheckQueryConsistency(source, AsQueryOverload, errorList, out resultTypeName, out resultType)); } else if (source.EmbeddingFeature is IPropertyFeature AsPropertyFeature) { if (CheckGetterConsistency(source, AsPropertyFeature.GetterBody, errorList)) { resultTypeName = AsPropertyFeature.ResolvedEntityTypeName.Item; resultType = AsPropertyFeature.ResolvedEntityType.Item; return(true); } } else if (source.EmbeddingFeature is IIndexerFeature AsIndexerFeature) { if (CheckGetterConsistency(source, AsIndexerFeature.GetterBody, errorList)) { resultTypeName = AsIndexerFeature.ResolvedEntityTypeName.Item; resultType = AsIndexerFeature.ResolvedEntityType.Item; return(true); } } else { errorList.AddError(new ErrorUnavailableResult(source)); } return(false); }
/// <summary> /// Finds the matching nodes of a <see cref="IManifestNumberExpression"/>. /// </summary> /// <param name="node">The agent expression to check.</param> /// <param name="errorList">The list of errors found.</param> /// <param name="resolvedResult">The expression result types upon return.</param> /// <param name="resolvedException">Exceptions the expression can throw upon return.</param> /// <param name="constantSourceList">Sources of the constant expression upon return, if any.</param> /// <param name="expressionConstant">The constant type upon return.</param> public static bool ResolveCompilerReferences(IManifestNumberExpression node, IErrorList errorList, out IResultType resolvedResult, out IResultException resolvedException, out ISealableList <IExpression> constantSourceList, out ILanguageConstant expressionConstant) { resolvedResult = null; resolvedException = null; constantSourceList = new SealableList <IExpression>(); expressionConstant = NeutralLanguageConstant.NotConstant; IClass EmbeddingClass = node.EmbeddingClass; string NumberText = node.ValidText.Item; ISealableDictionary <ITypeName, ICompiledType> TypeTable = EmbeddingClass.TypeTable; if (!Expression.IsLanguageTypeAvailable(LanguageClasses.Number.Guid, node, out ITypeName NumberTypeName, out ICompiledType NumberType)) { errorList.AddError(new ErrorNumberTypeMissing(node)); return(false); } resolvedResult = new ResultType(NumberTypeName, NumberType, string.Empty); resolvedException = new ResultException(); FormattedNumber FormattedNumber = FormattedNumber.Parse(NumberText); Debug.Assert(string.IsNullOrEmpty(FormattedNumber.InvalidText)); expressionConstant = new NumberLanguageConstant(FormattedNumber.Value); #if COVERAGE Debug.Assert(!node.IsComplex); #endif return(true); }
private static bool MergeClassTablesWithNewClass(ISealableDictionary <string, IImportedClass> importedClassTable, string className, IImportedClass mergedClassItem, IImport importLocation, BaseNode.ImportType mergedImportType, IErrorList errorList) { bool Success = true; foreach (KeyValuePair <string, IImportedClass> ImportedEntry in importedClassTable) { IImportedClass ClassItem = ImportedEntry.Value; if (ClassItem.Item == mergedClassItem.Item) { string OldName = ImportedEntry.Key; errorList.AddError(new ErrorClassAlreadyImported(importLocation, OldName, className)); Success = false; break; } } // First time this class is imported, use the merge import type specification and location since they are known. if (Success) { mergedClassItem.SetImportType(mergedImportType); mergedClassItem.SetImportLocation(importLocation); importedClassTable.Add(className, mergedClassItem); } return(Success); }
private static bool PropertyTypeConformToPropertyType(IPropertyType 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 && derivedType.PropertyKind == BaseNode.UtilityType.WriteOnly) || (baseType.PropertyKind == BaseNode.UtilityType.WriteOnly && derivedType.PropertyKind == BaseNode.UtilityType.ReadOnly) || (baseType.PropertyKind == BaseNode.UtilityType.ReadWrite && derivedType.PropertyKind != BaseNode.UtilityType.ReadWrite)) { errorList.AddError(new ErrorGetterSetterConformance(sourceLocation, derivedType, baseType)); Result = false; } Debug.Assert(derivedType.ResolvedEntityType.IsAssigned); Debug.Assert(baseType.ResolvedEntityType.IsAssigned); /* * if (!TypesHaveIdenticalSignature(derivedType.ResolvedEntityType.Item, baseType.ResolvedEntityType.Item)) * { * //errorList.Add(new ConformanceError(sourceLocation)); * return false; * } */ Result &= TypeConformToBase(derivedType.ResolvedEntityType.Item, baseType.ResolvedEntityType.Item, errorList, sourceLocation, isConversionAllowed: false); Result &= ExceptionListConformToBase(derivedType.GetExceptionIdentifierList, baseType.GetExceptionIdentifierList, errorList, sourceLocation); Result &= ExceptionListConformToBase(derivedType.SetExceptionIdentifierList, baseType.SetExceptionIdentifierList, errorList, sourceLocation); return(Result); }
/// <summary> /// Checks that a command overload conforms to another. /// </summary> /// <param name="derivedType">The derived type.</param> /// <param name="baseType">The base type.</param> /// <param name="errorList">The list of errors found.</param> /// <param name="sourceLocation">The location for reporting errors.</param> public static bool CommandOverloadConformToBase(ICommandOverloadType derivedType, ICommandOverloadType baseType, IErrorList errorList, ISource sourceLocation) { bool Result = true; if (baseType.ParameterList.Count != derivedType.ParameterList.Count || baseType.ParameterEnd != derivedType.ParameterEnd) { errorList.AddError(new ErrorParameterMismatchConformance(sourceLocation, derivedType, baseType)); Result = false; } for (int i = 0; i < baseType.ParameterList.Count && i < derivedType.ParameterList.Count; i++) { IEntityDeclaration BaseParameter = baseType.ParameterList[i]; IEntityDeclaration DerivedParameter = derivedType.ParameterList[i]; Debug.Assert(DerivedParameter.ValidEntity.IsAssigned); Debug.Assert(DerivedParameter.ValidEntity.Item.ResolvedEffectiveType.IsAssigned); Debug.Assert(BaseParameter.ValidEntity.IsAssigned); Debug.Assert(BaseParameter.ValidEntity.Item.ResolvedEffectiveType.IsAssigned); Result &= TypeConformToBase(DerivedParameter.ValidEntity.Item.ResolvedEffectiveType.Item, BaseParameter.ValidEntity.Item.ResolvedEffectiveType.Item, errorList, sourceLocation, isConversionAllowed: false); } Result &= ExceptionListConformToBase(derivedType.ExceptionIdentifierList, baseType.ExceptionIdentifierList, errorList, sourceLocation); return(Result); }
/// <summary> /// Finds the matching nodes of a <see cref="IResultOfExpression"/>. /// </summary> /// <param name="node">The agent expression to check.</param> /// <param name="errorList">The list of errors found.</param> /// <param name="resolvedResult">The expression result types upon return.</param> /// <param name="resolvedException">Exceptions the expression can throw upon return.</param> /// <param name="constantSourceList">Sources of the constant expression upon return, if any.</param> /// <param name="expressionConstant">The expression constant upon return.</param> public static bool ResolveCompilerReferences(IResultOfExpression node, IErrorList errorList, out IResultType resolvedResult, out IResultException resolvedException, out ISealableList <IExpression> constantSourceList, out ILanguageConstant expressionConstant) { resolvedResult = null; resolvedException = null; constantSourceList = new SealableList <IExpression>(); expressionConstant = NeutralLanguageConstant.NotConstant; IExpression Source = (IExpression)node.Source; IResultType ResolvedSourceResult = Source.ResolvedResult.Item; int ResultNameIndex = ResolvedSourceResult.ResultNameIndex; if (ResultNameIndex < 0) { errorList.AddError(new ErrorInvalidExpression(node)); return(false); } Debug.Assert(ResolvedSourceResult.Preferred != null); resolvedResult = new ResultType(ResolvedSourceResult.Preferred); constantSourceList.Add(Source); ResultException.Propagate(Source.ResolvedException, out resolvedException); #if COVERAGE Debug.Assert(node.IsComplex); #endif return(true); }
private static bool QueryOverloadHasPropertyConformingBase(IQueryOverloadType derivedOverload, IPropertyType baseType, IErrorList errorList, ISource sourceLocation) { bool Result = true; if (derivedOverload.ParameterList.Count > 0 || derivedOverload.ResultList.Count != 1 || derivedOverload.ParameterEnd != BaseNode.ParameterEndStatus.Closed) { errorList.AddError(new ErrorOverloadParameterMismatchConformance(sourceLocation, derivedOverload, baseType)); Result = false; } if (derivedOverload.ResultList.Count == 1) { IEntityDeclaration OverloadResult = derivedOverload.ResultList[0]; Debug.Assert(baseType.ResolvedEntityType.IsAssigned); Debug.Assert(OverloadResult.ValidEntity.IsAssigned); Debug.Assert(OverloadResult.ValidEntity.Item.ResolvedEffectiveType.IsAssigned); Result &= TypeConformToBase(baseType.ResolvedEntityType.Item, OverloadResult.ValidEntity.Item.ResolvedEffectiveType.Item, errorList, sourceLocation, isConversionAllowed: false); } Result &= ExceptionListConformToBase(derivedOverload.ExceptionIdentifierList, baseType.GetExceptionIdentifierList, errorList, sourceLocation); return(Result); }
private static bool ResolveCallClass(IPrecursorExpression node, IFeatureInstance selectedPrecursor, List <IExpressionType> mergedArgumentList, TypeArgumentStyles argumentStyle, IErrorList errorList, ref ResolvedExpression resolvedExpression, out ISealableList <IParameter> selectedParameterList, out ISealableList <IParameter> selectedResultList, out List <IExpressionType> resolvedArgumentList) { selectedParameterList = null; selectedResultList = null; resolvedArgumentList = null; IList <IArgument> ArgumentList = node.ArgumentList; if (ArgumentList.Count > 0) { errorList.AddError(new ErrorInvalidExpression(node)); return(false); } else { ICompiledFeature OperatorFeature = selectedPrecursor.Feature; ITypeName OperatorTypeName = OperatorFeature.ResolvedEffectiveTypeName.Item; ICompiledType OperatorType = OperatorFeature.ResolvedEffectiveType.Item; IList <ISealableList <IParameter> > ParameterTableList = new List <ISealableList <IParameter> >(); resolvedExpression.ResolvedResult = new ResultType(OperatorTypeName, OperatorType, string.Empty); resolvedExpression.ResolvedException = new ResultException(); selectedParameterList = new SealableList <IParameter>(); selectedResultList = new SealableList <IParameter>(); resolvedArgumentList = new List <IExpressionType>(); } return(true); }
private static bool GetArgumentPassingStyle(IList <IArgument> argumentList, out TypeArgumentStyles argumentStyle, IErrorList errorList) { argumentStyle = TypeArgumentStyles.None; foreach (IArgument Argument in argumentList) { bool IsHandled = false; switch (Argument) { case IPositionalArgument AsPositionalArgument: if (argumentStyle == TypeArgumentStyles.None) { argumentStyle = TypeArgumentStyles.Positional; } else if (argumentStyle == TypeArgumentStyles.Assignment) { errorList.AddError(new ErrorArgumentMixed(AsPositionalArgument)); return(false); } IsHandled = true; break; case IAssignmentArgument AsAssignmentArgument: if (argumentStyle == TypeArgumentStyles.None) { argumentStyle = TypeArgumentStyles.Assignment; } else if (argumentStyle == TypeArgumentStyles.Positional) { errorList.AddError(new ErrorArgumentMixed(AsAssignmentArgument)); return(false); } IsHandled = true; break; } Debug.Assert(IsHandled); } return(true); }