/// <summary> /// Checks for errors before applying a rule. /// </summary> /// <param name="node">The node instance to check.</param> /// <param name="dataList">Optional data collected during inspection of sources.</param> /// <param name="data">Private data to give to Apply() upon return.</param> /// <returns>True if an error occured.</returns> public override bool CheckConsistency(IOverLoopInstruction node, IDictionary <ISourceTemplate, object> dataList, out object data) { data = null; bool Success = true; IExpression OverList = (IExpression)node.OverList; IResultType OverTypeList = OverList.ResolvedResult.Item; IScope LoopInstructions = (IScope)node.LoopInstructions; IClass EmbeddingClass = node.EmbeddingClass; bool IsOverLoopSourceTypeAvailable = Expression.IsLanguageTypeAvailable(LanguageClasses.OverLoopSource.Guid, node, out ITypeName OverLoopSourceTypeName, out ICompiledType OverLoopSourceType); bool IsNumberTypeAvailable = Expression.IsLanguageTypeAvailable(LanguageClasses.Number.Guid, node, out ITypeName NumberTypeName, out ICompiledType NumberType); foreach (IExpressionType Item in OverTypeList) { ICompiledType ResultType = Item.ValueType; IErrorList OverSourceErrorList = new ErrorList(); bool IsConformantToEnumerable = false; bool IsConformantToNumericIndexer = false; if (IsOverLoopSourceTypeAvailable && ObjectType.TypeConformToBase(ResultType, OverLoopSourceType, isConversionAllowed: true)) { IsConformantToEnumerable = true; } if (IsNumberTypeAvailable && ResultType.FeatureTable.ContainsKey(FeatureName.IndexerFeatureName)) { IFeatureInstance IndexerInstance = ResultType.FeatureTable[FeatureName.IndexerFeatureName]; IIndexerFeature IndexerFeature = IndexerInstance.Feature as IIndexerFeature; Debug.Assert(IndexerFeature != null); if (IndexerFeature.IndexParameterList.Count == 1) { IEntityDeclaration IndexParameterDeclaration = IndexerFeature.IndexParameterList[0]; if (IndexParameterDeclaration.ValidEntity.Item.ResolvedEffectiveType.Item == NumberType) { IsConformantToNumericIndexer = true; } } } Debug.Assert(IsConformantToEnumerable != IsConformantToNumericIndexer); } IResultException ResolvedException = new ResultException(); ResultException.Merge(ResolvedException, OverList.ResolvedException.Item); ResultException.Merge(ResolvedException, LoopInstructions.ResolvedException.Item); foreach (IAssertion Item in node.InvariantList) { ResultException.Merge(ResolvedException, Item.ResolvedException.Item); } data = ResolvedException; return(Success); }
private static bool IsIndexerFeatureReady(IIndexerFeature feature, out ITypeName resolvedPathTypeName, out ICompiledType resolvedPathType) { bool Result = false; resolvedPathTypeName = null; resolvedPathType = null; if (feature.ResolvedEntityTypeName.IsAssigned && feature.ResolvedEntityType.IsAssigned) { resolvedPathTypeName = feature.ResolvedEntityTypeName.Item; resolvedPathType = feature.ResolvedEntityType.Item; Result = true; } return(Result); }
private static bool ResolveSelectedPrecursor(IPrecursorIndexExpression node, IFeatureInstance selectedPrecursor, IErrorList errorList, ref ResolvedExpression resolvedExpression) { IList <IArgument> ArgumentList = node.ArgumentList; List <IExpressionType> MergedArgumentList = new List <IExpressionType>(); if (!Argument.Validate(ArgumentList, MergedArgumentList, out TypeArgumentStyles TypeArgumentStyle, errorList)) { return(false); } IIndexerFeature OperatorFeature = selectedPrecursor.Feature as IIndexerFeature; Debug.Assert(OperatorFeature != null); IIndexerType OperatorType = OperatorFeature.ResolvedAgentType.Item as IIndexerType; Debug.Assert(OperatorType != null); IList <ISealableList <IParameter> > ParameterTableList = new List <ISealableList <IParameter> >(); ParameterTableList.Add(OperatorType.ParameterTable); IList <ISealableList <IParameter> > ResultTableList = new List <ISealableList <IParameter> >(); ResultTableList.Add(new SealableList <IParameter>()); int SelectedIndex; if (!Argument.ArgumentsConformToParameters(ParameterTableList, MergedArgumentList, TypeArgumentStyle, errorList, node, out SelectedIndex)) { return(false); } resolvedExpression.ResolvedResult = new ResultType(OperatorType.ResolvedEntityTypeName.Item, OperatorType.ResolvedEntityType.Item, string.Empty); resolvedExpression.ResolvedException = new ResultException(OperatorType.GetExceptionIdentifierList); resolvedExpression.FeatureCall = new FeatureCall(ParameterTableList[SelectedIndex], ResultTableList[SelectedIndex], ArgumentList, MergedArgumentList, TypeArgumentStyle); resolvedExpression.ResolvedFinalFeature = OperatorFeature; Argument.AddConstantArguments(ArgumentList, resolvedExpression.ConstantSourceList); return(true); }
private bool FindIndexer(IClassType instancingClassType, ISource source, IFeatureInstance indexerInstance, out ITypeName indexTypeName, out ICompiledType indexType) { bool IsConformantToNumericIndexer = false; indexTypeName = null; indexType = null; IIndexerFeature AsIndexer = indexerInstance.Feature as IIndexerFeature; Debug.Assert(AsIndexer != null); if (AsIndexer.IndexParameterList.Count == 1) { if (Expression.IsLanguageTypeAvailable(LanguageClasses.Number.Guid, source, out ITypeName NumberTypeName, out ICompiledType NumberType)) { IEntityDeclaration IndexParameterDeclaration = AsIndexer.IndexParameterList[0]; ICompiledType IndexParameterType = IndexParameterDeclaration.ValidEntity.Item.ResolvedEffectiveType.Item; if (IndexParameterType is IClassType AsClassIndexType) { if (AsClassIndexType == NumberType) { ITypeName IndexResultTypeName = AsIndexer.ResolvedEntityTypeName.Item; ICompiledType IndexResultType = AsIndexer.ResolvedEntityType.Item; IndexResultType.InstanciateType(instancingClassType, ref IndexResultTypeName, ref IndexResultType); IsConformantToNumericIndexer = true; indexTypeName = IndexResultTypeName; indexType = IndexResultType; } } } } return(IsConformantToNumericIndexer); }
/// <summary> /// Checks that a keyword is available in the context of the source. /// </summary> /// <param name="keyword">The keyword to check.</param> /// <param name="source">The source node.</param> /// <param name="errorList">The list of errors found if not available.</param> /// <param name="resultTypeName">The resulting type name upon return if available.</param> /// <param name="resultType">The resulting type upon return if available.</param> public static bool IsKeywordAvailable(BaseNode.Keyword keyword, ISource source, IErrorList errorList, out ITypeName resultTypeName, out ICompiledType resultType) { resultTypeName = null; resultType = null; bool Result = false; bool IsHandled = false; IClass EmbeddingClass = source.EmbeddingClass; switch (keyword) { case BaseNode.Keyword.True: case BaseNode.Keyword.False: case BaseNode.Keyword.Retry: if (!Expression.IsLanguageTypeAvailable(LanguageClasses.Boolean.Guid, source, out resultTypeName, out resultType)) { errorList.AddError(new ErrorBooleanTypeMissing(source)); } else { Result = true; } IsHandled = true; break; case BaseNode.Keyword.Current: Debug.Assert(EmbeddingClass.ResolvedClassTypeName.IsAssigned); Debug.Assert(EmbeddingClass.ResolvedClassType.IsAssigned); resultTypeName = EmbeddingClass.ResolvedClassTypeName.Item; resultType = EmbeddingClass.ResolvedClassType.Item; Result = true; IsHandled = true; break; case BaseNode.Keyword.Value: Result = IsWithinProperty(source, errorList, out resultTypeName, out resultType); IsHandled = true; break; case BaseNode.Keyword.Result: Result = IsWithinGetter(source, errorList, out resultTypeName, out resultType); IsHandled = true; break; case BaseNode.Keyword.Exception: if (!Expression.IsLanguageTypeAvailable(LanguageClasses.Exception.Guid, source, out resultTypeName, out resultType)) { errorList.AddError(new ErrorExceptionTypeMissing(source)); } else { Result = true; } IsHandled = true; break; case BaseNode.Keyword.Indexer: if (EmbeddingClass.ClassIndexer.IsAssigned) { IIndexerFeature IndexerFeature = EmbeddingClass.ClassIndexer.Item; Debug.Assert(IndexerFeature.ResolvedAgentTypeName.IsAssigned); Debug.Assert(IndexerFeature.ResolvedAgentType.IsAssigned); resultTypeName = IndexerFeature.ResolvedAgentTypeName.Item; resultType = IndexerFeature.ResolvedAgentType.Item; Result = true; } else { errorList.AddError(new ErrorMissingIndexer(source)); } IsHandled = true; break; } Debug.Assert(IsHandled); return(Result); }
/// <summary> /// Finds the matching nodes of a <see cref="IIndexQueryExpression"/>. /// </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(IIndexQueryExpression node, IErrorList errorList, out ResolvedExpression resolvedExpression) { resolvedExpression = new ResolvedExpression(); IExpression IndexedExpression = (IExpression)node.IndexedExpression; IList <IArgument> ArgumentList = node.ArgumentList; IClass EmbeddingClass = node.EmbeddingClass; IResultType ResolvedIndexerResult = IndexedExpression.ResolvedResult.Item; IExpressionType PreferredIndexerResult = ResolvedIndexerResult.Preferred; ICompiledType IndexedExpressionType; if (PreferredIndexerResult == null) { errorList.AddError(new ErrorInvalidExpression(node)); return(false); } else { IndexedExpressionType = PreferredIndexerResult.ValueType; } if (IndexedExpressionType is IClassType AsClassType) { IClass IndexedBaseClass = AsClassType.BaseClass; ISealableDictionary <IFeatureName, IFeatureInstance> IndexedFeatureTable = IndexedBaseClass.FeatureTable; if (!IndexedFeatureTable.ContainsKey(FeatureName.IndexerFeatureName)) { errorList.AddError(new ErrorMissingIndexer(node)); return(false); } IFeatureInstance IndexerInstance = IndexedFeatureTable[FeatureName.IndexerFeatureName]; IIndexerFeature Indexer = (IndexerFeature)IndexerInstance.Feature; IIndexerType AsIndexerType = (IndexerType)Indexer.ResolvedAgentType.Item; List <IExpressionType> MergedArgumentList = new List <IExpressionType>(); if (!Argument.Validate(ArgumentList, MergedArgumentList, out TypeArgumentStyles TypeArgumentStyle, errorList)) { return(false); } IList <ISealableList <IParameter> > ParameterTableList = new List <ISealableList <IParameter> >(); ParameterTableList.Add(AsIndexerType.ParameterTable); IList <ISealableList <IParameter> > ResultTableList = new List <ISealableList <IParameter> >(); ResultTableList.Add(new SealableList <IParameter>()); int SelectedIndex; if (!Argument.ArgumentsConformToParameters(ParameterTableList, MergedArgumentList, TypeArgumentStyle, errorList, node, out SelectedIndex)) { return(false); } resolvedExpression.ResolvedFinalFeature = Indexer; resolvedExpression.ResolvedResult = new ResultType(AsIndexerType.ResolvedEntityTypeName.Item, AsIndexerType.ResolvedEntityType.Item, string.Empty); resolvedExpression.ResolvedException = new ResultException(AsIndexerType.GetExceptionIdentifierList); resolvedExpression.FeatureCall = new FeatureCall(ParameterTableList[SelectedIndex], ResultTableList[SelectedIndex], ArgumentList, MergedArgumentList, TypeArgumentStyle); Argument.AddConstantArguments(ArgumentList, resolvedExpression.ConstantSourceList); } else { errorList.AddError(new ErrorInvalidExpression(node)); return(false); } #if COVERAGE Debug.Assert(!node.IsComplex); #endif return(true); }
private static ISealableDictionary <string, IScopeAttributeFeature> CurrentIndexerScope(IIndexerFeature indexerFeature, ISource childSource) { ISealableDictionary <string, IScopeAttributeFeature> Result = null; bool IsHandled = false; if (indexerFeature.GetterBody.IsAssigned && indexerFeature.GetterBody.Item == childSource) { Result = indexerFeature.FullGetScope; IsHandled = true; } else if (indexerFeature.SetterBody.IsAssigned && indexerFeature.SetterBody.Item == childSource) { Result = indexerFeature.FullSetScope; IsHandled = true; } Debug.Assert(IsHandled); return(Result); }
/// <summary> /// Finds the matching nodes of a <see cref="IKeywordEntityExpression"/>. /// </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> public static bool ResolveCompilerReferences(IKeywordEntityExpression node, IErrorList errorList, out IResultType resolvedResult, out IResultException resolvedException, out ISealableList <IExpression> constantSourceList, out ILanguageConstant expressionConstant, out ICompiledFeature resolvedFinalFeature) { if (node == null) { throw new ArgumentNullException(nameof(node)); } if (errorList == null) { throw new ArgumentNullException(nameof(errorList)); } resolvedResult = null; resolvedException = null; constantSourceList = new SealableList <IExpression>(); expressionConstant = NeutralLanguageConstant.NotConstant; resolvedFinalFeature = null; IClass EmbeddingClass = node.EmbeddingClass; BaseNode.Keyword Value = node.Value; if (!Expression.IsLanguageTypeAvailable(LanguageClasses.Entity.Guid, node, out ITypeName ResultTypeName, out ICompiledType ResultType)) { errorList.AddError(new ErrorEntityTypeMissing(node)); return(false); } Guid EntityGuid = Guid.Empty; switch (node.Value) { case BaseNode.Keyword.Indexer: if (EmbeddingClass.ClassIndexer.IsAssigned) { IIndexerFeature ClassIndexer = EmbeddingClass.ClassIndexer.Item; resolvedFinalFeature = ClassIndexer; EntityGuid = ClassIndexer.EntityGuid; expressionConstant = new EntityLanguageConstant(ClassIndexer); } else { errorList.AddError(new ErrorMissingIndexer(node)); return(false); } break; default: errorList.AddError(new ErrorInvalidExpression(node)); return(false); } Debug.Assert(EntityGuid != Guid.Empty); ITypeName EntityTypeName = EmbeddingClass.ImportedLanguageTypeTable[EntityGuid].Item1; ICompiledType EntityType = EmbeddingClass.ImportedLanguageTypeTable[EntityGuid].Item2; resolvedResult = new ResultType(EntityTypeName, EntityType, string.Empty); resolvedException = new ResultException(); #if COVERAGE Debug.Assert(!node.IsComplex); #endif return(true); }
/// <summary> /// Checks for errors before applying a rule. /// </summary> /// <param name="node">The node instance to check.</param> /// <param name="dataList">Optional data collected during inspection of sources.</param> /// <param name="data">Private data to give to Apply() upon return.</param> /// <returns>True if an error occured.</returns> public override bool CheckConsistency(IIndexAssignmentInstruction node, IDictionary <ISourceTemplate, object> dataList, out object data) { data = null; bool Success = true; IQualifiedName Destination = (IQualifiedName)node.Destination; IExpression Source = (IExpression)node.Source; IList <IIdentifier> ValidPath = Destination.ValidPath.Item; IClass EmbeddingClass = node.EmbeddingClass; IClassType BaseType = EmbeddingClass.ResolvedClassType.Item; ISealableDictionary <string, IScopeAttributeFeature> LocalScope = Scope.CurrentScope(node); 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); } Debug.Assert(FinalFeature != null); FinalType = FinalFeature.ResolvedEffectiveType.Item; if (FinalType is IClassType AsClassType) { IClass IndexedBaseClass = AsClassType.BaseClass; ISealableDictionary <IFeatureName, IFeatureInstance> IndexedFeatureTable = IndexedBaseClass.FeatureTable; if (!IndexedFeatureTable.ContainsKey(FeatureName.IndexerFeatureName)) { AddSourceError(new ErrorMissingIndexer(node)); return(false); } IFeatureInstance IndexerInstance = IndexedFeatureTable[FeatureName.IndexerFeatureName]; IIndexerFeature Indexer = (IndexerFeature)IndexerInstance.Feature; IIndexerType AsIndexerType = (IndexerType)Indexer.ResolvedAgentType.Item; bool IsReadOnlyIndexer = Indexer.GetterBody.IsAssigned && !Indexer.SetterBody.IsAssigned; bool IsReadOnlyIndexerType = AsIndexerType.IndexerKind == BaseNode.UtilityType.ReadOnly; Debug.Assert(IsReadOnlyIndexerType == IsReadOnlyIndexer); if (IsReadOnlyIndexer) { AddSourceError(new ErrorInvalidInstruction(node)); return(false); } else { IList <ISealableList <IParameter> > ParameterTableList = new List <ISealableList <IParameter> >(); ParameterTableList.Add(AsIndexerType.ParameterTable); IList <ISealableList <IParameter> > ResultTableList = new List <ISealableList <IParameter> >(); ResultTableList.Add(new SealableList <IParameter>()); ICompiledType DestinationType = AsIndexerType.ResolvedEntityType.Item; if (!Argument.CheckAssignmentConformance(ParameterTableList, ResultTableList, node.ArgumentList, Source, DestinationType, ErrorList, node, out IFeatureCall FeatureCall)) { return(false); } ObjectType.FillResultPath(EmbeddingClass, BaseType, LocalScope, ValidPath, 0, Destination.ValidResultTypePath.Item); IResultException ResolvedException = new ResultException(); ResultException.Merge(ResolvedException, AsIndexerType.SetExceptionIdentifierList); foreach (IArgument Item in node.ArgumentList) { ResultException.Merge(ResolvedException, Item.ResolvedException.Item); } data = new Tuple <IResultException, IFeatureCall>(ResolvedException, FeatureCall); } } else { AddSourceError(new ErrorInvalidInstruction(node)); return(false); } return(Success); }