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;
        }
예제 #3
0
        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;
        }