/// <summary> /// Initializes a new instance of the <see cref="CSharpEntityExpression"/> class. /// </summary> /// <param name="context">The creation context.</param> /// <param name="source">The Easly expression from which the C# expression is created.</param> protected CSharpEntityExpression(ICSharpContext context, IEntityExpression source) : base(context, source) { if (Source.ResolvedFinalFeature.IsAssigned) { ICompiledFeature ResolvedFeature = Source.ResolvedFinalFeature.Item; if (ResolvedFeature is IScopeAttributeFeature AsScopeAttributeFeature) { ICSharpClass Owner = context.GetClass(source.EmbeddingClass); Feature = CSharpScopeAttributeFeature.Create(context, Owner, AsScopeAttributeFeature); } else { Feature = context.GetFeature(Source.ResolvedFinalFeature.Item); } } if (Source.ResolvedFinalDiscrete.IsAssigned) { ICSharpClass Class = context.GetClass(Source.ResolvedFinalDiscrete.Item.EmbeddingClass); foreach (ICSharpDiscrete Item in Class.DiscreteList) { if (Item.Source == Source.ResolvedFinalDiscrete.Item) { Debug.Assert(Discrete == null); Discrete = Item; } } } Debug.Assert((Feature != null && Discrete == null) || (Feature == null && Discrete != null)); Query = CSharpQualifiedName.Create(context, (IQualifiedName)Source.Query, Feature, Discrete, false); }
/// <summary> /// Compares two expressions. /// </summary> /// <param name="other">The other expression.</param> protected bool IsExpressionEqual(IEntityExpression other) { Debug.Assert(other != null); bool Result = true; Result &= QualifiedName.IsQualifiedNameEqual((IQualifiedName)Query, (IQualifiedName)other.Query); return(Result); }
/// <exception cref="InvalidOperationException">Unable to materialize Entity.</exception> private Expression CreateEntity(IEntityExpression expression, Expression tupleExpression) { int index; if (!entityRegistry.TryGetValue(expression, out index)) { index = entityRegistry.Count; entityRegistry.Add(expression, index); } if (itemMaterializationContextParameter == null) { throw new InvalidOperationException(String.Format(Strings.ExUnableToTranslateLambdaExpressionXBecauseItRequiresToMaterializeEntityOfTypeX, context.Translator.state.CurrentLambda, expression.PersistentType.UnderlyingType.FullName)); } var typeIdField = expression.Fields.SingleOrDefault(f => f.Name == WellKnown.TypeIdFieldName); int typeIdIndex = typeIdField == null ? -1 : typeIdField.Mapping.Offset; var mappingInfo = expression.Fields .OfType <FieldExpression>() .Where(f => f.ExtendedType == ExtendedExpressionType.Field) .OrderBy(f => f.Field.MappingInfo.Offset) .Select(f => new Pair <int>(f.Field.MappingInfo.Offset, f.Mapping.Offset)) .Distinct() .ToArray(); var isMaterializedExpression = Expression.Call( itemMaterializationContextParameter, ItemMaterializationContext.IsMaterializedMethodInfo, Expression.Constant(index)); var getEntityExpression = Expression.Call( itemMaterializationContextParameter, ItemMaterializationContext.GetEntityMethodInfo, Expression.Constant(index)); var materializeEntityExpression = Expression.Call( itemMaterializationContextParameter, ItemMaterializationContext.MaterializeMethodInfo, Expression.Constant(index), Expression.Constant(typeIdIndex), Expression.Constant(expression.PersistentType), Expression.Constant(mappingInfo), tupleExpression); return(Expression.TypeAs( Expression.Condition( isMaterializedExpression, getEntityExpression, materializeEntityExpression), expression.Type)); }
/// <summary> /// Creates a new C# expression. /// </summary> /// <param name="context">The creation context.</param> /// <param name="source">The Easly expression from which the C# expression is created.</param> public static ICSharpEntityExpression Create(ICSharpContext context, IEntityExpression source) { return(new CSharpEntityExpression(context, source)); }
/// <summary> /// Finds the matching nodes of a <see cref="IEntityExpression"/>. /// </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> public static bool ResolveCompilerReferences(IEntityExpression node, IErrorList errorList, out IResultType resolvedResult, out IResultException resolvedException, out ISealableList <IExpression> constantSourceList, out ILanguageConstant expressionConstant, out ICompiledFeature resolvedFinalFeature, out IDiscrete resolvedFinalDiscrete) { resolvedResult = null; resolvedException = null; constantSourceList = new SealableList <IExpression>(); expressionConstant = NeutralLanguageConstant.NotConstant; resolvedFinalFeature = null; resolvedFinalDiscrete = null; IQualifiedName Query = (IQualifiedName)node.Query; IClass EmbeddingClass = (Class)node.EmbeddingClass; IClassType BaseType = EmbeddingClass.ResolvedClassType.Item; if (!Expression.IsLanguageTypeAvailable(LanguageClasses.Entity.Guid, node, out ITypeName ResultTypeName, out ICompiledType ResultType)) { errorList.AddError(new ErrorEntityTypeMissing(node)); return(false); } IList <IIdentifier> ValidPath = Query.ValidPath.Item; IIdentifier LastIdentifier = ValidPath[ValidPath.Count - 1]; string ValidText = LastIdentifier.ValidText.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); } Guid EntityGuid; if (FinalFeature is IFeatureWithEntity AsFeatureWithEntity) { ObjectType.FillResultPath(EmbeddingClass, BaseType, LocalScope, ValidPath, 0, Query.ValidResultTypePath.Item); resolvedFinalFeature = FinalFeature; EntityGuid = AsFeatureWithEntity.EntityGuid; expressionConstant = new EntityLanguageConstant(AsFeatureWithEntity); } else { Debug.Assert(FinalDiscrete != null); resolvedFinalDiscrete = FinalDiscrete; EntityGuid = LanguageClasses.NamedFeatureEntity.Guid; expressionConstant = new EntityLanguageConstant(resolvedFinalDiscrete); } ITypeName EntityTypeName = EmbeddingClass.ImportedLanguageTypeTable[EntityGuid].Item1; ICompiledType EntityType = EmbeddingClass.ImportedLanguageTypeTable[EntityGuid].Item2; resolvedResult = new ResultType(EntityTypeName, EntityType, ValidText); resolvedException = new ResultException(); #if COVERAGE Debug.Assert(!node.IsComplex); #endif return(true); }