/// <summary> /// Finds the matching nodes of a <see cref="IKeywordExpression"/>. /// </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(IKeywordExpression 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; BaseNode.Keyword Value = node.Value; if (!IsKeywordAvailable(Value, node, errorList, out ITypeName KeywordTypeName, out ICompiledType KeywordType)) { return(false); } resolvedResult = new ResultType(KeywordTypeName, KeywordType, Value.ToString()); resolvedException = new ResultException(); bool IsHandled = false; switch (Value) { case BaseNode.Keyword.True: case BaseNode.Keyword.False: expressionConstant = new BooleanLanguageConstant(Value == BaseNode.Keyword.True); IsHandled = true; break; case BaseNode.Keyword.Current: case BaseNode.Keyword.Value: case BaseNode.Keyword.Result: case BaseNode.Keyword.Retry: case BaseNode.Keyword.Exception: case BaseNode.Keyword.Indexer: IsHandled = true; break; } Debug.Assert(IsHandled); #if COVERAGE Debug.Assert(!node.IsComplex); #endif return(true); }
/// <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="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); }