예제 #1
0
        public static IEnumerable<TestCaseInfo> GetTestCases(IProjectEntry projEntry)
        {
            var entry = projEntry as IPythonProjectEntry;
            if (entry == null) {
                yield break;
            }

            foreach (var classValue in GetTestCaseClasses(entry)) {
                // Check the name of all functions on the class using the
                // analyzer. This will return functions defined on this
                // class and base classes
                foreach (var member in GetTestCaseMembers(entry, classValue)) {
                    // Find the definition to get the real location of the
                    // member. Otherwise decorators will confuse us.
                    var definition = entry.Analysis
                        .GetVariablesByIndex(classValue.Name + "." + member.Key, 0)
                        .FirstOrDefault(v => v.Type == VariableType.Definition);

                    var location = (definition != null) ?
                        definition.Location :
                        member.Value.SelectMany(m => m.Locations).FirstOrDefault(loc => loc != null);

                    int endLine = location?.EndLine ?? location?.StartLine ?? 0;

                    yield return new TestCaseInfo(
                        classValue.DeclaringModule.FilePath,
                        classValue.Name,
                        member.Key,
                        location.StartLine,
                        location.StartColumn,
                        endLine
                    );
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Parses the specified file on disk.
        /// </summary>
        /// <param name="filename"></param>
        private void EnqueueFile(IProjectEntry projEntry, string filename) {
            // get the current snapshot from the UI thread

            EnqueWorker(() => {
                for (int i = 0; i < 10; i++) {
                    try {
                        if (!File.Exists(filename)) {
                            break;
                        }

                        var cookie = new FileCookie(filename);
                        var reader = new StreamReader(
                            new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete)
                        );

                        using (reader) {
                            ParseFile(projEntry, filename, reader, cookie);
                        }
                        return;
                    } catch (IOException) {
                        // file being copied, try again...
                        Thread.Sleep(100);
                    } catch (UnauthorizedAccessException) {
                        // file is inaccessible, try again...
                        Thread.Sleep(100);
                    }
                }

                IJsProjectEntry pyEntry = projEntry as IJsProjectEntry;
                if (pyEntry != null) {
                    // failed to parse, keep the UpdateTree calls balanced
                    pyEntry.UpdateTree(null, null);
                }
            });
        }
예제 #3
0
파일: ParseQueue.cs 프로젝트: omnimark/PTVS
        /// <summary>
        /// Parses the specified file on disk.
        /// </summary>
        /// <param name="filename"></param>
        public void EnqueueFile(IProjectEntry projEntry, string filename) {
            var severity = _parser.PyService.GeneralOptions.IndentationInconsistencySeverity;
            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);
                    }
                }

                IPythonProjectEntry pyEntry = projEntry as IPythonProjectEntry;
                if (pyEntry != null) {
                    // failed to parse, keep the UpdateTree calls balanced
                    pyEntry.UpdateTree(null, null);
                }
            });
        }
예제 #4
0
            private const int ReparseDelay = 1000;      // delay in MS before we re-parse a buffer w/ non-line changes.

            public BufferParser(IProjectEntry initialProjectEntry, VsProjectAnalyzer parser, ITextBuffer buffer) {
                _parser = parser;
                _timer = new Timer(ReparseTimer, null, Timeout.Infinite, Timeout.Infinite);
                _buffers = new[] { buffer };
                _currentProjEntry = initialProjectEntry;
                AttachedViews = 1;

                InitBuffer(buffer);
            }
예제 #5
0
        /// <summary>
        /// Parses the specified text buffer.  Continues to monitor the parsed buffer and updates
        /// the parse tree asynchronously as the buffer changes.
        /// </summary>
        /// <param name="buffer"></param>
        private BufferParser EnqueueBuffer(IProjectEntry projEntry, ITextBuffer buffer) {
            // only attach one parser to each buffer, we can get multiple enqueue's
            // for example if a document is already open when loading a project.
            BufferParser bufferParser;
            if (!buffer.Properties.TryGetProperty<BufferParser>(typeof(BufferParser), out bufferParser)) {
                bufferParser = new BufferParser(projEntry, this, buffer);

                var curSnapshot = buffer.CurrentSnapshot;
                bufferParser.EnqueingEntry();
                EnqueWorker(() => {
                    ParseBuffers(bufferParser, curSnapshot);
                });
            } else {
                bufferParser.AttachedViews++;
            }

            return bufferParser;
        }
예제 #6
0
파일: ParseQueue.cs 프로젝트: omnimark/PTVS
        /// <summary>
        /// Parses the specified text buffer.  Continues to monitor the parsed buffer and updates
        /// the parse tree asynchronously as the buffer changes.
        /// </summary>
        /// <param name="buffer"></param>
        public BufferParser EnqueueBuffer(IProjectEntry projEntry, ITextView textView, ITextBuffer buffer) {
            // only attach one parser to each buffer, we can get multiple enqueue's
            // for example if a document is already open when loading a project.
            BufferParser bufferParser;
            if (!buffer.Properties.TryGetProperty<BufferParser>(typeof(BufferParser), out bufferParser)) {
                Dispatcher dispatcher = null;
                var uiElement = textView as UIElement;
                if (uiElement != null) {
                    dispatcher = uiElement.Dispatcher;
                }
                bufferParser = new BufferParser(this, dispatcher, projEntry, _parser, buffer);

                var curSnapshot = buffer.CurrentSnapshot;
                var severity = _parser.PyService.GeneralOptions.IndentationInconsistencySeverity;
                bufferParser.EnqueingEntry();
                EnqueWorker(() => {
                    _parser.ParseBuffers(bufferParser, severity, curSnapshot);
                });
            } else {
                bufferParser.AttachedViews++;
            }
            
            return bufferParser;
        }
예제 #7
0
        private void ParseFile(IProjectEntry entry, IDictionary<int, CodeInfo> buffers) {
            IPythonProjectEntry pyEntry;
            IExternalProjectEntry externalEntry;

            SortedDictionary<int, ParseResult> parseResults = new SortedDictionary<int, ParseResult>();

            if ((pyEntry = entry as IPythonProjectEntry) != null) {
                foreach (var buffer in buffers) {
                    var errorSink = new CollectingErrorSink();
                    var tasks = new List<AP.TaskItem>();
                    ParserOptions options = MakeParserOptions(errorSink, tasks);

                    using (var parser = buffer.Value.CreateParser(Project.LanguageVersion, options)) {
                        var ast = ParseOneFile(parser);
                        parseResults[buffer.Key] = new ParseResult(
                            ast,
                            errorSink,
                            tasks,
                            buffer.Value.Version
                        );
                    }
                }

                // Save the single or combined tree into the project entry
                UpdateAnalysisTree(pyEntry, parseResults);

                // update squiggles for the buffer. snapshot may be null if we
                // are analyzing a file that is not open
                SendParseComplete(pyEntry, parseResults);

                // enqueue analysis of the file
                if (parseResults.Where(x => x.Value.Ast != null).Any()) {
                    _analysisQueue.Enqueue(pyEntry, AnalysisPriority.Normal);
                }
            } else if ((externalEntry = entry as IExternalProjectEntry) != null) {
                foreach (var keyValue in buffers) {
                    externalEntry.ParseContent(keyValue.Value.GetReader(), null);
                    _analysisQueue.Enqueue(entry, AnalysisPriority.Normal);
                }
            }
        }
예제 #8
0
 public LocationInfo ResolveLocation(IProjectEntry project, object location) {
     SourceLocation loc = (SourceLocation)location;
     return new LocationInfo(project, loc.Line, loc.Column);
 }
        private void ParseFile(IProjectEntry entry, string filename, TextReader reader, IAnalysisCookie cookie) {
            IJsProjectEntry jsEntry;
            IExternalProjectEntry externalEntry;

            if ((jsEntry = entry as IJsProjectEntry) != null) {
                JsAst ast;
                CollectingErrorSink errorSink;
                ParseNodejsCode(reader, out ast, out errorSink);

                if (ast != null) {
                    jsEntry.UpdateTree(ast, cookie);
                } else {
                    // notify that we failed to update the existing analysis
                    jsEntry.UpdateTree(null, null);
                }
                ProjectItem item;
                if (!_projectFiles.TryGetValue(filename, out item) || item.ReportErrors) {
                    // update squiggles for the buffer. snapshot may be null if we
                    // are analyzing a file that is not open
                    UpdateErrorsAndWarnings(entry, GetSnapshot(reader), errorSink);
                } else {
                    TaskProvider.Clear(entry, ParserTaskMoniker);
                }

                // enqueue analysis of the file
                if (ast != null && ShouldEnqueue()) {
                    _analysisQueue.Enqueue(jsEntry, AnalysisPriority.Normal);
                }
            } else if ((externalEntry = entry as IExternalProjectEntry) != null) {
                externalEntry.ParseContent(reader ?? reader, cookie);
                if (ShouldEnqueue()) {
                    _analysisQueue.Enqueue(entry, AnalysisPriority.Normal);
                }
            }
        }
예제 #10
0
 public abstract IAnalysisResult GetValueByIndex(string exprText, int index, IFunctionInformationProvider functionProvider,
                                                 IDatabaseInformationProvider databaseProvider, IProgramFileProvider programFileProvider,
                                                 bool isFunctionCallOrDefinition, out bool isDeferred,
                                                 out IGeneroProject definingProject, out IProjectEntry projectEntry,
                                                 FunctionProviderSearchMode searchInFunctionProvider = FunctionProviderSearchMode.NoSearch);
예제 #11
0
 internal static string GetPathInZipFile(IProjectEntry entry) {
     object result;
     entry.Properties.TryGetValue(_pathInZipFile, out result);
     return (string)result;
 }
예제 #12
0
        internal void ClearParserTasks(IProjectEntry entry) {
            if (entry != null) {
                _errorProvider.Clear(entry, ParserTaskMoniker);
                _commentTaskProvider.Clear(entry, ParserTaskMoniker);
                _unresolvedSquiggles.StopListening(entry as IPythonProjectEntry);

                bool removed = false;
                lock (_hasParseErrorsLock) {
                    removed = _hasParseErrors.Remove(entry);
                }
                if (removed) {
                    OnShouldWarnOnLaunchChanged(entry);
                }
            }
        }
예제 #13
0
 internal static bool TryGetAnalysis(this ITextBuffer buffer, out IProjectEntry analysis)
 {
     return buffer.Properties.TryGetProperty<IProjectEntry>(typeof(IProjectEntry), out analysis);
 }
예제 #14
0
 /// <summary>
 /// Replaces the items for the specified entry.
 /// </summary>
 public void ReplaceItems(IProjectEntry entry, string moniker, List <TaskProviderItem> items)
 {
     SendMessage(WorkerMessage.Replace(entry, moniker, items));
 }
예제 #15
0
 public static WorkerMessage Append(IProjectEntry entry, string moniker, List <TaskProviderItem> items)
 {
     return(new AppendMessage(new EntryKey(entry, moniker), items));
 }
예제 #16
0
 public static WorkerMessage Clear(IProjectEntry entry, string moniker)
 {
     return(new ClearMessage(new EntryKey(entry, moniker)));
 }
예제 #17
0
 public EntryKey(IProjectEntry entry, string moniker)
 {
     Entry   = entry;
     Moniker = moniker;
 }
예제 #18
0
        public IAnalysisSet GetTypesNoCopy(IProjectEntry accessor = null, IProjectEntry declaringScope = null)
        {
            bool needsCopy;

            return(GetTypesWorker(accessor, declaringScope, out needsCopy));
        }
예제 #19
0
 public IAnalysisSet GetTypesNoCopy(AnalysisUnit accessor, IProjectEntry declaringScope = null)
 {
     return(GetTypesNoCopy(accessor.ProjectEntry, declaringScope));
 }
예제 #20
0
        public bool AddTypes(IVersioned projectEntry, IAnalysisSet newTypes, bool enqueue = true, IProjectEntry declaringScope = null)
        {
            object dummy;

            if (LockedVariableDefs.TryGetValue(this, out dummy))
            {
                return(false);
            }

            bool added = false;

            if (newTypes.Count > 0)
            {
                var dependencies = GetDependentItems(projectEntry);

                foreach (var value in newTypes)
                {
#if DEBUG || FULL_VALIDATION
                    if (ENABLE_SET_CHECK)
                    {
                        bool testAdded;
                        var  original   = dependencies.ToImmutableTypeSet();
                        var  afterAdded = original.Add(value, out testAdded, false);
                        if (afterAdded.Comparer == original.Comparer)
                        {
                            if (testAdded)
                            {
                                if (!ObjectComparer.Instance.Equals(afterAdded, original))
                                {
                                    // Double validation, as sometimes testAdded is a false positive
                                    afterAdded = original.Add(value, out testAdded, false);
                                    if (testAdded)
                                    {
                                        Validation.Assert(!ObjectComparer.Instance.Equals(afterAdded, original), $"Inconsistency adding {value} to {original}");
                                    }
                                }
                            }
                            else if (afterAdded.Count == original.Count)
                            {
                                Validation.Assert(ObjectComparer.Instance.Equals(afterAdded, original), $"Inconsistency not adding {value} to {original}");
                            }
                        }
                    }
#endif

                    if (dependencies.AddType(value))
                    {
                        added = true;
                    }
                }
            }

            if (added)
            {
                _cache = null;
            }
            if (added && enqueue)
            {
                EnqueueDependents(projectEntry, declaringScope);
            }

            return(added);
        }
예제 #21
0
        /// <summary>
        /// Parses the specified file on disk.
        /// </summary>
        /// <param name="filename"></param>
        public void EnqueueFile(IProjectEntry projEntry, string filename) {
            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)) {
                            ParseFile(
                                projEntry,
                                new Dictionary<int, CodeInfo> {
                                    { 0, new StreamCodeInfo(0, reader) }
                                }
                            );
                            return;
                        }
                    } catch (IOException) {
                        // file being copied, try again...
                        Thread.Sleep(100);
                    } catch (UnauthorizedAccessException) {
                        // file is inaccessible, try again...
                        Thread.Sleep(100);
                    }
                }

                IPythonProjectEntry pyEntry = projEntry as IPythonProjectEntry;
                if (pyEntry != null) {
                    SendParseComplete(pyEntry, new SortedDictionary<int, ParseResult>());
                    // failed to parse, keep the UpdateTree calls balanced
                    pyEntry.UpdateTree(null, null);
                }
            });
        }
예제 #22
0
 public void AddDependency(IProjectEntry projectEntry) {
     lock (_dependencies) {
         _dependencies.Add(projectEntry);
     }
 }
예제 #23
0
 /// <summary>
 /// Adds items to the specified entry's existing items.
 /// </summary>
 public void AddItems(IProjectEntry entry, string moniker, List <TaskProviderItem> items)
 {
     SendMessage(WorkerMessage.Append(entry, moniker, items));
 }
예제 #24
0
 public IAnalysisResult GetMember(string name, Genero4glAst ast, out IGeneroProject definingProject, out IProjectEntry projEntry, bool function)
 {
     definingProject = null;
     projEntry       = null;
     return(null);
 }
예제 #25
0
 /// <summary>
 /// Removes all items for the specified entry.
 /// </summary>
 public void Clear(IProjectEntry entry, string moniker)
 {
     SendMessage(WorkerMessage.Clear(entry, moniker));
 }
예제 #26
0
 private void OnShouldWarnOnLaunchChanged(IProjectEntry entry) {
     var evt = ShouldWarnOnLaunchChanged;
     if (evt != null) {
         evt(this, new EntryEventArgs(entry));
     }
 }
예제 #27
0
 /// <summary>
 /// Clears all tracked buffers for the given project entry and moniker for
 /// the error source.
 /// </summary>
 public void ClearErrorSource(IProjectEntry entry, string moniker)
 {
     lock (_errorSources) {
         _errorSources.Remove(new EntryKey(entry, moniker));
     }
 }
예제 #28
0
 public void DisconnectErrorList(IProjectEntry projEntry, ITextBuffer buffer) {
     _errorProvider.RemoveBufferForErrorSource(projEntry, ParserTaskMoniker, buffer);
     _commentTaskProvider.RemoveBufferForErrorSource(projEntry, ParserTaskMoniker, buffer);
 }
예제 #29
0
 public void RemoveModule(IProjectEntry entry) => RemoveModule(entry, null);
 private void DisconnectErrorList(IProjectEntry projEntry, ITextBuffer buffer) {
     TaskProvider.RemoveBufferForErrorSource(projEntry, ParserTaskMoniker, buffer);
 }
예제 #31
0
 public void ClearDiagnostics(IProjectEntry entry)
 {
     lock (_diagnostics) {
         _diagnostics.Remove(entry);
     }
 }
예제 #32
0
 public MonitoredBufferResult(BufferParser bufferParser, ITextView textView, IProjectEntry projectEntry) {
     BufferParser = bufferParser;
     TextView = textView;
     ProjectEntry = projectEntry;
 }
예제 #33
0
 public IProjectEntry GetOrAddEntry(Uri documentUri, IProjectEntry entry) => _projectFiles.GetOrAdd(documentUri, entry);
예제 #34
0
 public EntryEventArgs(IProjectEntry entry) {
     Entry = entry;
 }
예제 #35
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;

            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)
                {
                    IGeneroProject tempProj;
                    IProjectEntry  tempProjEntry;
                    if (ast != null)
                    {
                        IAnalysisResult tempRes = res.GetMember(dotPiece, ast, out tempProj, out tempProjEntry, lookForFunctions);
                        if (tempProj != null && definingProject != tempProj)
                        {
                            definingProject = tempProj;
                        }
                        if (tempProjEntry != null && projectEntry != tempProjEntry)
                        {
                            projectEntry = tempProjEntry;
                        }
                        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)
                    {
                        if (!lookForFunctions)
                        {
                            // Check for local vars, types, and constants
                            IFunctionResult func = containingNode as IFunctionResult;
                            if ((getVariables && func.Variables.TryGetValue(dotPiece, out res)) ||
                                (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)
                        {
                            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.GetFileName(x.Directory);
                                return(fn?.Equals(dotPiece, StringComparison.OrdinalIgnoreCase) ?? false);
                            });
                            if (refProjKVP is IAnalysisResult)
                            {
                                definingProject = refProjKVP;
                                res             = refProjKVP as IAnalysisResult;
                                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);
        }
예제 #36
0
        private AP.CompletionsResponse GetNormalCompletions(IProjectEntry projectEntry, AP.CompletionsRequest request) {
            int version;
            var code = projectEntry.GetCurrentCode(request.bufferId, out version);

            if (IsSpaceCompletion(code, request.location) && !request.forceCompletions) {
                return new AP.CompletionsResponse() {
                    completions = new AP.Completion[0]
                };
            }

            var analysis = ((IPythonProjectEntry)projectEntry).Analysis;
            if (analysis != null) {
                var members = analysis.GetMembers(
                    request.text,
                    new SourceLocation(
                        request.location,
                        1,
                        request.column
                    ),
                    request.options
                );

                return new AP.CompletionsResponse() {
                    completions = ToCompletions(members.ToArray(), request.options)
                };
            }
            return new AP.CompletionsResponse() {
                completions = Array.Empty<AP.Completion>()
            };
        }
예제 #37
0
        public Genero4glAst(AstNode4gl body, int[] lineLocations, GeneroLanguageVersion langVersion = GeneroLanguageVersion.None, IProjectEntry projEntry = null, string filename = null)
            : base(body, lineLocations, langVersion, projEntry, filename)
        {
            ReloadContextMap();
            InitializeBuiltins();
            InitializeImportedPackages();   // for this instance
            InitializePackages();

            if (body is ModuleNode)
            {
                foreach (var import in (body as ModuleNode).CExtensionImports)
                {
                    if (_importedPackages.ContainsKey(import))
                    {
                        _importedPackages[import] = true;
                    }
                }
            }
        }
예제 #38
0
        public void EnqueueZipArchiveEntry(IProjectEntry projEntry, string zipFileName, ZipArchiveEntry entry, Action onComplete) {
            var pathInArchive = entry.FullName.Replace('/', '\\');
            var fileName = Path.Combine(zipFileName, pathInArchive);
            EnqueWorker(() => {
                try {
                    using (var stream = entry.Open()) {
                        ParseFile(
                            projEntry,
                            new Dictionary<int, CodeInfo> {
                                { 0, new StreamCodeInfo(0, stream) }
                            }
                        );
                        return;
                    }
                } catch (IOException ex) {
                    Debug.Fail(ex.Message);
                } catch (InvalidDataException ex) {
                    Debug.Fail(ex.Message);
                } finally {
                    onComplete();
                }

                IPythonProjectEntry pyEntry = projEntry as IPythonProjectEntry;
                if (pyEntry != null) {
                    // failed to parse, keep the UpdateTree calls balanced
                    pyEntry.UpdateTree(null, null);
                }
            });
        }
예제 #39
0
        /// <summary>
        /// Evaluates the given expression in at the provided line number and returns the values
        /// that the expression can evaluate to.
        /// </summary>
        /// <param name="exprText">The expression to determine the result of.</param>
        /// <param name="index">The 0-based absolute index into the file where the expression should be evaluated within the module.</param>
        public override IAnalysisResult GetValueByIndex(string exprText, int index, IFunctionInformationProvider functionProvider,
                                                        IDatabaseInformationProvider databaseProvider, IProgramFileProvider programFileProvider,
                                                        bool isFunctionCallOrDefinition, out bool isDeferred,
                                                        out IGeneroProject definingProject, out IProjectEntry projectEntry,
                                                        FunctionProviderSearchMode searchInFunctionProvider = FunctionProviderSearchMode.NoSearch)
        {
            _functionProvider    = functionProvider;
            _databaseProvider    = databaseProvider;
            _programFileProvider = programFileProvider;

            return(GetValueByIndex(exprText, index, this, out definingProject, out projectEntry, out isDeferred,
                                   searchInFunctionProvider,
                                   isFunctionCallOrDefinition));
        }
예제 #40
0
 internal void UpdateProjectEntry(IProjectEntry newEntry) {
     if (newEntry is IPythonProjectEntry) {
         _projectEntry.OnNewParseTree -= ParserOnNewParseTree;
         _projectEntry = (IPythonProjectEntry)newEntry;
         _projectEntry.OnNewParseTree += ParserOnNewParseTree;
     }
 }
예제 #41
0
        public LocationInfo ResolveLocation(IProjectEntry project, object location)
        {
            SourceLocation loc = (SourceLocation)location;

            return(new LocationInfo(project, loc.Line, loc.Column));
        }
예제 #42
0
        private static CurrentCode GetCurrentCode(IProjectEntry entry, int buffer) {
            object dictTmp;
            SortedDictionary<int, CurrentCode> dict;
            if (!entry.Properties.TryGetValue(_currentCodeKey, out dictTmp)) {
                entry.Properties[_currentCodeKey] = dict = new SortedDictionary<int, CurrentCode>();
            } else {
                dict = (SortedDictionary<int, CurrentCode>)dictTmp;
            }

            CurrentCode curCode;
            if (!dict.TryGetValue(buffer, out curCode)) {
                curCode = dict[buffer] = new CurrentCode();
            }

            return curCode;
        }
예제 #43
0
 public bool AddTypes(AnalysisUnit unit, IAnalysisSet newTypes, bool enqueue = true, IProjectEntry declaringScope = null)
 {
     return(AddTypes(unit.DependencyProject, newTypes, enqueue, declaringScope));
 }
예제 #44
0
        internal void UnloadFile(IProjectEntry entry) {
            if (_pyAnalyzer == null) {
                // We aren't able to analyze code.
                return;
            }

            if (entry != null) {
                // If we remove a Python module, reanalyze any other modules
                // that referenced it.
                IPythonProjectEntry[] reanalyzeEntries = null;
                var pyEntry = entry as IPythonProjectEntry;
                if (pyEntry != null && !string.IsNullOrEmpty(pyEntry.ModuleName)) {
                    reanalyzeEntries = _pyAnalyzer.GetEntriesThatImportModule(pyEntry.ModuleName, false).ToArray();
                }

                ClearParserTasks(entry);
                _pyAnalyzer.RemoveModule(entry);
                IProjectEntry removed;
                _projectFiles.TryRemove(entry.FilePath, out removed);

                if (reanalyzeEntries != null) {
                    foreach (var existing in reanalyzeEntries) {
                        _analysisQueue.Enqueue(existing, AnalysisPriority.Normal);
                    }
                }
            }
        }
예제 #45
0
        internal void ParseFile(IProjectEntry entry, string filename, Stream content, Severity indentationSeverity) {
            IPythonProjectEntry pyEntry;
            IExternalProjectEntry externalEntry;

            TextReader reader = null;
            ITextSnapshot snapshot = GetOpenSnapshot(entry);
            string zipFileName = GetZipFileName(entry);
            string pathInZipFile = GetPathInZipFile(entry);
            IAnalysisCookie cookie;
            if (snapshot != null) {
                cookie = new SnapshotCookie(snapshot);
                reader = new SnapshotSpanSourceCodeReader(new SnapshotSpan(snapshot, 0, snapshot.Length));
            } else if (zipFileName != null) {
                cookie = new ZipFileCookie(zipFileName, pathInZipFile);
            } else {
                cookie = new FileCookie(filename);
            }

            if ((pyEntry = entry as IPythonProjectEntry) != null) {
                PythonAst ast;
                CollectingErrorSink errorSink;
                List<TaskProviderItem> commentTasks;
                if (reader != null) {
                    ParsePythonCode(snapshot, reader, indentationSeverity, out ast, out errorSink, out commentTasks);
                } else {
                    ParsePythonCode(snapshot, content, indentationSeverity, out ast, out errorSink, out commentTasks);
                }

                if (ast != null) {
                    pyEntry.UpdateTree(ast, cookie);
                } else {
                    // notify that we failed to update the existing analysis
                    pyEntry.UpdateTree(null, null);
                }

                // update squiggles for the buffer. snapshot may be null if we
                // are analyzing a file that is not open
                UpdateErrorsAndWarnings(entry, snapshot, errorSink, commentTasks);

                // enqueue analysis of the file
                if (ast != null) {
                    _analysisQueue.Enqueue(pyEntry, AnalysisPriority.Normal);
                }
            } else if ((externalEntry = entry as IExternalProjectEntry) != null) {
                externalEntry.ParseContent(reader ?? new StreamReader(content), cookie);
                _analysisQueue.Enqueue(entry, AnalysisPriority.Normal);
            }
        }
예제 #46
0
 internal bool ShouldWarnOnLaunch(IProjectEntry entry) {
     lock (_hasParseErrorsLock) {
         return _hasParseErrors.Contains(entry);
     }
 }
예제 #47
0
 public IAnalysisResult GetMember(string name, Genero4glAst ast, out IGeneroProject definingProject, out IProjectEntry projEntry, bool function)
 {
     definingProject = null;
     projEntry       = null;
     if (_returns != null && _returns.Count == 1)
     {
         var typeRef = new TypeReference(_returns[0]);
         return(typeRef.GetMember(name, ast, out definingProject, out projEntry, function));
     }
     return(null);
 }
예제 #48
0
 private static void SetZipFileName(IProjectEntry entry, string value) {
     entry.Properties[_zipFileName] = value;
 }
예제 #49
0
        public static IEnumerable <TestCaseInfo> GetTestCasesFromAnalysis(IProjectEntry projEntry)
        {
            var entry = projEntry as IPythonProjectEntry;

            if (entry == null)
            {
                yield break;
            }
            var analysis = entry.Analysis;

            if (analysis == null || !entry.IsAnalyzed)
            {
                yield break;
            }

            // GetTestCaseMembers may return duplicates, so we filter in
            // this function.
            var seen = new Dictionary <string, int>();

            foreach (var classValue in GetTestCaseClasses(analysis))
            {
                // Check the name of all functions on the class using the
                // analyzer. This will return functions defined on this
                // class and base classes
                foreach (var member in GetTestCaseMembers(entry.Tree, entry.FilePath, entry.DocumentUri, analysis, classValue))
                {
                    var name = $"{classValue.Name}.{member.Key}";
                    // Find the definition to get the real location of the
                    // member. Otherwise decorators will confuse us.
                    var definition = entry.Analysis
                                     .GetVariables(name, SourceLocation.MinValue)
                                     .FirstOrDefault(v => v.Type == VariableType.Definition);

                    var location = definition?.Location ?? member.Value;

                    int endLine = location?.EndLine ?? location?.StartLine ?? 0;

                    int startLine = location?.StartLine ?? 0;
                    if (seen.TryGetValue(name, out int existingStartLine))
                    {
                        // Same name and same line is obviously the same
                        // test. Within one line probably means that the
                        // decorator was miscalculated, and it's best to
                        // skip it anyway. (There isn't a style guide on
                        // earth that encourages using distinct single-line
                        // tests with the same name adjacent to each other,
                        // so this should have no false positives.)
                        if (Math.Abs(startLine - existingStartLine) <= 1)
                        {
                            continue;
                        }
                    }
                    else
                    {
                        seen[name] = startLine;
                    }

                    yield return(new TestCaseInfo(
                                     classValue.DeclaringModule?.FilePath,
                                     classValue.Name,
                                     member.Key,
                                     location?.StartLine ?? 0,
                                     location?.StartColumn ?? 1,
                                     endLine
                                     ));
                }
            }
        }
예제 #50
0
 private static void SetPathInZipFile(IProjectEntry entry, string value) {
     entry.Properties[_pathInZipFile] = value;
 }
예제 #51
0
 internal static bool TryGetProjectEntry(this ITextBuffer buffer, out IProjectEntry entry)
 {
     return(buffer.Properties.TryGetProperty <IProjectEntry>(typeof(IProjectEntry), out entry));
 }
예제 #52
0
        internal ITextSnapshot GetOpenSnapshot(IProjectEntry entry) {
            if (entry == null) {
                return null;
            }

            lock (_openFiles) {
                var item = _openFiles.FirstOrDefault(kv => kv.Value == entry);
                if (item.Value == null) {
                    return null;
                }
                var document = item.Key.Document;
                if (document == null) {
                    return null;
                }

                var textBuffer = document.TextBuffer;
                // TextBuffer may be null if we are racing with file close
                return textBuffer != null ? textBuffer.CurrentSnapshot : null;
            }
        }
예제 #53
0
 public ReferenceList(IProjectEntry project)
 {
     Version    = project.AnalysisVersion;
     Project    = project.FilePath;
     References = new HashSet <EncodedLocation>();
 }
예제 #54
0
        private void UpdateErrorsAndWarnings(
            IProjectEntry entry,
            ITextSnapshot snapshot,
            CollectingErrorSink errorSink,
            List<TaskProviderItem> commentTasks
        ) {
            // Update the warn-on-launch state for this entry
            bool changed = false;
            lock (_hasParseErrorsLock) {
                changed = errorSink.Errors.Any() ? _hasParseErrors.Add(entry) : _hasParseErrors.Remove(entry);
            }
            if (changed) {
                OnShouldWarnOnLaunchChanged(entry);
            }
            
            // Update the parser warnings/errors.
            var factory = new TaskProviderItemFactory(snapshot);
            if (errorSink.Warnings.Any() || errorSink.Errors.Any()) {
                _errorProvider.ReplaceItems(
                    entry,
                    ParserTaskMoniker,
                    errorSink.Warnings
                        .Select(er => factory.FromErrorResult(_serviceProvider, er, VSTASKPRIORITY.TP_NORMAL, VSTASKCATEGORY.CAT_BUILDCOMPILE))
                        .Concat(errorSink.Errors.Select(er => factory.FromErrorResult(_serviceProvider, er, VSTASKPRIORITY.TP_HIGH, VSTASKCATEGORY.CAT_BUILDCOMPILE)))
                        .ToList()
                );
            } else {
                _errorProvider.Clear(entry, ParserTaskMoniker);
            }

            // Update comment tasks.
            if (commentTasks.Count != 0) {
                _commentTaskProvider.ReplaceItems(entry, ParserTaskMoniker, commentTasks);
            } else {
                _commentTaskProvider.Clear(entry, ParserTaskMoniker);
            }
        }
예제 #55
0
 public IAnalysisResult GetMember(string name, Genero4glAst ast, out IGeneroProject definingProject, out IProjectEntry projEntry, bool function)
 {
     definingProject = null;
     projEntry       = null;
     if (Children.Count == 1 &&
         Children[Children.Keys[0]] is TypeReference)
     {
         return((Children[Children.Keys[0]] as TypeReference).GetMember(name, ast, out definingProject, out projEntry, function));
     }
     return(null);
 }