internal IAnalysisResult TryGetUserDefinedType(string typeName, int index)
        {
            // do a binary search to determine what node we're in
            IAnalysisResult type = null;

            _body.SetNamespace(null);
            // TODO: need to handle multiple results of the same name
            AstNode containingNode = GetContainingNode(_body, index);

            if (containingNode != null)
            {
                if (containingNode is IFunctionResult)
                {
                    if ((containingNode as IFunctionResult).Types.TryGetValue(typeName, out type))
                    {
                        return(type);
                    }
                }

                if (_body is IModuleResult)
                {
                    if ((_body as IModuleResult).Types.TryGetValue(typeName, out type) ||
                        (_body as IModuleResult).GlobalTypes.TryGetValue(typeName, out type))
                    {
                        return(type);
                    }
                }
            }

            // TODO: this could probably be done more efficiently by having each GeneroAst load globals and functions into
            // dictionaries stored on the IGeneroProject, instead of in each project entry.
            // However, this does required more upkeep when changes occur. Will look into it...
            if (_projEntry != null && _projEntry is IGeneroProjectEntry)
            {
                IGeneroProjectEntry genProj = _projEntry as IGeneroProjectEntry;
                if (genProj.ParentProject != null)
                {
                    foreach (var projEntry in genProj.ParentProject.ProjectEntries.Where(x => x.Value != genProj))
                    {
                        if (projEntry.Value.Analysis != null &&
                            projEntry.Value.Analysis.Body != null)
                        {
                            projEntry.Value.Analysis.Body.SetNamespace(null);
                            IModuleResult modRes = projEntry.Value.Analysis.Body as IModuleResult;
                            if (modRes != null)
                            {
                                // check global types

                                if (modRes.GlobalTypes.TryGetValue(typeName, out type))
                                {
                                    return(type);
                                }
                            }
                        }
                    }
                }
            }

            return(type);
        }
Beispiel #2
0
 public DropDownBarClient(IWpfTextView textView, IGeneroProjectEntry pythonProjectEntry)
 {
     _projectEntry = pythonProjectEntry;
     _projectEntry.OnNewParseTree += ParserOnNewParseTree;
     _textView        = textView;
     _topLevelEntries = _nestedEntries = EmptyEntries;
     _dispatcher      = Dispatcher.CurrentDispatcher;
     _textView.Caret.PositionChanged += CaretPositionChanged;
 }
Beispiel #3
0
 internal void UpdateProjectEntry(IProjectEntry newEntry)
 {
     if (newEntry is IGeneroProjectEntry)
     {
         _projectEntry.OnNewParseTree -= ParserOnNewParseTree;
         _projectEntry = (IGeneroProjectEntry)newEntry;
         _projectEntry.OnNewParseTree += ParserOnNewParseTree;
     }
 }
Beispiel #4
0
        internal static bool TryGetAnalysis(this ITextBuffer buffer, out IGeneroProjectEntry analysis)
        {
            IProjectEntry entry;

            if (buffer.TryGetAnalysis(out entry) && (analysis = entry as IGeneroProjectEntry) != null)
            {
                return(true);
            }
            analysis = null;
            return(false);
        }
Beispiel #5
0
        public IGeneroProject AddImportedModule(string path, IGeneroProjectEntry importer)
        {
            IGeneroProject refProj = null;

            if (!ReferencedProjects.TryGetValue(path, out refProj))
            {
                // need to tell the genero project analyzer to add a directory to the project
                refProj = VSGeneroPackage.Instance.DefaultAnalyzer.AddImportedProject(path, importer);
                if (refProj == null)
                {
                    // TODO: need to report that the project is invalid?
                }
                else
                {
                    ReferencedProjects.AddOrUpdate(path, refProj, (x, y) => y);
                }
            }
            return(refProj);
        }
Beispiel #6
0
        /// <summary>
        /// Parses the specified file on disk.
        /// </summary>
        /// <param name="filename"></param>
        public void EnqueueFile(IProjectEntry projEntry, string filename)
        {
            var severity = Severity.Ignore;

            EnqueWorker(() =>
            {
                for (int i = 0; i < 10; i++)
                {
                    try
                    {
                        if (!File.Exists(filename))
                        {
                            break;
                        }
                        using (var reader = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete))
                        {
                            _parser.ParseFile(projEntry, filename, reader, severity);
                            return;
                        }
                    }
                    catch (IOException)
                    {
                        // file being copied, try again...
                        Thread.Sleep(100);
                    }
                    catch (UnauthorizedAccessException)
                    {
                        // file is inaccessible, try again...
                        Thread.Sleep(100);
                    }
                }

                IGeneroProjectEntry gEntry = projEntry as IGeneroProjectEntry;
                IAnalysisCookie cookie     = null;
                Genero4glAst node          = null;
                if (gEntry != null)
                {
                    // failed to parse, keep the UpdateTree calls balanced
                    gEntry.UpdateTree(node, cookie);
                }
            });
        }
        public override IEnumerable <MemberResult> GetDefinedMembers(int index, AstMemberType memberType, bool isMemberAccess = false)
        {
            HashSet <MemberResult> members = new HashSet <MemberResult>();

            HashSet <GeneroPackage> includedPackages = new HashSet <GeneroPackage>();

            if (memberType.HasFlag(AstMemberType.SystemTypes) && !isMemberAccess)
            {
                // Built-in types
                members.AddRange(BuiltinTypes.Select(x => new MemberResult(Tokens.TokenKinds[x], GeneroMemberType.Keyword, this)));

                foreach (var package in Packages.Values.Where(x => _importedPackages[x.Name] && x.ContainsInstanceMembers &&
                                                              (this.LanguageVersion >= x.MinimumLanguageVersion && this.LanguageVersion <= x.MaximumLanguageVersion)))
                {
                    members.Add(new MemberResult(package.Name, GeneroMemberType.Module, this));
                    includedPackages.Add(package);
                }
            }
            if (memberType.HasFlag(AstMemberType.Constants) && !isMemberAccess)
            {
                members.AddRange(SystemConstants.Where(x => this.LanguageVersion >= x.Value.MinimumLanguageVersion && this.LanguageVersion <= x.Value.MaximumLanguageVersion)
                                 .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Keyword, this)));
                members.AddRange(SystemMacros.Where(x => this.LanguageVersion >= x.Value.MinimumLanguageVersion && this.LanguageVersion <= x.Value.MaximumLanguageVersion)
                                 .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Constant, this)));
            }
            if (memberType.HasFlag(AstMemberType.Variables) && !isMemberAccess)
            {
                members.AddRange(SystemVariables.Where(x => this.LanguageVersion >= x.Value.MinimumLanguageVersion && this.LanguageVersion <= x.Value.MaximumLanguageVersion)
                                 .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Keyword, this)));
            }
            if (memberType.HasFlag(AstMemberType.Functions) && !isMemberAccess)
            {
                members.AddRange(SystemFunctions.Where(x => this.LanguageVersion >= x.Value.MinimumLanguageVersion && this.LanguageVersion <= x.Value.MaximumLanguageVersion)
                                 .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Function, this)));
                foreach (var package in Packages.Values.Where(x => _importedPackages[x.Name] && x.ContainsStaticClasses &&
                                                              (this.LanguageVersion >= x.MinimumLanguageVersion && this.LanguageVersion <= x.MaximumLanguageVersion)))
                {
                    if (!includedPackages.Contains(package))
                    {
                        members.Add(new MemberResult(package.Name, GeneroMemberType.Module, this));
                    }
                }
            }

            // TODO: need to handle multiple results of the same name
            AstNode containingNode = GetContainingNode(_body, index);

            if (containingNode != null)
            {
                if (containingNode is IFunctionResult)
                {
                    if (memberType.HasFlag(AstMemberType.Variables))
                    {
                        members.AddRange((containingNode as IFunctionResult).Variables.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, this)));
                        foreach (var varList in (containingNode as IFunctionResult).LimitedScopeVariables)
                        {
                            foreach (var item in varList.Value)
                            {
                                if (item.Item2.IsInSpan(index))
                                {
                                    members.Add(new MemberResult(item.Item1.Name, item.Item1, GeneroMemberType.Instance, this));
                                    break;
                                }
                            }
                        }
                    }
                    if (memberType.HasFlag(AstMemberType.SystemTypes))
                    {
                        members.AddRange((containingNode as IFunctionResult).Types.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Class, this)));
                    }
                    if (memberType.HasFlag(AstMemberType.Constants))
                    {
                        members.AddRange((containingNode as IFunctionResult).Constants.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Constant, this)));
                    }
                    if (memberType.HasFlag(AstMemberType.Functions))
                    {
                        foreach (var res in (containingNode as IFunctionResult).Variables /*.Where(x => x.Value.HasChildFunctions(this))
                                                                                           */.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, this)))
                        {
                            if (!members.Contains(res))
                            {
                                members.Add(res);
                            }
                        }

                        foreach (var varList in (containingNode as IFunctionResult).LimitedScopeVariables)
                        {
                            foreach (var item in varList.Value)
                            {
                                if (item.Item2.IsInSpan(index))
                                {
                                    members.Add(new MemberResult(item.Item1.Name, item.Item1, GeneroMemberType.Instance, this));
                                    break;
                                }
                            }
                        }
                    }
                }

                if (_body is IModuleResult)
                {
                    // check for module vars, types, and constants (and globals defined in this module)
                    if (memberType.HasFlag(AstMemberType.Variables))
                    {
                        members.AddRange((_body as IModuleResult).Variables.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, this)));
                        members.AddRange((_body as IModuleResult).GlobalVariables.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, this)));
                    }
                    if (memberType.HasFlag(AstMemberType.UserDefinedTypes))
                    {
                        members.AddRange((_body as IModuleResult).Types.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Class, this)));
                        members.AddRange((_body as IModuleResult).GlobalTypes.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Class, this)));
                    }
                    if (memberType.HasFlag(AstMemberType.Constants))
                    {
                        members.AddRange((_body as IModuleResult).Constants.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Constant, this)));
                        members.AddRange((_body as IModuleResult).GlobalConstants.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Constant, this)));
                    }
                    if (memberType.HasFlag(AstMemberType.Dialogs))
                    {
                        members.AddRange((_body as IModuleResult).Functions.Where(x => x.Value is DeclarativeDialogBlock)
                                         .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Dialog, this)));
                        members.AddRange((_body as IModuleResult).FglImports.Select(x => new MemberResult(x, GeneroMemberType.Module, this)));
                    }
                    if (memberType.HasFlag(AstMemberType.Reports))
                    {
                        members.AddRange((_body as IModuleResult).Functions.Where(x => x.Value is ReportBlockNode)
                                         .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Report, this)));
                    }
                    if (memberType.HasFlag(AstMemberType.Functions))
                    {
                        members.AddRange((_body as IModuleResult).Functions
                                         .Where(x => !(x.Value is ReportBlockNode) && !(x.Value is DeclarativeDialogBlock))
                                         .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Method, this)));
                        foreach (var res in (_body as IModuleResult).Variables /*.Where(x => x.Value.HasChildFunctions(this))
                                                                                */.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, this)))
                        {
                            if (!members.Contains(res))
                            {
                                members.Add(res);
                            }
                        }
                        foreach (var res in (_body as IModuleResult).GlobalVariables /*.Where(x => x.Value.HasChildFunctions(this))
                                                                                      */.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, this)))
                        {
                            if (!members.Contains(res))
                            {
                                members.Add(res);
                            }
                        }
                    }

                    // Tables and cursors are module specific, and cannot be accessed via fgl import
                    if (memberType.HasFlag(AstMemberType.DeclaredCursors) ||
                        memberType.HasFlag(AstMemberType.PreparedCursors) ||
                        memberType.HasFlag(AstMemberType.Tables))
                    {
                        if (memberType.HasFlag(AstMemberType.DeclaredCursors))
                        {
                            members.AddRange((_body as IModuleResult).Cursors.Where(x => x.Value is DeclareStatement).Select(x => new MemberResult(x.Value.Name, x.Value, GeneroMemberType.Cursor, this)));
                        }
                        if (memberType.HasFlag(AstMemberType.PreparedCursors))
                        {
                            members.AddRange((_body as IModuleResult).Cursors.Where(x => x.Value is PrepareStatement).Select(x => new MemberResult(x.Value.Name, x.Value, GeneroMemberType.Cursor, this)));
                        }
                        if (memberType.HasFlag(AstMemberType.Tables))
                        {
                            members.AddRange((_body as IModuleResult).Tables.Select(x => new MemberResult(x.Value.Name, x.Value, GeneroMemberType.DbTable, this)));
                        }
                    }
                    else
                    {
                        members.AddRange((_body as IModuleResult).FglImports.Select(x => new MemberResult(x, GeneroMemberType.Module, this)));
                    }
                }
            }

            // TODO: this could probably be done more efficiently by having each GeneroAst load globals and functions into
            // dictionaries stored on the IGeneroProject, instead of in each project entry.
            // However, this does required more upkeep when changes occur. Will look into it...
            if (_projEntry != null && _projEntry is IGeneroProjectEntry)
            {
                IGeneroProjectEntry genProj = _projEntry as IGeneroProjectEntry;
                if (genProj.ParentProject != null &&
                    !genProj.FilePath.ToLower().EndsWith(".inc"))
                {
                    foreach (var projEntry in genProj.ParentProject.ProjectEntries.Where(x => x.Value != genProj))
                    {
                        if (projEntry.Value.Analysis != null &&
                            projEntry.Value.Analysis.Body != null)
                        {
                            projEntry.Value.Analysis.Body.SetNamespace(null);
                            IModuleResult modRes = projEntry.Value.Analysis.Body as IModuleResult;
                            if (modRes != null)
                            {
                                // check global types
                                // TODO: need to add an option to enable/disable legacy linking (to not reference other modules' non-public members
                                if (memberType.HasFlag(AstMemberType.Variables))
                                {
                                    members.AddRange(modRes.GlobalVariables.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, this)));
                                    members.AddRange(modRes.Variables.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, this)));
                                }
                                if (memberType.HasFlag(AstMemberType.UserDefinedTypes))
                                {
                                    members.AddRange(modRes.GlobalTypes.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Class, this)));
                                    members.AddRange(modRes.Types.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Class, this)));
                                }
                                if (memberType.HasFlag(AstMemberType.Constants))
                                {
                                    members.AddRange(modRes.GlobalConstants.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Constant, this)));
                                    members.AddRange(modRes.Constants.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Constant, this)));
                                }
                                if (memberType.HasFlag(AstMemberType.Dialogs))
                                {
                                    members.AddRange(modRes.Functions.Where(x => x.Value is DeclarativeDialogBlock)
                                                     .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Dialog, this)));
                                }
                                if (memberType.HasFlag(AstMemberType.Reports))
                                {
                                    members.AddRange(modRes.Functions.Where(x => x.Value is ReportBlockNode)
                                                     .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Report, this)));
                                }
                                if (memberType.HasFlag(AstMemberType.Functions))
                                {
                                    members.AddRange(modRes.Functions.Where(x => !(x.Value is ReportBlockNode) && !(x.Value is DeclarativeDialogBlock))
                                                     .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Method, this)));
                                    foreach (var res in modRes.GlobalVariables/*.Where(x =>
                                                                               * {
                                                                               * return x.Value.HasChildFunctions(this);
                                                                               * })*/
                                             .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, this)))
                                    {
                                        if (!members.Contains(res))
                                        {
                                            members.Add(res);
                                        }
                                    }
                                    foreach (var res in modRes.Variables/*.Where(x =>
                                                                         * {
                                                                         * return x.Value.HasChildFunctions(this);
                                                                         * })*/
                                             .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, this)))
                                    {
                                        if (!members.Contains(res))
                                        {
                                            members.Add(res);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            if (memberType.HasFlag(AstMemberType.Functions))
            {
                _includePublicFunctions = true; // allow for deferred adding of public functions
            }

            if (memberType.HasFlag(AstMemberType.Tables))
            {
                _includeDatabaseTables = true;  // allow for deferred adding of external database tables
            }

            members.AddRange(this.ProjectEntry.GetIncludedFiles().Where(x => x.Analysis != null).SelectMany(x => x.Analysis.GetDefinedMembers(1, memberType)));

            return(members);
        }
Beispiel #8
0
        /// <summary>
        /// Gets the variables the given expression evaluates to.  Variables include parameters, locals, and fields assigned on classes, modules and instances.
        ///
        /// Variables are classified as either definitions or references.  Only parameters have unique definition points - all other types of variables
        /// have only one or more references.
        ///
        /// index is a 0-based absolute index into the file.
        /// </summary>
        public override IEnumerable <IAnalysisVariable> GetVariablesByIndex(string exprText, int index, IFunctionInformationProvider functionProvider,
                                                                            IDatabaseInformationProvider databaseProvider, IProgramFileProvider programFileProvider,
                                                                            bool isFunctionCallOrDefinition)
        {
            _functionProvider    = functionProvider;
            _databaseProvider    = databaseProvider;
            _programFileProvider = programFileProvider;

            List <IAnalysisVariable> vars = new List <IAnalysisVariable>();

            _body.SetNamespace(null);
            AstNode containingNode = GetContainingNode(_body, index);

            if (containingNode != null)
            {
                if (!isFunctionCallOrDefinition)
                {
                    if (containingNode is IFunctionResult)
                    {
                        // Check for local vars, types, and constants
                        IFunctionResult func = containingNode as IFunctionResult;
                        IAnalysisResult res;

                        if (func.Variables.TryGetValue(exprText, out res))
                        {
                            vars.Add(new AnalysisVariable(this.ResolveLocation(res), VariableType.Definition));
                        }

                        if (func.Types.TryGetValue(exprText, out res))
                        {
                            vars.Add(new AnalysisVariable(this.ResolveLocation(res), VariableType.Definition));
                        }

                        if (func.Constants.TryGetValue(exprText, out res))
                        {
                            vars.Add(new AnalysisVariable(this.ResolveLocation(res), VariableType.Definition));
                        }

                        List <Tuple <IAnalysisResult, IndexSpan> > limitedScopeVars;
                        if (func.LimitedScopeVariables.TryGetValue(exprText, out limitedScopeVars))
                        {
                            foreach (var item in limitedScopeVars)
                            {
                                if (item.Item2.IsInSpan(index))
                                {
                                    vars.Add(new AnalysisVariable(this.ResolveLocation(res), VariableType.Reference));
                                }
                            }
                        }
                    }
                }

                if (_body is IModuleResult)
                {
                    // check for module vars, types, and constants (and globals defined in this module)
                    IModuleResult   mod = _body as IModuleResult;
                    IAnalysisResult res;

                    if (!isFunctionCallOrDefinition)
                    {
                        if (mod.Variables.TryGetValue(exprText, out res))
                        {
                            vars.Add(new AnalysisVariable(this.ResolveLocation(res), VariableType.Definition));
                        }

                        if (mod.Types.TryGetValue(exprText, out res))
                        {
                            vars.Add(new AnalysisVariable(this.ResolveLocation(res), VariableType.Definition));
                        }

                        if (mod.Constants.TryGetValue(exprText, out res))
                        {
                            vars.Add(new AnalysisVariable(this.ResolveLocation(res), VariableType.Definition));
                        }

                        if (mod.GlobalVariables.TryGetValue(exprText, out res))
                        {
                            vars.Add(new AnalysisVariable(this.ResolveLocation(res), VariableType.Definition));
                        }

                        if (mod.GlobalTypes.TryGetValue(exprText, out res))
                        {
                            vars.Add(new AnalysisVariable(this.ResolveLocation(res), VariableType.Definition));
                        }

                        if (mod.GlobalConstants.TryGetValue(exprText, out res))
                        {
                            vars.Add(new AnalysisVariable(this.ResolveLocation(res), VariableType.Definition));
                        }

                        // check for cursors in this module
                        if (mod.Cursors.TryGetValue(exprText, out res))
                        {
                            vars.Add(new AnalysisVariable(this.ResolveLocation(res), VariableType.Definition));
                        }
                    }
                    else
                    {
                        // check for module functions
                        IFunctionResult funcRes;
                        if (mod.Functions.TryGetValue(exprText, out funcRes))
                        {
                            vars.Add(new AnalysisVariable(this.ResolveLocation(funcRes), VariableType.Definition, funcRes.Name, 1));
                        }
                    }
                }
            }

            // TODO: this could probably be done more efficiently by having each GeneroAst load globals and functions into
            // dictionaries stored on the IGeneroProject, instead of in each project entry.
            // However, this does required more upkeep when changes occur. Will look into it...
            if (_projEntry != null && _projEntry is IGeneroProjectEntry)
            {
                IGeneroProjectEntry genProj = _projEntry as IGeneroProjectEntry;
                if (genProj.ParentProject != null &&
                    !genProj.FilePath.ToLower().EndsWith(".inc"))
                {
                    foreach (var projEntry in genProj.ParentProject.ProjectEntries.Where(x => x.Value != genProj))
                    {
                        if (projEntry.Value.Analysis != null &&
                            projEntry.Value.Analysis.Body != null)
                        {
                            projEntry.Value.Analysis.Body.SetNamespace(null);
                            IModuleResult modRes = projEntry.Value.Analysis.Body as IModuleResult;
                            if (modRes != null)
                            {
                                if (!isFunctionCallOrDefinition)
                                {
                                    // check global vars, types, and constants
                                    // TODO: need to introduce option to enable/disable legacy linking
                                    IAnalysisResult res;
                                    if (modRes.GlobalVariables.TryGetValue(exprText, out res) || modRes.Variables.TryGetValue(exprText, out res))
                                    {
                                        vars.Add(new AnalysisVariable(projEntry.Value.Analysis.ResolveLocation(res), VariableType.Definition));
                                    }

                                    if (modRes.GlobalTypes.TryGetValue(exprText, out res) || modRes.Types.TryGetValue(exprText, out res))
                                    {
                                        vars.Add(new AnalysisVariable(projEntry.Value.Analysis.ResolveLocation(res), VariableType.Definition));
                                    }

                                    if (modRes.GlobalConstants.TryGetValue(exprText, out res) || modRes.Constants.TryGetValue(exprText, out res))
                                    {
                                        vars.Add(new AnalysisVariable(projEntry.Value.Analysis.ResolveLocation(res), VariableType.Definition));
                                    }

                                    // check for cursors in this module
                                    if (modRes.Cursors.TryGetValue(exprText, out res))
                                    {
                                        vars.Add(new AnalysisVariable(projEntry.Value.Analysis.ResolveLocation(res), VariableType.Definition));
                                    }
                                }
                                else
                                {
                                    // check for module functions
                                    IFunctionResult funcRes;
                                    if (modRes.Functions.TryGetValue(exprText, out funcRes))
                                    {
                                        vars.Add(new AnalysisVariable(projEntry.Value.Analysis.ResolveLocation(funcRes), VariableType.Definition, funcRes.Name, 1));
                                    }
                                }
                            }
                        }
                    }
                }
            }

            /* TODO:
             * Need to check for:
             * 1) Temp tables
             * 2) DB Tables and columns
             * 3) Record fields
             */

            if (isFunctionCallOrDefinition && _functionProvider != null)
            {
                var funcRes = _functionProvider.GetFunction(exprText);
                if (funcRes != null)
                {
                    vars.AddRange(funcRes.Select(x => new AnalysisVariable(x.Location, VariableType.Definition, x.Name, 2)));
                }

                IFunctionResult funcResult;
                if (SystemFunctions.TryGetValue(exprText, out funcResult))
                {
                    vars.Add(new AnalysisVariable(funcResult.Location, VariableType.Definition, funcResult.Name, 2));
                }
            }

            // try an imported module
            if (Body is IModuleResult && ProjectEntry != null)
            {
                if ((Body as IModuleResult).FglImports.Contains(exprText))
                {
                    // need to get the ast for the other project entry
                    var refProjKVP = (ProjectEntry as IGeneroProjectEntry).ParentProject.ReferencedProjects.Values.FirstOrDefault(
                        x =>
                    {
                        var fn = Path.GetFileNameWithoutExtension(x.Directory);
                        return(fn?.Equals(exprText, StringComparison.OrdinalIgnoreCase) ?? false);
                    });
                    if (refProjKVP is IAnalysisResult)
                    {
                        IGeneroProject definingProject = refProjKVP;
                        vars.Add(new AnalysisVariable(new LocationInfo(definingProject.Directory, 1), VariableType.Definition));
                    }
                }
            }

            if (exprText.Contains('.') && vars.Count == 0)
            {
                IGeneroProject  definingProj;
                IProjectEntry   projEntry;
                bool            dummyDef;
                IAnalysisResult res = GetValueByIndex(exprText, index, functionProvider, databaseProvider, _programFileProvider, isFunctionCallOrDefinition, out dummyDef, out definingProj, out projEntry);
                if (res != null)
                {
                    LocationInfo locInfo = null;
                    if (definingProj != null || projEntry != null)
                    {
                        locInfo = ResolveLocationInternal(definingProj, projEntry, res);
                    }
                    else
                    {
                        locInfo = this.ResolveLocation(res);
                    }
                    if (locInfo != null &&
                        (
                            (locInfo.Index > 0 || (locInfo.Line > 0 && locInfo.Column > 0)) ||
                            !string.IsNullOrWhiteSpace(locInfo.DefinitionURL)
                        )
                        )
                    {
                        vars.Add(new AnalysisVariable(locInfo, VariableType.Definition));
                    }
                }
            }

            if (_body is IModuleResult &&
                _projEntry is IGeneroProjectEntry)
            {
                string   dotPiece  = exprText;
                string[] dotPieces = exprText.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
                if (dotPieces.Length > 1)
                {
                    dotPiece = dotPieces[0];
                }
                if ((_body as IModuleResult).FglImports.Contains(dotPiece))
                {
                    // need to get the ast for the other project entry
                    var refProjKVP = (_projEntry as IGeneroProjectEntry).ParentProject.ReferencedProjects.Values.FirstOrDefault(
                        x =>
                    {
                        var fn = Path.GetFileName(x.Directory);
                        return(fn?.Equals(dotPiece, StringComparison.OrdinalIgnoreCase) ?? false);
                    });
                    if (refProjKVP is IAnalysisResult)
                    {
                        IProjectEntry   dummyEntry;
                        bool            dummyDef;
                        IAnalysisResult res = GetValueByIndex(exprText, index, functionProvider, databaseProvider, _programFileProvider, isFunctionCallOrDefinition, out dummyDef, out refProjKVP, out dummyEntry);
                        if (res != null)
                        {
                            LocationInfo locInfo = null;
                            locInfo = refProjKVP != null?ResolveLocationInternal(refProjKVP, dummyEntry, res) : this.ResolveLocation(res);

                            if (locInfo != null && (locInfo.Index > 0 || (locInfo.Line > 0 && locInfo.Column > 0)))
                            {
                                vars.Add(new AnalysisVariable(locInfo, VariableType.Definition));
                            }
                        }
                    }
                }
            }

            if (!isFunctionCallOrDefinition)
            {
                foreach (var includeFile in this.ProjectEntry.GetIncludedFiles())
                {
                    IAnalysisResult res;
                    if (includeFile.Analysis != null &&
                        includeFile.Analysis.Body is IModuleResult)
                    {
                        includeFile.Analysis.Body.SetNamespace(null);
                        var mod = includeFile.Analysis.Body as IModuleResult;
                        if (mod.Types.TryGetValue(exprText, out res))
                        {
                            vars.Add(new AnalysisVariable(ResolveLocationInternal(null, includeFile, res), VariableType.Definition));
                        }
                        if (mod.Constants.TryGetValue(exprText, out res))
                        {
                            vars.Add(new AnalysisVariable(ResolveLocationInternal(null, includeFile, res), VariableType.Definition));
                        }
                    }
                }
            }

            return(vars);
        }
Beispiel #9
0
        public static IAnalysisResult GetValueByIndex(string exprText, int index, Genero4glAst ast, out IGeneroProject definingProject, out IProjectEntry projectEntry, out bool isDeferredFunction,
                                                      FunctionProviderSearchMode searchInFunctionProvider = FunctionProviderSearchMode.NoSearch, bool isFunctionCallOrDefinition = false,
                                                      bool getTypes = true, bool getVariables = true, bool getConstants = true)
        {
            isDeferredFunction = false;
            definingProject    = null;
            projectEntry       = null;
            //_functionProvider = functionProvider;
            //_databaseProvider = databaseProvider;
            //_programFileProvider = programFileProvider;

            AstNode containingNode = null;

            if (ast != null)
            {
                containingNode = GetContainingNode(ast.Body, index);
                ast.Body.SetNamespace(null);
            }

            IAnalysisResult res = null;
            int             tmpIndex = 0;
            int             bracketDepth = 0;
            bool            doSearch = false;
            bool            resetStartIndex = false;
            int             startIndex = 0, endIndex = 0;
            bool            noEndIndexSet = false;

            if (exprText == null)
            {
                return(null);
            }

            while (tmpIndex < exprText.Length)
            {
                if (resetStartIndex)
                {
                    startIndex      = tmpIndex;
                    resetStartIndex = false;
                    if (startIndex + 1 > exprText.Length)
                    {
                        break;
                    }
                }

                doSearch = false;
                switch (exprText[tmpIndex])
                {
                case '.':
                {
                    if (bracketDepth == 0)
                    {
                        endIndex = tmpIndex - 1;
                        if (endIndex >= startIndex)
                        {
                            // we have our 'piece'
                            doSearch = true;
                        }
                        if (exprText[startIndex] == '.')
                        {
                            startIndex++;
                        }
                    }
                    tmpIndex++;
                }
                break;

                case '[':
                    if (noEndIndexSet)
                    {
                        noEndIndexSet = false;
                    }
                    else
                    {
                        if (bracketDepth == 0)
                        {
                            endIndex = tmpIndex - 1;
                        }
                    }
                    bracketDepth++;
                    tmpIndex++;
                    break;

                case ']':
                {
                    bracketDepth--;
                    if (bracketDepth == 0)
                    {
                        if (exprText.Length <= tmpIndex + 1 ||
                            exprText[tmpIndex + 1] != '[')
                        {
                            // we have our first 'piece'
                            doSearch = true;
                        }
                        else
                        {
                            noEndIndexSet = true;
                        }
                    }
                    tmpIndex++;
                }
                break;

                default:
                {
                    if (bracketDepth == 0 && (tmpIndex + 1 == exprText.Length))
                    {
                        endIndex = tmpIndex;
                        doSearch = true;
                    }
                    tmpIndex++;
                }
                break;
                }

                if (!doSearch)
                {
                    continue;
                }

                // we can do our search
                var dotPiece = exprText.Substring(startIndex, (endIndex - startIndex) + 1);
                if (dotPiece.Contains('('))
                {
                    // remove the params piece
                    int remIndex = dotPiece.IndexOf('(');
                    dotPiece = dotPiece.Substring(0, remIndex);
                }

                bool lookForFunctions = isFunctionCallOrDefinition && (endIndex + 1 == exprText.Length);

                resetStartIndex = true;

                if (res != null)
                {
                    if (ast != null)
                    {
                        var gmi = new GetMemberInput
                        {
                            Name       = dotPiece,
                            AST        = ast,
                            IsFunction = lookForFunctions
                        };
                        IAnalysisResult tempRes = res.GetMember(gmi);
                        if (gmi.DefiningProject != null && definingProject != gmi.DefiningProject)
                        {
                            definingProject = gmi.DefiningProject;
                        }
                        if (gmi.ProjectEntry != null && projectEntry != gmi.ProjectEntry)
                        {
                            projectEntry = gmi.ProjectEntry;
                        }
                        res = tempRes;
                        if (tempRes == null)
                        {
                            res = null;
                            break;
                        }
                    }
                    else
                    {
                        res = null;
                        break;
                    }
                }
                else
                {
                    IFunctionResult funcRes;
                    if (!lookForFunctions)
                    {
                        if (SystemVariables.TryGetValue(dotPiece, out res) ||
                            SystemConstants.TryGetValue(dotPiece, out res) ||
                            SystemMacros.TryGetValue(dotPiece, out res))
                        {
                            continue;
                        }
                    }
                    else
                    {
                        if (SystemFunctions.TryGetValue(dotPiece, out funcRes))
                        {
                            res = funcRes;
                            continue;
                        }

                        if (ast != null && ast._functionProvider != null && ast._functionProvider.Name.Equals(dotPiece, StringComparison.OrdinalIgnoreCase))
                        {
                            res = ast._functionProvider;
                            continue;
                        }
                    }

                    if (containingNode != null && containingNode is IFunctionResult)
                    {
                        IFunctionResult func = containingNode as IFunctionResult;
                        if ((getVariables && func.Variables.TryGetValue(dotPiece, out res)))
                        {
                            continue;
                        }
                        if (!lookForFunctions)
                        {
                            // Check for local vars, types, and constants
                            if ((getTypes && func.Types.TryGetValue(dotPiece, out res)) ||
                                (getConstants && func.Constants.TryGetValue(dotPiece, out res)))
                            {
                                continue;
                            }

                            List <Tuple <IAnalysisResult, IndexSpan> > limitedScopeVars;
                            if ((getVariables && func.LimitedScopeVariables.TryGetValue(dotPiece, out limitedScopeVars)))
                            {
                                foreach (var item in limitedScopeVars)
                                {
                                    if (item.Item2.IsInSpan(index))
                                    {
                                        res = item.Item1;

                                        break;
                                    }
                                }
                                if (res != null)
                                {
                                    continue;
                                }
                            }
                        }
                    }

                    if (ast != null && ast.Body is IModuleResult)
                    {
                        IModuleResult mod = ast.Body as IModuleResult;
                        if (!lookForFunctions)
                        {
                            // check for module vars, types, and constants (and globals defined in this module)
                            if ((getVariables && (mod.Variables.TryGetValue(dotPiece, out res) || mod.GlobalVariables.TryGetValue(dotPiece, out res))) ||
                                (getTypes && (mod.Types.TryGetValue(dotPiece, out res) || mod.GlobalTypes.TryGetValue(dotPiece, out res))) ||
                                (getConstants && (mod.Constants.TryGetValue(dotPiece, out res) || mod.GlobalConstants.TryGetValue(dotPiece, out res))))
                            {
                                continue;
                            }

                            // check for cursors in this module
                            if (mod.Cursors.TryGetValue(dotPiece, out res))
                            {
                                continue;
                            }
                        }
                        else
                        {
                            // check for module functions
                            if (mod.Functions.TryGetValue(dotPiece, out funcRes))
                            {
                                // check for any function info collected at the project entry level, and update the function's documentation with that.
                                if (ast._projEntry != null && ast._projEntry is IGeneroProjectEntry)
                                {
                                    var commentInfo = (ast._projEntry as IGeneroProjectEntry).GetFunctionInfo(funcRes.Name);
                                    if (commentInfo != null)
                                    {
                                        funcRes.SetCommentDocumentation(commentInfo);
                                    }
                                }
                                res = funcRes;
                                continue;
                            }
                        }
                    }

                    // TODO: this could probably be done more efficiently by having each GeneroAst load globals and functions into
                    // dictionaries stored on the IGeneroProject, instead of in each project entry.
                    // However, this does required more upkeep when changes occur. Will look into it...
                    if (ast != null && ast.ProjectEntry != null && ast.ProjectEntry is IGeneroProjectEntry)
                    {
                        IGeneroProjectEntry genProj = ast.ProjectEntry as IGeneroProjectEntry;
                        if (genProj.ParentProject != null &&
                            !genProj.FilePath.ToLower().EndsWith(".inc"))
                        {
                            bool found = false;
                            foreach (var projEntry in genProj.ParentProject.ProjectEntries.Where(x => x.Value != genProj))
                            {
                                if (projEntry.Value.Analysis != null &&
                                    projEntry.Value.Analysis.Body != null)
                                {
                                    projEntry.Value.Analysis.Body.SetNamespace(null);
                                    IModuleResult modRes = projEntry.Value.Analysis.Body as IModuleResult;
                                    if (modRes != null)
                                    {
                                        if (!lookForFunctions)
                                        {
                                            // check global vars, types, and constants
                                            // TODO: need option to enable/disable legacy linking
                                            if ((getVariables && (modRes.Variables.TryGetValue(dotPiece, out res) || modRes.GlobalVariables.TryGetValue(dotPiece, out res))) ||
                                                (getTypes && (modRes.Types.TryGetValue(dotPiece, out res) || modRes.GlobalTypes.TryGetValue(dotPiece, out res))) ||
                                                (getConstants && (modRes.Constants.TryGetValue(dotPiece, out res) || modRes.GlobalConstants.TryGetValue(dotPiece, out res))))
                                            {
                                                found = true;
                                                break;
                                            }

                                            // check for cursors in this module
                                            if (modRes.Cursors.TryGetValue(dotPiece, out res))
                                            {
                                                found = true;
                                                break;
                                            }
                                        }
                                        else
                                        {
                                            // check project functions
                                            if (modRes.Functions.TryGetValue(dotPiece, out funcRes))
                                            {
                                                if (funcRes.AccessModifier == AccessModifier.Public)
                                                {
                                                    res   = funcRes;
                                                    found = true;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }
                            }

                            if (found)
                            {
                                continue;
                            }
                        }
                    }

                    // check for classes
                    GeneroPackage package;
                    if (Packages.TryGetValue(dotPiece, out package))
                    {
                        res = package;
                        continue;
                    }

                    /* TODO:
                     * Need to check for:
                     * 1) Temp tables
                     */

                    // Nothing found yet...
                    // If our containing node is at the function or globals level, we need to go deeper
                    if (containingNode != null &&
                        (containingNode is GlobalsNode ||
                         containingNode is FunctionBlockNode ||
                         containingNode is ReportBlockNode))
                    {
                        containingNode = GetContainingNode(containingNode, index);
                    }
                    // check for record field
                    if (containingNode != null &&
                        (containingNode is DefineNode ||
                         containingNode is TypeDefNode))
                    {
                        containingNode = GetContainingNode(containingNode, index);

                        if (containingNode != null &&
                            (containingNode is VariableDefinitionNode ||
                             containingNode is TypeDefinitionNode) &&
                            containingNode.Children.Count == 1 &&
                            containingNode.Children[containingNode.Children.Keys[0]] is TypeReference)
                        {
                            var typeRef = containingNode.Children[containingNode.Children.Keys[0]] as TypeReference;
                            while (typeRef != null &&
                                   typeRef.Children.Count == 1)
                            {
                                if (typeRef.Children[typeRef.Children.Keys[0]] is RecordDefinitionNode)
                                {
                                    var         recNode = typeRef.Children[typeRef.Children.Keys[0]] as RecordDefinitionNode;
                                    VariableDef recField;
                                    if (recNode.MemberDictionary.TryGetValue(exprText, out recField))
                                    {
                                        res = recField;
                                        break;
                                    }
                                    else
                                    {
                                        recField = recNode.MemberDictionary.Where(x => x.Value.LocationIndex < index)
                                                   .OrderByDescending(x => x.Value.LocationIndex)
                                                   .Select(x => x.Value)
                                                   .FirstOrDefault();
                                        if (recField != null)
                                        {
                                            typeRef = recField.Type;
                                        }
                                        else
                                        {
                                            break;
                                        }
                                    }
                                }
                                else if (typeRef.Children[typeRef.Children.Keys[0]] is TypeReference)
                                {
                                    typeRef = typeRef.Children[typeRef.Children.Keys[0]] as TypeReference;
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                    }

                    // try an imported module
                    if (ast != null && ast.Body is IModuleResult &&
                        ast.ProjectEntry != null && ast.ProjectEntry != null)
                    {
                        if ((ast.Body as IModuleResult).FglImports.Contains(dotPiece))
                        {
                            // need to get the ast for the other project entry
                            var refProjKVP = (ast.ProjectEntry as IGeneroProjectEntry).ParentProject.ReferencedProjects.Values.FirstOrDefault(
                                x =>
                            {
                                var fn = Path.GetFileNameWithoutExtension(x.Directory);
                                return(fn?.Equals(dotPiece, StringComparison.OrdinalIgnoreCase) ?? false);
                            });
                            if (refProjKVP is IAnalysisResult)
                            {
                                definingProject = refProjKVP;
                                res             = refProjKVP as IAnalysisResult;
                                continue;
                            }

                            IAnalysisResult sysImportMod;
                            // check the system imports
                            if (SystemImportModules.TryGetValue(dotPiece, out sysImportMod))
                            {
                                res = sysImportMod;
                                continue;
                            }
                        }
                    }

                    if (!lookForFunctions)
                    {
                        // try include files
                        var foundInclude = false;
                        if (ast?.ProjectEntry != null)
                        {
                            foreach (var includeFile in ast.ProjectEntry.GetIncludedFiles())
                            {
                                if (includeFile.Analysis?.Body is IModuleResult)
                                {
                                    var mod = includeFile.Analysis.Body as IModuleResult;
                                    if ((getTypes && (mod.Types.TryGetValue(dotPiece, out res) || mod.GlobalTypes.TryGetValue(dotPiece, out res))) ||
                                        (getConstants && (mod.Constants.TryGetValue(dotPiece, out res) || mod.GlobalConstants.TryGetValue(dotPiece, out res))))
                                    {
                                        foundInclude = true;
                                        break;
                                    }
                                }
                            }
                        }
                        if (foundInclude)
                        {
                            continue;
                        }

                        if (ast?._databaseProvider != null)
                        {
                            res = ast._databaseProvider.GetTable(dotPiece);
                            if (res != null)
                            {
                                continue;
                            }
                        }
                    }

                    // Only do a public function search if the dotPiece is the whole text we're searching for
                    // I.e. no namespaces
                    if (lookForFunctions && dotPiece == exprText)
                    {
                        if (searchInFunctionProvider == FunctionProviderSearchMode.Search)
                        {
                            if (res == null && ast?._functionProvider != null)
                            {
                                // check for the function name in the function provider
                                var funcs = ast._functionProvider.GetFunction(dotPiece);
                                if (funcs != null)
                                {
                                    res = funcs.FirstOrDefault();
                                    if (res != null)
                                    {
                                        continue;
                                    }
                                }
                            }
                        }
                        else if (searchInFunctionProvider == FunctionProviderSearchMode.Deferred)
                        {
                            isDeferredFunction = true;
                        }
                    }

                    if (res == null)
                    {
                        break;
                    }
                }
            }

            return(res);
        }
Beispiel #10
0
        /// <summary>
        /// Gets information about the available signatures for the given expression.
        /// </summary>
        /// <param name="exprText">The expression to get signatures for.</param>
        /// <param name="index">The 0-based absolute index into the file.</param>
        public override IEnumerable <IFunctionResult> GetSignaturesByIndex(string exprText, int index, IReverseTokenizer revTokenizer, IFunctionInformationProvider functionProvider)
        {
            _functionProvider = functionProvider;

            // First see if we're in the process of defining a function
            List <MemberResult> dummyList;

            if (TryFunctionDefContext(index, revTokenizer, out dummyList))
            {
                return(null);
            }

            /*
             * Need to check for:
             * 1) Functions within the current module
             * 2) Functions within the current project
             * 3) Public functions
             */
            if (_body is IModuleResult)
            {
                _body.SetNamespace(null);
                // check for module vars, types, and constants (and globals defined in this module)
                IModuleResult mod = _body as IModuleResult;

                // check for module functions
                IFunctionResult funcRes;
                if (mod.Functions.TryGetValue(exprText, out funcRes))
                {
                    return(new IFunctionResult[1] {
                        funcRes
                    });
                }
            }

            if (_projEntry != null && _projEntry is IGeneroProjectEntry)
            {
                IGeneroProjectEntry genProj = _projEntry as IGeneroProjectEntry;
                if (genProj.ParentProject != null &&
                    !genProj.FilePath.ToLower().EndsWith(".inc"))
                {
                    foreach (var projEntry in genProj.ParentProject.ProjectEntries.Where(x => x.Value != genProj))
                    {
                        if (projEntry.Value.Analysis != null &&
                            projEntry.Value.Analysis.Body != null)
                        {
                            projEntry.Value.Analysis.Body.SetNamespace(null);
                            IModuleResult modRes = projEntry.Value.Analysis.Body as IModuleResult;
                            if (modRes != null)
                            {
                                // check project functions
                                IFunctionResult funcRes;
                                if (modRes.Functions.TryGetValue(exprText, out funcRes))
                                {
                                    if (funcRes.AccessModifier == AccessModifier.Public)
                                    {
                                        return new IFunctionResult[1] {
                                                   funcRes
                                        }
                                    }
                                    ;
                                }
                            }
                        }
                    }
                }
            }

            // Check for class methods
            IGeneroProject  dummyProj;
            IProjectEntry   dummyProjEntry;
            bool            dummyDef;
            IAnalysisResult member = GetValueByIndex(exprText, index, _functionProvider, _databaseProvider, _programFileProvider, true, out dummyDef, out dummyProj, out dummyProjEntry);

            if (member is IFunctionResult)
            {
                return(new IFunctionResult[1] {
                    member as IFunctionResult
                });
            }
            else if (member is VariableDef &&
                     (member as VariableDef).Type != null)
            {
                var typeRef = (member as VariableDef).Type;
                if (typeRef.ResolvedType != null && typeRef.ResolvedType is TypeDefinitionNode)
                {
                    var tdn = typeRef.ResolvedType as TypeDefinitionNode;
                    if (tdn.TypeRef != null && tdn.TypeRef is FunctionTypeReference)
                    {
                        return(new IFunctionResult[1] {
                            tdn.TypeRef as FunctionTypeReference
                        });
                    }
                }
            }

            if (_functionProvider != null)
            {
                // check for the function name in the function provider
                var func = _functionProvider.GetFunction(exprText);
                if (func != null)
                {
                    return(func);
                }
            }

            return(null);
        }