public bool ValidateMethodSignatureAndOverloads(GrapeCallExpression callExpression, GrapeMethod method, GrapeModifier.GrapeModifierType modifiers, ref string errorMessage) { errorMessage = ""; List<GrapeMethod> methods = new List<GrapeMethod>(); methods.AddRange(astUtils.GetMethodsWithNameFromImportedPackagesInFile(Config, method.Name, method.FileName, method.GetLogicalParentOfEntityType<GrapeClass>())); List<GrapeMethod> methodsWithSignature = typeCheckingUtils.GetMethodsWithSignature(Config, methods, modifiers, method.Name, method.ReturnType, new List<GrapeExpression>(callExpression.Parameters), ref errorMessage); if (errorMessage != "") { errorSink.AddError(new GrapeErrorSink.Error { Description = errorMessage, FileName = callExpression.FileName, Entity = callExpression }); if (!Config.ContinueOnError) { return false; } } if (methodsWithSignature.Count > 1) { errorMessage = "Multiple functions with signature '" + typeCheckingUtils.GetMethodSignatureString(Config, method.Name, method.ReturnType, new List<GrapeExpression>(callExpression.Parameters)) + "' found."; errorSink.AddError(new GrapeErrorSink.Error { Description = errorMessage, FileName = callExpression.FileName, Entity = callExpression }); if (!Config.ContinueOnError) { return false; } } return true; }
public bool ValidateNode(object obj) { if (Config.OutputErrors) { GrapeInitStatement s = obj as GrapeInitStatement; if (s != null) { if (s.Type == GrapeInitStatement.GrapeInitStatementType.Base) { GrapeClass c = s.GetLogicalParentOfEntityType<GrapeClass>(); if (c.Inherits == null) { errorSink.AddError(new GrapeErrorSink.Error { Description = "Cannot access base constructor when the current class has no base class.", FileName = s.FileName, Entity = s }); if (!Config.ContinueOnError) { return false; } } GrapeEntity inheritingEntity = astUtils.GetClassWithNameFromImportedPackagesInFile(Config.Ast, typeCheckingUtils.GetTypeNameForTypeAccessExpression(Config, c.Inherits), c.FileName); if (inheritingEntity != null && inheritingEntity is GrapeClass) { string errorMessage = ""; GrapeClass inheritingClass = inheritingEntity as GrapeClass; GrapeMethod method = null; foreach (GrapeEntity entity in inheritingClass.GetChildren()) { if (entity != null && entity is GrapeMethod && ((GrapeMethod)entity).Name == inheritingClass.Name && ((GrapeMethod)entity).Type == GrapeMethod.GrapeMethodType.Constructor) { method = entity as GrapeMethod; break; } } if (method == null) { GrapeList<GrapeModifier> methodModifiers = new GrapeList<GrapeModifier>(new GrapePublicModifier()); GrapeList<GrapeIdentifier> nameParts = new GrapeList<GrapeIdentifier>(new GrapeIdentifier(inheritingClass.Name)); method = new GrapeMethod(methodModifiers, new GrapeSimpleType(nameParts), new GrapeIdentifier(inheritingClass.Name), new GrapeList<GrapeParameter>(), new GrapeList<GrapeStatement>()); method.Parent = inheritingClass; } GrapeModifier.GrapeModifierType modifiers = c.GetAppropriateModifiersForEntityAccess(Config, method); bool valid = accessExpressionValidator.ValidateMethodSignatureAndOverloads(GrapeCallExpression.Create(new GrapeIdentifier(inheritingClass.Name), GrapeList<GrapeExpression>.FromEnumerable(s.Parameters), null), method, modifiers, ref errorMessage); if (!valid) { errorSink.AddError(new GrapeErrorSink.Error { Description = errorMessage, FileName = s.FileName, Entity = s }); if (!Config.ContinueOnError) { return false; } } } else { errorSink.AddError(new GrapeErrorSink.Error { Description = "Cannot find base class '" + typeCheckingUtils.GetTypeNameForTypeAccessExpression(Config, c.Inherits) + "'.", FileName = s.FileName, Entity = s }); if (!Config.ContinueOnError) { return false; } } } else if (s.Type == GrapeInitStatement.GrapeInitStatementType.This) { GrapeClass c = s.GetLogicalParentOfEntityType<GrapeClass>(); GrapeMethod method = null; foreach (GrapeEntity entity in c.GetChildren()) { if (entity != null && entity is GrapeMethod && ((GrapeMethod)entity).Name == c.Name && ((GrapeMethod)entity).Type == GrapeMethod.GrapeMethodType.Constructor) { method = entity as GrapeMethod; break; } } if (method == null) { GrapeList<GrapeModifier> methodModifiers = new GrapeList<GrapeModifier>(new GrapePublicModifier()); GrapeList<GrapeIdentifier> nameParts = new GrapeList<GrapeIdentifier>(new GrapeIdentifier(c.Name)); method = new GrapeMethod(methodModifiers, new GrapeSimpleType(nameParts), new GrapeIdentifier(c.Name), new GrapeList<GrapeParameter>(), new GrapeList<GrapeStatement>()); method.Parent = c; } string errorMessage = ""; GrapeModifier.GrapeModifierType modifiers = c.GetAppropriateModifiersForEntityAccess(Config, method); bool valid = accessExpressionValidator.ValidateMethodSignatureAndOverloads(GrapeCallExpression.Create(new GrapeIdentifier(c.Name), GrapeList<GrapeExpression>.FromEnumerable(s.Parameters), null), method, modifiers, ref errorMessage); if (!valid) { errorSink.AddError(new GrapeErrorSink.Error { Description = errorMessage, FileName = s.FileName, Entity = s }); if (!Config.ContinueOnError) { return false; } } } else { errorSink.AddError(new GrapeErrorSink.Error { Description = "Cannot find initialization type.", FileName = s.FileName, Entity = s }); if (!Config.ContinueOnError) { return false; } } } } return true; }
private bool ValidateModifiers(GrapeMethod m, out string errorMessage) { errorMessage = ""; bool isStatic = m.Modifiers.Contains(GrapeModifier.GrapeModifierType.Static); bool isAbstract = m.Modifiers.Contains(GrapeModifier.GrapeModifierType.Abstract); bool isSealed = m.Modifiers.Contains(GrapeModifier.GrapeModifierType.Sealed); bool isOverride = m.Modifiers.Contains(GrapeModifier.GrapeModifierType.Override); if (m.Modifiers.HasInvalidAccessModifiers()) { errorMessage = "Invalid access modifiers found."; return false; } if (isStatic) { if (isAbstract || isSealed || isOverride) { errorMessage = "A function cannot be declared static and abstract, sealed or override at the same time."; return false; } } else if (isAbstract && isSealed) { errorMessage = "A function cannot be declared abstract and sealed at the same time."; return false; } else if (isAbstract && isOverride) { errorMessage = "A function cannot be declared abstract and override at the same time."; return false; } return true; }