示例#1
0
        private IAnalysisResult GetResolvedType(Genero4glAst ast, out string errMsg)
        {
            errMsg = null;
            IAnalysisResult result = null;
            // if it's not a base type, look up the type
            IGeneroProject dummyProj;
            IProjectEntry  dummyProjEntry;
            bool           isDeferred;
            var            res = Genero4glAst.GetValueByIndex(_typeNameString, StartIndex, ast as Genero4glAst, out dummyProj, out dummyProjEntry, out isDeferred, FunctionProviderSearchMode.NoSearch, false, true, false, false);

            if (res == null)
            {
                errMsg = string.Format("Type {0} not found.", _typeNameString);
            }
            else
            {
                if (res is GeneroPackageClass ||
                    res is TypeDefinitionNode)
                {
                    result = res;
                }
                else
                {
                    errMsg = string.Format("Invalid type {0} found.", _typeNameString);
                }
            }
            return(result);
        }
示例#2
0
        public bool HasChildFunctions(Genero4glAst ast)
        {
            if (Children.Count == 1)
            {
                var node = Children[Children.Keys[0]];
                if (node is ArrayTypeReference)
                {
                    return(true);
                }
                else if (node is RecordDefinitionNode)
                {
                    return((node as RecordDefinitionNode).HasChildFunctions(ast));
                }
            }
            else
            {
                if (!string.IsNullOrWhiteSpace(_typeNameString))
                {
                    if (_typeNameString.Equals("string", StringComparison.OrdinalIgnoreCase))
                    {
                        return(true);
                    }
                    else
                    {
                        // try to determine if the _typeNameString is a user defined type
                        IAnalysisResult udt = ast.TryGetUserDefinedType(_typeNameString, LocationIndex);
                        if (udt != null)
                        {
                            return(udt.HasChildFunctions(ast));
                        }

                        // check for package class
                        IGeneroProject dummyProj;
                        IProjectEntry  projEntry;
                        bool           dummyDef;
                        udt = ast.GetValueByIndex(_typeNameString, LocationIndex, ast._functionProvider, ast._databaseProvider, ast._programFileProvider, false, out dummyDef, out dummyProj, out projEntry);
                        if (udt != null)
                        {
                            return(udt.HasChildFunctions(ast));
                        }
                    }
                }
            }
            return(false);
        }
示例#3
0
 public override void CheckForErrors(GeneroAst ast, Action <string, int, int> errorFunc, Dictionary <string, List <int> > deferredFunctionSearches, FunctionProviderSearchMode searchInFunctionProvider = FunctionProviderSearchMode.NoSearch, bool isFunctionCallOrDefinition = false)
 {
     if (Children.Count > 0)
     {
         base.CheckForErrors(ast, errorFunc, deferredFunctionSearches, searchInFunctionProvider, isFunctionCallOrDefinition);
     }
     else if (!string.IsNullOrWhiteSpace(DatabaseName) ||
              !string.IsNullOrWhiteSpace(TableName) ||
              !string.IsNullOrWhiteSpace(ColumnName))
     {
         // TODO: do deferred checking of these
     }
     else if (_typeNameString != null && !_isConstrainedType)
     {
         // see if the _typeNameString is a base type
         var tok = Tokens.GetToken(_typeNameString);
         if (tok == null || !Genero4glAst.BuiltinTypes.Contains(tok.Kind))
         {
             // if it's not a base type, look up the type
             IGeneroProject dummyProj;
             IProjectEntry  dummyProjEntry;
             bool           isDeferred;
             var            res = Genero4glAst.GetValueByIndex(_typeNameString, StartIndex, ast as Genero4glAst, out dummyProj, out dummyProjEntry, out isDeferred, FunctionProviderSearchMode.NoSearch, false, true, false, false);
             if (res == null)
             {
                 errorFunc(string.Format("Type {0} not found.", _typeNameString), StartIndex, EndIndex);
             }
             else
             {
                 if (res is GeneroPackageClass ||
                     res is TypeDefinitionNode)
                 {
                     ResolvedType = res;
                 }
                 else
                 {
                     errorFunc(string.Format("Invalid type {0} found.", _typeNameString), StartIndex, EndIndex);
                 }
             }
         }
     }
 }
示例#4
0
        public IEnumerable <MemberResult> GetMembers(Genero4glAst ast, MemberType memberType, bool function)
        {
            bool dummyDef;
            List <MemberResult> members = new List <MemberResult>();

            if (Children.Count == 1)
            {
                // we have an array type or a record type definition
                var node = Children[Children.Keys[0]];
                if (node is ArrayTypeReference)
                {
                    return((node as ArrayTypeReference).GetMembersInternal(ast, memberType, function));
                }
                else if (node is RecordDefinitionNode)
                {
                    return((node as RecordDefinitionNode).GetMembers(ast, memberType, function));
                }
            }
            else
            {
                if (!string.IsNullOrWhiteSpace(TableName))
                {
                    // TODO: return the table's columns
                }
                else if (_typeNameString.Equals("string", StringComparison.OrdinalIgnoreCase))
                {
                    return(Genero4glAst.StringFunctions.Values.Select(x => new MemberResult(x.Name, x, GeneroMemberType.Method, ast)));
                }
                else if (_typeNameString.Equals("text", StringComparison.OrdinalIgnoreCase))
                {
                    return(Genero4glAst.TextFunctions.Values.Select(x => new MemberResult(x.Name, x, GeneroMemberType.Method, ast)));
                }
                else if (_typeNameString.Equals("byte", StringComparison.OrdinalIgnoreCase))
                {
                    return(Genero4glAst.ByteFunctions.Values.Select(x => new MemberResult(x.Name, x, GeneroMemberType.Method, ast)));
                }
                else
                {
                    // try to determine if the _typeNameString is a user defined type (or package class), in which case we need to call its GetMembers function
                    IAnalysisResult udt = ast.TryGetUserDefinedType(_typeNameString, LocationIndex);
                    if (udt != null)
                    {
                        return(udt.GetMembers(ast, memberType, function));
                    }

                    foreach (var includedFile in ast.ProjectEntry.GetIncludedFiles())
                    {
                        if (includedFile.Analysis != null)
                        {
                            IGeneroProject dummyProj;
                            IProjectEntry  dummyProjEntry;
                            var            res = includedFile.Analysis.GetValueByIndex(_typeNameString, 1, null, null, null, false, out dummyDef, out dummyProj, out dummyProjEntry);
                            if (res != null)
                            {
                                return(res.GetMembers(ast, memberType, function));
                            }
                        }
                    }

                    if (ast.ProjectEntry.ParentProject.ReferencedProjects.Count > 0)
                    {
                        foreach (var refProj in ast.ProjectEntry.ParentProject.ReferencedProjects.Values)
                        {
                            if (refProj is GeneroProject)
                            {
                                IProjectEntry dummyProj;
                                udt = (refProj as GeneroProject).GetMemberOfType(_typeNameString, ast, false, true, false, false, out dummyProj);
                                if (udt != null)
                                {
                                    return(udt.GetMembers(ast, memberType, function));
                                }
                            }
                        }
                    }

                    // check for package class
                    IGeneroProject dummyProject;
                    IProjectEntry  projEntry;
                    udt = ast.GetValueByIndex(_typeNameString, LocationIndex, ast._functionProvider, ast._databaseProvider, ast._programFileProvider, false, out dummyDef, out dummyProject, out projEntry);
                    if (udt != null)
                    {
                        return(udt.GetMembers(ast, memberType, function));
                    }
                }
            }
            return(members);
        }
示例#5
0
        public override void CheckForErrors(GeneroAst ast, Action <string, int, int> errorFunc,
                                            Dictionary <string, List <int> > deferredFunctionSearches,
                                            FunctionProviderSearchMode searchInFunctionProvider = FunctionProviderSearchMode.NoSearch, bool isFunctionCallOrDefinition = false)
        {
            // 1) Check parameters for errors
            //      - undefined identifier
            //      - record without .*
            if (_skipValidationFunctionNames.Contains(Function.Name))
            {
                return;
            }

            // Check for the function name
            if (Function != null)
            {
                Function.CheckForErrors(ast, errorFunc, deferredFunctionSearches, FunctionProviderSearchMode.Deferred, true);
            }

            if (Parameters != null)
            {
                if (Function != null &&
                    Function.ResolvedResult != null &&
                    (Function.ResolvedResult is IFunctionResult))
                {
                    // TODO: if a parameter is a record, then the number of required input arguments increases by the number of fields in that record.
                    int            totalRequiredParams = 0;
                    IGeneroProject proj;
                    IProjectEntry  projEntry;
                    bool           isDeferred;
                    foreach (var param in (Function.ResolvedResult as IFunctionResult).Parameters)
                    {
                        TypeReference typeRef  = null;
                        var           typeName = param.Type;
                        int           index    = typeName.IndexOf("record", StringComparison.OrdinalIgnoreCase);
                        // TODO: need to look into how importable projects populate their parameter result types
                        if (index == 0 && (typeName.Length == 6 || char.IsWhiteSpace(typeName[6])))
                        {
                            if (Function.ResolvedResult is AstNode4gl &&
                                (Function.ResolvedResult as AstNode4gl).StartIndex >= 0)
                            {
                                var useAst = ast as Genero4glAst;
                                if ((Function.ResolvedResult as AstNode4gl).SyntaxTree != null &&
                                    (Function.ResolvedResult as AstNode4gl).SyntaxTree != ast)
                                {
                                    useAst = (Function.ResolvedResult as AstNode4gl).SyntaxTree as Genero4glAst;
                                }
                                // need to retrieve the variable and then get its type
                                var resVar = Genero4glAst.GetValueByIndex(param.Name, (Function.ResolvedResult as AstNode4gl).StartIndex, useAst, out proj, out projEntry, out isDeferred);
                                if (resVar != null &&
                                    resVar is VariableDef)
                                {
                                    typeRef = ((resVar as VariableDef).ResolvedType as TypeReference) ?? (resVar as VariableDef).Type;
                                }
                            }
                        }
                        else
                        {
                            // TODO: eventually, this needs to handle system types
                            var resType = Genero4glAst.GetValueByIndex(typeName, StartIndex, ast as Genero4glAst, out proj, out projEntry, out isDeferred);
                            if (resType != null &&
                                resType is TypeDefinitionNode &&
                                (resType as TypeDefinitionNode).TypeRef != null)
                            {
                                typeRef = (resType as TypeDefinitionNode).TypeRef;
                            }
                        }

                        if (typeRef != null && typeRef.IsRecord && (typeRef.Children[typeRef.Children.Keys[0]] is RecordDefinitionNode))
                        {
                            int recFieldCount = (typeRef.Children[typeRef.Children.Keys[0]] as RecordDefinitionNode).GetMembers(ast as Genero4glAst, Analysis.MemberType.All, false).Count();
                            if (recFieldCount > 0)
                            {
                                totalRequiredParams += recFieldCount;
                            }
                            else
                            {
                                totalRequiredParams++;
                            }
                        }
                        else
                        {
                            totalRequiredParams++;
                        }
                    }

                    int totalParameters = 0;
                    foreach (var param in Parameters)
                    {
                        // The genero compiler does not do error checking of types, so I guess anything goes...
                        // That makes things easier...
                        if (param is FglNameExpression)
                        {
                            var nameParam = param as FglNameExpression;
                            nameParam.CheckForErrors(ast, errorFunc, deferredFunctionSearches, FunctionProviderSearchMode.Deferred);
                            if (nameParam.ResolvedResult != null)
                            {
                                if (nameParam.ResolvedResult is TypeDefinitionNode) // Check for any invalid parameters TODO: others
                                {
                                    errorFunc("Invalid parameter found.", param.StartIndex, param.EndIndex);
                                }
                                else
                                {
                                    TypeReference typeRef = null;
                                    if (nameParam.ResolvedResult is VariableDef)
                                    {
                                        if ((nameParam.ResolvedResult as VariableDef).ResolvedType != null &&
                                            (nameParam.ResolvedResult as VariableDef).ResolvedType is TypeDefinitionNode)
                                        {
                                            var typeDef = (nameParam.ResolvedResult as VariableDef).ResolvedType as TypeDefinitionNode;
                                            if (typeDef?.TypeRef != null)
                                            {
                                                typeRef = typeDef.TypeRef;
                                            }
                                        }
                                        else
                                        {
                                            typeRef = (nameParam.ResolvedResult as VariableDef).Type;
                                        }
                                    }

                                    if (typeRef != null && typeRef.IsRecord && (typeRef.Children[typeRef.Children.Keys[0]] is RecordDefinitionNode))
                                    {
                                        if ((nameParam.ResolvedResult as VariableDef).Type.IsArray)
                                        {
                                            if ((param as FglNameExpression).Name.EndsWith(".*"))
                                            {
                                                // need to get the number of fields in the record, as they count toward our passed parameter total
                                                int recFieldCount = ((RecordDefinitionNode)typeRef.Children[typeRef.Children.Keys[0]]).GetMembers(ast as Genero4glAst, Analysis.MemberType.All, false).Count();
                                                if (recFieldCount > 0)
                                                {
                                                    totalParameters += (recFieldCount - 1); // minus 1 so we can do the increment below
                                                }
                                            }
                                        }
                                        else
                                        {
                                            if (!(param as FglNameExpression).Name.EndsWith(".*") &&
                                                !_allowedNonStarRecordParamFunctions.Contains(Function.Name))
                                            {
                                                errorFunc("Records must be specified with a '.*' ending when passed as a function parameter.", param.StartIndex, param.EndIndex);
                                            }
                                            else
                                            {
                                                if (!_allowedNonStarRecordParamFunctions.Contains(Function.Name))
                                                {
                                                    // need to get the number of fields in the record, as they count toward our passed parameter total
                                                    int recFieldCount = ((RecordDefinitionNode)typeRef.Children[typeRef.Children.Keys[0]]).GetMembers(ast as Genero4glAst, Analysis.MemberType.All, false).Count();
                                                    if (recFieldCount > 0)
                                                    {
                                                        totalParameters += (recFieldCount - 1); // minus 1 so we can do the increment below
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        param.CheckForErrors(ast, errorFunc, deferredFunctionSearches);
                        totalParameters++;
                    }

                    // need to determine if any of the passed in parameters are records, and if so, adjust the passed count
                    if (totalParameters != totalRequiredParams)
                    {
                        errorFunc(string.Format("Unexpected number of parameters ({0}) found, expected {1} variables.", totalParameters, totalRequiredParams), StartIndex, EndIndex);
                    }
                }
            }

            // TODO: should we do something with the anything parameters

            base.CheckForErrors(ast, errorFunc, deferredFunctionSearches);
        }