internal static GrapeCallExpression Create(GrapeIdentifier identifier, GrapeList<GrapeExpression> parameters, GrapeAccessExpression next) { List<GrapeEntity> children = new List<GrapeEntity>(); children.Add(identifier); children.AddRange(parameters.Enumerate()); GrapeCallExpression result = new GrapeCallExpression(identifier, parameters, next); result.InitializeFromTemplate(identifier); result.InitializeFromChildren(identifier.FileName, children); return result; }
internal static GrapeMemberExpression Create(GrapeAccessExpressionType type, GrapeIdentifier identifier, GrapeAccessExpression next) { if (identifier == null) { throw new ArgumentNullException("identifier"); } Debug.Assert((type == GrapeAccessExpressionType.Root) || (type == GrapeAccessExpressionType.Field)); GrapeMemberExpression result = new GrapeMemberExpression(type, identifier, next); result.InitializeFromTemplate(identifier); return result; }
private GrapeAccessExpression ToExpression(GrapeAccessExpression next) { next = GetAccessor(next); if (identifiers.Count > 0) { next = ToExpression(identifiers[identifiers.Count - 1], next); for (int i = identifiers.Count - 2; i >= 0; i--) { next = GrapeMemberExpression.Create(i == 0 ? GrapeAccessExpression.GrapeAccessExpressionType.Root : GrapeAccessExpression.GrapeAccessExpressionType.Field, identifiers[i], next); } } return next; }
protected override GrapeAccessExpression ToExpression(GrapeIdentifier identifier, GrapeAccessExpression next) { return GrapeCallExpression.Create(identifier, parameters, next); }
protected virtual GrapeAccessExpression ToExpression(GrapeIdentifier identifier, GrapeAccessExpression next) { return GrapeMemberExpression.Create((identifiers.Count == 1) && (ofMember == null) ? GrapeAccessExpression.GrapeAccessExpressionType.Root : GrapeAccessExpression.GrapeAccessExpressionType.Field, identifier, next); }
protected virtual GrapeAccessExpression GetAccessor(GrapeAccessExpression next) { return (ofMember != null) ? ofMember.ToExpression(next) : next; }
private GrapeCallExpression(GrapeIdentifier identifier, GrapeList<GrapeExpression> parameters, GrapeAccessExpression next): base(GrapeAccessExpressionType.Method, identifier, next) { this.parameters = parameters.ToList(this).AsReadOnly(); }
protected GrapeMemberExpression(GrapeAccessExpressionType type, GrapeIdentifier identifier, GrapeAccessExpression next): base(next) { Debug.Assert(type != GrapeAccessExpressionType.Array); this.type = type; this.identifier = identifier; }
protected GrapeAccessExpression(GrapeAccessExpression next) { this.next = next; }
public GrapeSetExpression(GrapeAccessExpression memberAccess, GrapeExpression value) { this.memberAccess = memberAccess; this.value = value; }
public IEnumerable<GrapeEntity> GetEntitiesForAccessExpression(GrapeCodeGeneratorConfiguration config, GrapeAccessExpression accessExpression, GrapeEntity parent, out string errorMessage, bool detectMethodsUsedAsTypesOrVars) { errorMessage = ""; string memberExpressionQualifiedId = accessExpression.GetAccessExpressionQualifiedId(); if (memberExpressionQualifiedId == "this") { if ((accessExpression.GetType() != typeof(GrapeMemberExpression) && accessExpression.GetType() != typeof(GrapeSetExpression)) || (parent is GrapeExpression && parent.GetType() != typeof(GrapeMemberExpression) && parent.GetType() != typeof(GrapeSetExpression))) { errorMessage = "Cannot access this class through a statement expression."; return new GrapeEntity[] { null }; } GrapeClass thisClass = parent.GetLogicalParentOfEntityType<GrapeClass>(); if (thisClass != null) { return new GrapeEntity[] { thisClass }; } return new GrapeEntity[] { null }; } else if (memberExpressionQualifiedId == "base") { if ((accessExpression.GetType() != typeof(GrapeMemberExpression) && accessExpression.GetType() != typeof(GrapeSetExpression)) || (parent is GrapeExpression && parent.GetType() != typeof(GrapeMemberExpression) && parent.GetType() != typeof(GrapeSetExpression))) { errorMessage = "Cannot access base class through a statement expression."; return new GrapeEntity[] { null }; } GrapeClass thisClass = parent.GetLogicalParentOfEntityType<GrapeClass>(); if (thisClass != null && thisClass.Inherits != null) { GrapeClass baseClass = astUtils.GetClassWithNameFromImportedPackagesInFile(config.Ast, GetTypeNameForTypeAccessExpression(config, thisClass.Inherits, ref errorMessage), parent.FileName); return new GrapeEntity[] { baseClass }; } return new GrapeEntity[] { null }; } else if (accessExpression is GrapeCallExpression) { GrapeAccessExpression identifierExpression = accessExpression.GetAccessExpressionInAccessExpression(); GrapeEntity entity = null; GrapeEntity lastParent = null; GrapeEntity lastLastParent = null; GrapeEntity lastMemberAccess = null; GrapeAccessExpression currentExpression = identifierExpression; bool lastClassAccessWasThisOrBaseAccess = false; bool shouldBeStatic = false; bool staticnessMatters = false; while (currentExpression != null) { //lastParent = (new List<GrapeEntity>(GetEntitiesForAccessExpression(config, currentExpression, lastParent == null ? accessExpression as GrapeEntity : lastParent.GetLogicalParentOfEntityType<GrapeClass>(), out errorMessage)))[0]; if (currentExpression is GrapeCallExpression) { List<GrapeEntity> list = (new List<GrapeEntity>(astUtils.GetMethodsWithNameFromImportedPackagesInFile(config, currentExpression.GetAccessExpressionQualifiedId(), currentExpression.FileName, currentExpression.GetLogicalParentOfEntityType<GrapeClass>()))); if (list.Count > 0) { lastParent = list[0]; } } else { lastParent = (new List<GrapeEntity>(GetEntitiesForAccessExpression(config, currentExpression, lastParent == null ? accessExpression as GrapeEntity : lastParent.GetLogicalParentOfEntityType<GrapeClass>(), out errorMessage)))[0]; } if (lastParent == null) { break; } if (lastParent is GrapeMethod && !(currentExpression is GrapeCallExpression) && !(accessExpression is GrapeCallExpression) && !(parent is GrapeCallExpression) && detectMethodsUsedAsTypesOrVars) { errorMessage = "Cannot use method '" + currentExpression.GetAccessExpressionQualifiedId() + "' as a variable or type."; return new GrapeEntity[] { null }; } if (lastLastParent != null) { if (lastMemberAccess != null) { GrapeClass c = null; if (lastMemberAccess is GrapeVariable) { c = (new List<GrapeEntity>(GetEntitiesForAccessExpression(config, ((GrapeVariable)lastMemberAccess).Type, lastMemberAccess, out errorMessage)))[0] as GrapeClass; } else if (lastMemberAccess is GrapeMethod) { c = (new List<GrapeEntity>(GetEntitiesForAccessExpression(config, ((GrapeMethod)lastMemberAccess).ReturnType, lastMemberAccess, out errorMessage)))[0] as GrapeClass; } if (c != null) { lastLastParent = c; shouldBeStatic = false; staticnessMatters = true; } lastMemberAccess = null; } else if (lastLastParent is GrapeClass) { shouldBeStatic = !lastClassAccessWasThisOrBaseAccess && !(lastParent is GrapeClass); staticnessMatters = true; } else if (lastLastParent is GrapeField) { GrapeModifier.GrapeModifierType variableModifiers = ((GrapeField)lastLastParent).Modifiers; shouldBeStatic = variableModifiers.Contains(GrapeModifier.GrapeModifierType.Static); lastMemberAccess = lastLastParent as GrapeField; staticnessMatters = true; } else if (lastLastParent is GrapeVariable) { shouldBeStatic = false; staticnessMatters = true; lastMemberAccess = lastLastParent as GrapeVariable; } else if (lastLastParent is GrapeMethod) { GrapeModifier.GrapeModifierType methodModifiers = ((GrapeMethod)lastLastParent).Modifiers; shouldBeStatic = methodModifiers.Contains(GrapeModifier.GrapeModifierType.Static); staticnessMatters = true; lastMemberAccess = lastLastParent as GrapeMethod; } } GrapeModifier.GrapeModifierType modifiers = lastParent.GetPotentialModifiersOfEntity(); if (modifiers != 0 && staticnessMatters) { if (shouldBeStatic && !modifiers.Contains(GrapeModifier.GrapeModifierType.Static)) { errorMessage = "Cannot access instance member when the context implies that a static member should be accessed. The expression is '" + identifierExpression.GetAccessExpressionQualifiedId() + "'."; return new GrapeEntity[] { null }; } else if (!shouldBeStatic && modifiers.Contains(GrapeModifier.GrapeModifierType.Static)) { errorMessage = "Cannot access static member when the context implies that an instance member should be accessed. The expression is '" + identifierExpression.GetAccessExpressionQualifiedId() + "'."; return new GrapeEntity[] { null }; } } lastLastParent = lastParent; if (lastLastParent is GrapeVariable || lastLastParent is GrapeMethod) { lastMemberAccess = lastLastParent; } lastClassAccessWasThisOrBaseAccess = currentExpression.GetAccessExpressionQualifiedId() == "this" || currentExpression.GetAccessExpressionQualifiedId() == "base"; currentExpression = currentExpression.Next; } entity = lastParent; if (entity != null) { GrapeMethod method = entity as GrapeMethod; if (method != null && accessExpression is GrapeCallExpression && !accessExpressionValidator.ValidateMethodSignatureAndOverloads(((GrapeCallExpression)accessExpression), method, GrapeModifier.GrapeModifierType.Public, ref errorMessage)) { return new GrapeEntity[] { entity }; } GrapeAccessExpression memberExpressionWithNext = accessExpression.Next == null ? identifierExpression : accessExpression; if (memberExpressionWithNext.Next != null) { GrapeEntity newParent = null; if (entity is GrapeClass) { newParent = entity as GrapeClass; } else if (entity is GrapeMethod) { newParent = (new List<GrapeEntity>(GetEntitiesForAccessExpression(config, ((GrapeMethod)entity).ReturnType, parent, out errorMessage)))[0]; } else if (entity is GrapeVariable) { newParent = (new List<GrapeEntity>(GetEntitiesForAccessExpression(config, ((GrapeVariable)entity).Type, parent, out errorMessage)))[0]; } return GetEntitiesForAccessExpression(config, memberExpressionWithNext.Next, newParent, out errorMessage); } return new GrapeEntity[] { entity }; } } else if (accessExpression is GrapeMemberExpression) { GrapeEntity foundEntity = null; GrapeEntity lastParent = null; GrapeEntity lastEntity = null; GrapeEntity lastLastEntity = null; GrapeEntity lastMemberAccess = null; GrapeAccessExpression currentExpression = accessExpression; IEnumerable<GrapeEntity> members = null; IEnumerable<GrapeEntity> classes = null; bool lastClassAccessWasThisOrBaseAccess = false; bool shouldBeStatic = false; bool staticnessMatters = false; while (currentExpression != null) { string qualifiedId = currentExpression.GetAccessExpressionQualifiedId(); IList<GrapeEntity> currentMembers = new List<GrapeEntity>(GetMembersForExpression(config, qualifiedId, lastParent == null ? parent : lastParent)); IList<GrapeEntity> currentClasses = new List<GrapeEntity>(GetClassesForExpression(config, qualifiedId, lastParent == null ? parent : lastParent)); lastParent = currentClasses.Count() == 1 && currentClasses[0] != null ? currentClasses[0] : currentMembers.Count() > 0 ? currentMembers[0] is GrapeVariable ? astUtils.GetClassWithNameFromImportedPackagesInFile(config.Ast, GetTypeNameForTypeAccessExpression(config, ((GrapeVariable)currentMembers[0]).Type), parent.FileName) : currentMembers[0] is GrapeMethod ? astUtils.GetClassWithNameFromImportedPackagesInFile(config.Ast, GetTypeNameForTypeAccessExpression(config, ((GrapeMethod)currentMembers[0]).ReturnType), parent.FileName) : null : null; lastEntity = currentClasses.Count() == 1 && currentClasses[0] != null ? currentClasses[0] : currentMembers.Count() > 0 ? currentMembers[0] : null; if (lastParent == null) { members = null; classes = null; break; } if (lastEntity is GrapeMethod && !(currentExpression is GrapeCallExpression) && !(accessExpression is GrapeCallExpression) && !(parent is GrapeCallExpression) && detectMethodsUsedAsTypesOrVars) { errorMessage = "Cannot use method '" + qualifiedId + "' as a variable or type."; return new GrapeEntity[] { null }; } if (lastLastEntity != null) { if (lastMemberAccess != null) { GrapeClass c = null; if (lastMemberAccess is GrapeVariable) { c = (new List<GrapeEntity>(GetEntitiesForAccessExpression(config, ((GrapeVariable)lastMemberAccess).Type, lastMemberAccess, out errorMessage)))[0] as GrapeClass; } else if (lastMemberAccess is GrapeMethod) { c = (new List<GrapeEntity>(GetEntitiesForAccessExpression(config, ((GrapeMethod)lastMemberAccess).ReturnType, lastMemberAccess, out errorMessage)))[0] as GrapeClass; } if (c != null) { lastLastEntity = c; shouldBeStatic = false; staticnessMatters = true; } lastMemberAccess = null; } else if (lastLastEntity is GrapeClass) { shouldBeStatic = !lastClassAccessWasThisOrBaseAccess && !(lastEntity is GrapeClass); staticnessMatters = true; } else if (lastLastEntity is GrapeField) { GrapeModifier.GrapeModifierType variableModifiers = ((GrapeField)lastLastEntity).Modifiers; shouldBeStatic = variableModifiers.Contains(GrapeModifier.GrapeModifierType.Static); staticnessMatters = true; lastMemberAccess = lastLastEntity as GrapeField; } else if (lastLastEntity is GrapeVariable) { shouldBeStatic = false; staticnessMatters = true; lastMemberAccess = lastLastEntity as GrapeVariable; } else if (lastLastEntity is GrapeMethod) { GrapeModifier.GrapeModifierType methodModifiers = ((GrapeMethod)lastLastEntity).Modifiers; shouldBeStatic = methodModifiers.Contains(GrapeModifier.GrapeModifierType.Static); staticnessMatters = true; lastMemberAccess = lastLastEntity as GrapeMethod; } } GrapeModifier.GrapeModifierType modifiers = lastEntity.GetPotentialModifiersOfEntity(); if (modifiers != 0 && staticnessMatters) { if (shouldBeStatic && !modifiers.Contains(GrapeModifier.GrapeModifierType.Static)) { errorMessage = "Cannot access instance member when the context implies that a static member should be accessed. The expression is '" + accessExpression.GetAccessExpressionQualifiedId() + "'."; return new GrapeEntity[] { null }; } else if (!shouldBeStatic && modifiers.Contains(GrapeModifier.GrapeModifierType.Static)) { errorMessage = "Cannot access static member when the context implies that an instance member should be accessed. The expression is '" + accessExpression.GetAccessExpressionQualifiedId() + "'."; return new GrapeEntity[] { null }; } } lastLastEntity = lastEntity; if (lastLastEntity is GrapeVariable || lastLastEntity is GrapeMethod) { lastMemberAccess = lastLastEntity; } lastClassAccessWasThisOrBaseAccess = currentExpression.GetAccessExpressionQualifiedId() == "this" || currentExpression.GetAccessExpressionQualifiedId() == "base"; members = currentMembers; classes = currentClasses; currentExpression = currentExpression.Next; } foundEntity = lastParent; List<GrapeEntity> entities = new List<GrapeEntity>(); if (members != null) { entities.AddRange(members); if (classes != null && classes.Count() > 0) { List<GrapeEntity> membersToRemove = new List<GrapeEntity>(); foreach (GrapeClass c in classes) { if (c != null) { foreach (GrapeEntity member in members) { if (member is GrapeMethod && ((GrapeMethod)member).Name == c.Name) { membersToRemove.Add(member); } } } } membersToRemove.ForEach(m => entities.Remove(m)); } } if (classes != null) { entities.AddRange(classes); } if (entities.Count == 0) { if (errorMessage == "") { errorMessage = "Cannot find variable, field, type or method with name '" + memberExpressionQualifiedId + "'."; } return new GrapeEntity[] { null }; } GrapeMethod method = null; foreach (GrapeEntity entity in entities) { if (entity is GrapeMethod) { method = entity as GrapeMethod; break; } } if (method != null) { GrapeAccessExpression currentMemberExpression = accessExpression; GrapeCallExpression callExpression = null; while (currentMemberExpression != null) { if (currentMemberExpression is GrapeCallExpression && ((GrapeCallExpression)currentMemberExpression).GetAccessExpressionQualifiedId() == method.Name) { callExpression = currentMemberExpression as GrapeCallExpression; } currentMemberExpression = currentMemberExpression.Next; } if (callExpression != null && !accessExpressionValidator.ValidateMethodSignatureAndOverloads(callExpression, method, GrapeModifier.GrapeModifierType.Public, ref errorMessage)) { return entities; } } return entities; } return new GrapeEntity[] { null }; }
public IEnumerable<GrapeEntity> GetEntitiesForAccessExpression(GrapeCodeGeneratorConfiguration config, GrapeAccessExpression accessExpression, GrapeEntity parent, out string errorMessage) { return GetEntitiesForAccessExpression(config, accessExpression, parent, out errorMessage, true); }