public LocationPreviewItem(VsProjectAnalyzer analyzer, FilePreviewItem parent, AnalysisLocation locationInfo, VariableType type) { _lineNo = locationInfo.Line; _columnNo = locationInfo.Column; _parent = parent; var analysis = analyzer.GetAnalysisEntryFromPath(locationInfo.FilePath); _type = type; if (analysis != null) { string text = analysis.GetLine(locationInfo.Line); string trimmed = text.TrimStart(_whitespace); _text = trimmed; _span = new Span(_columnNo - (text.Length - trimmed.Length) - 1, parent.Engine.OriginalName.Length); if (String.Compare(_text, _span.Start, parent.Engine.OriginalName, 0, parent.Engine.OriginalName.Length) != 0) { // we are renaming a name mangled name (or we have a bug where the names aren't lining up). Debug.Assert(_text.Substring(_span.Start, _span.Length + 1 + parent.Engine.PrivatePrefix.Length) == "_" + parent.Engine.PrivatePrefix + parent.Engine.OriginalName); if (parent.Engine.Request.Name.StartsWith("__")) { // if we're renaming to a private prefix name then we just rename the non-prefixed portion _span = new Span(_span.Start + 1 + parent.Engine.PrivatePrefix.Length, _span.Length); _columnNo += 1 + parent.Engine.PrivatePrefix.Length; } else { // otherwise we renmae the prefixed and non-prefixed portion _span = new Span(_span.Start, _span.Length + 1 + parent.Engine.PrivatePrefix.Length); } } } else { _text = String.Empty; } }
internal ExpressionAnalysis(VsProjectAnalyzer analyzer, string expression, ModuleAnalysis analysis, int index, ITrackingSpan span, ITextSnapshot snapshot) { _expr = expression; _analysis = analysis; _index = index; _span = span; _analyzer = analyzer; _snapshot = snapshot; }
private async Task AnalyzeReferenceAsync(VsProjectAnalyzer interp) { if (interp != null) { _failedToAnalyze = false; var resp = await interp.AddReferenceAsync(new ProjectAssemblyReference(AssemblyName, Url)); if (resp == null) { _failedToAnalyze = true; } } }
public static async Task<BufferParser> CreateAsync(AnalysisEntry analysis, VsProjectAnalyzer parser, ITextBuffer buffer) { var res = new BufferParser(analysis, parser, buffer); using (new DebugTimer("BufferParser.ParseBuffers", 100)) { // lock not necessary for _bufferInfo, no one has access to us yet... await res.ParseBuffers(new[] { buffer.CurrentSnapshot }, new[] { res._bufferInfo[buffer] }); } return res; }
public PreviewChangesEngine(IServiceProvider serviceProvider, IRenameVariableInput input, string expr, RenameVariableRequest request, string originalName, string privatePrefix, VsProjectAnalyzer analyzer, IEnumerable<AnalysisVariable> variables) { _serviceProvider = serviceProvider; _expr = expr; _analyzer = analyzer; _renameReq = request; _originalName = originalName; _privatePrefix = privatePrefix; _variables = variables; _input = input; _list = new PreviewList(CreatePreviewItems().ToArray()); }
private BufferParser(AnalysisEntry analysis, VsProjectAnalyzer parser, ITextBuffer buffer) { Debug.Assert(analysis != null); _parser = parser; _timer = new Timer(ReparseTimer, null, Timeout.Infinite, Timeout.Infinite); _buffers = new[] { buffer }; AnalysisEntry = analysis; analysis.BufferParser = this; InitBuffer(buffer, 0); }
public void AnalyzeBadEgg() { var factories = new[] { InterpreterFactoryCreator.CreateAnalysisInterpreterFactory(new Version(3, 4)) }; using (var analyzer = new VsProjectAnalyzer(PythonToolsTestUtilities.CreateMockServiceProvider(), factories[0])) { analyzer.AnalyzeZipArchiveAsync(TestData.GetPath(@"TestData\BadEgg.egg")).Wait(); analyzer.WaitForCompleteAnalysis(_ => true); // Analysis result must contain the module for the filename inside the egg that is a valid identifier, // and no entries for the other filename which is not. var moduleNames = analyzer.GetModulesResult(true).Result.Select(x => x.Name); AssertUtil.Contains(moduleNames, "module"); AssertUtil.DoesntContain(moduleNames, "42"); } }
public BufferParser(AnalysisEntry analysis, VsProjectAnalyzer parser, ITextBuffer buffer) { Debug.Assert(analysis != null); _parser = parser; _timer = new Timer(ReparseTimer, null, Timeout.Infinite, Timeout.Infinite); _buffers = new[] { buffer }; AnalysisEntry = analysis; analysis.BufferParser = this; InitBuffer(buffer, 0); // lock not necessary for _bufferInfo, no one has access to us yet... ParseBuffers(new[] { buffer.CurrentSnapshot }, new[] { _bufferInfo[buffer] }).DoNotWait(); }
public ProjectBlockCompletionContext(VsProjectAnalyzer analyzer, ITextBuffer buffer) : base(analyzer, buffer.GetFileName()) { var doc = HtmlEditorDocument.FromTextBuffer(buffer); if (doc == null) { return; } var artifacts = doc.HtmlEditorTree.ArtifactCollection; foreach (var artifact in artifacts.OfType<TemplateBlockArtifact>()) { var artifactText = doc.HtmlEditorTree.ParseTree.Text.GetText(artifact.InnerRange); artifact.Parse(artifactText); if (artifact.Block != null) { var varNames = artifact.Block.GetVariables(); foreach (var varName in varNames) { AddLoopVariable(varName); } } } }
internal AnalysisQueue(VsProjectAnalyzer analyzer) { _workEvent = new AutoResetEvent(false); _cancel = new CancellationTokenSource(); _analyzer = analyzer; _queue = new List<IAnalyzable>[PriorityCount]; for (int i = 0; i < PriorityCount; i++) { _queue[i] = new List<IAnalyzable>(); } _workThread = new Thread(Worker); _workThread.Name = "Python Analysis Queue"; _workThread.Priority = ThreadPriority.BelowNormal; _workThread.IsBackground = true; // start the thread, wait for our synchronization context to be created using (AutoResetEvent threadStarted = new AutoResetEvent(false)) { _workThread.Start(threadStarted); threadStarted.WaitOne(); } }
protected override void Connect() { _serviceProvider.GetUIThread().MustBeCalledFromUIThread(); var configurableOptions = CurrentOptions as ConfigurablePythonReplOptions; if (configurableOptions != null) { _interpreter = configurableOptions.InterpreterFactory ?? _interpreter; } if (Interpreter == null || Interpreter is UnavailableFactory) { Window.WriteError(Strings.ReplEvaluatorInterpreterNotFound); return; } else if (String.IsNullOrWhiteSpace(Interpreter.Configuration.InterpreterPath)) { Window.WriteError(Strings.ReplEvaluatorInterpreterNotConfigured.FormatUI(Interpreter.Description)); return; } var processInfo = new ProcessStartInfo(Interpreter.Configuration.InterpreterPath); #if DEBUG bool debugMode = Environment.GetEnvironmentVariable("DEBUG_REPL") != null; processInfo.CreateNoWindow = !debugMode; processInfo.UseShellExecute = debugMode; processInfo.RedirectStandardOutput = !debugMode; processInfo.RedirectStandardError = !debugMode; processInfo.RedirectStandardInput = !debugMode; #else processInfo.CreateNoWindow = true; processInfo.UseShellExecute = false; processInfo.RedirectStandardOutput = true; processInfo.RedirectStandardError = true; processInfo.RedirectStandardInput = true; #endif Socket conn; int portNum; CreateConnection(out conn, out portNum); List<string> args = new List<string>(); if (!String.IsNullOrWhiteSpace(CurrentOptions.InterpreterOptions)) { args.Add(CurrentOptions.InterpreterOptions); } var workingDir = CurrentOptions.WorkingDirectory; if (!string.IsNullOrEmpty(workingDir)) { processInfo.WorkingDirectory = workingDir; } else { processInfo.WorkingDirectory = Interpreter.Configuration.PrefixPath; } #if DEBUG if (!debugMode) { #endif var envVars = CurrentOptions.EnvironmentVariables; if (envVars != null) { foreach (var keyValue in envVars) { processInfo.EnvironmentVariables[keyValue.Key] = keyValue.Value; } } string pathEnvVar = Interpreter.Configuration.PathEnvironmentVariable ?? ""; if (!string.IsNullOrWhiteSpace(pathEnvVar)) { var searchPaths = CurrentOptions.SearchPaths; if (string.IsNullOrEmpty(searchPaths)) { if (_serviceProvider.GetPythonToolsService().GeneralOptions.ClearGlobalPythonPath) { processInfo.EnvironmentVariables[pathEnvVar] = ""; } } else if (_serviceProvider.GetPythonToolsService().GeneralOptions.ClearGlobalPythonPath) { processInfo.EnvironmentVariables[pathEnvVar] = searchPaths; } else { processInfo.EnvironmentVariables[pathEnvVar] = searchPaths + ";" + Environment.GetEnvironmentVariable(pathEnvVar); } } #if DEBUG } #endif var interpreterArgs = CurrentOptions.InterpreterArguments; if (!String.IsNullOrWhiteSpace(interpreterArgs)) { args.Add(interpreterArgs); } var analyzer = CurrentOptions.ProjectAnalyzer; if (analyzer != null && analyzer.InterpreterFactory == _interpreter) { if (_replAnalyzer != null && _replAnalyzer != analyzer) { analyzer.SwitchAnalyzers(_replAnalyzer); } _replAnalyzer = analyzer; _ownsAnalyzer = false; } args.Add(ProcessOutput.QuoteSingleArgument(PythonToolsInstallPath.GetFile("visualstudio_py_repl.py"))); args.Add("--port"); args.Add(portNum.ToString()); if (!String.IsNullOrWhiteSpace(CurrentOptions.StartupScript)) { args.Add("--launch_file"); args.Add(ProcessOutput.QuoteSingleArgument(CurrentOptions.StartupScript)); } _enableAttach = CurrentOptions.EnableAttach; if (CurrentOptions.EnableAttach) { args.Add("--enable-attach"); } bool multipleScopes = true; if (!String.IsNullOrWhiteSpace(CurrentOptions.ExecutionMode)) { // change ID to module name if we have a registered mode var modes = Microsoft.PythonTools.Options.ExecutionMode.GetRegisteredModes(_serviceProvider); string modeValue = CurrentOptions.ExecutionMode; foreach (var mode in modes) { if (mode.Id == CurrentOptions.ExecutionMode) { modeValue = mode.Type; multipleScopes = mode.SupportsMultipleScopes; _supportsMultipleCompleteStatementInputs = mode.SupportsMultipleCompleteStatementInputs; break; } } args.Add("--execution_mode"); args.Add(modeValue); } SetMultipleScopes(multipleScopes); processInfo.Arguments = String.Join(" ", args); var process = new Process(); process.StartInfo = processInfo; try { if (!File.Exists(processInfo.FileName)) { throw new Win32Exception(Microsoft.VisualStudioTools.Project.NativeMethods.ERROR_FILE_NOT_FOUND); } process.Start(); } catch (Exception e) { if (e.IsCriticalException()) { throw; } Win32Exception wex = e as Win32Exception; if (wex != null && wex.NativeErrorCode == Microsoft.VisualStudioTools.Project.NativeMethods.ERROR_FILE_NOT_FOUND) { Window.WriteError(Strings.ReplEvaluatorInterpreterNotFound); } else { Window.WriteError(Strings.ErrorStartingInteractiveProcess.FormatUI(e.ToString())); } return; } CreateCommandProcessor(conn, processInfo.RedirectStandardOutput, process); }
private void RemoveAnalyzedAssembly(VsProjectAnalyzer interp) { if (interp != null) { if (_curReference != null) { interp.RemoveReferenceAsync(_curReference).Wait(); _curReference = null; } } }
private void ExtractMethodTest(string input, Func<Span> extract, TestResult expected, string scopeName = null, string targetName = "g", Version version = null, params string[] parameters) { var fact = InterpreterFactoryCreator.CreateAnalysisInterpreterFactory(version ?? new Version(2, 7)); var serviceProvider = PythonToolsTestUtilities.CreateMockServiceProvider(); using (var analyzer = new VsProjectAnalyzer(serviceProvider, fact)) { var buffer = new MockTextBuffer(input, "Python", "C:\\fob.py"); var view = new MockTextView(buffer); buffer.AddProperty(typeof(VsProjectAnalyzer), analyzer); analyzer.MonitorTextBufferAsync(buffer).Wait(); var extractInput = new ExtractMethodTestInput(true, scopeName, targetName, parameters ?? new string[0]); view.Selection.Select( new SnapshotSpan(view.TextBuffer.CurrentSnapshot, extract()), false ); new MethodExtractor(serviceProvider, view).ExtractMethod(extractInput).Wait(); if (expected.IsError) { Assert.AreEqual(expected.Text, extractInput.FailureReason); Assert.AreEqual(input, view.TextBuffer.CurrentSnapshot.GetText()); } else { Assert.AreEqual(null, extractInput.FailureReason); Assert.AreEqual(expected.Text, view.TextBuffer.CurrentSnapshot.GetText()); } } }
public WaitForCompleteAnalysisDialog(VsProjectAnalyzer analyzer) { _analyzer = analyzer; InitializeComponent(); new Thread(AnalysisComplete).Start(); }
public PythonSignature(VsProjectAnalyzer analyzer, ITrackingSpan span, AP.Signature overload, int paramIndex, string lastKeywordArg = null) { _span = span; _overload = overload; if (lastKeywordArg != null) { paramIndex = Int32.MaxValue; } var content = new StringBuilder(overload.name); var ppContent = new StringBuilder(overload.name); content.Append('('); ppContent.AppendLine("("); int start = content.Length, ppStart = ppContent.Length; var parameters = new IParameter[overload.parameters.Length]; for (int i = 0; i < overload.parameters.Length; i++) { ppContent.Append(" "); ppStart = ppContent.Length; var param = overload.parameters[i]; if (param.optional) { content.Append('['); ppContent.Append('['); } if (i > 0) { content.Append(", "); start = content.Length; } content.Append(param.name); ppContent.Append(param.name); if (!string.IsNullOrEmpty(param.type) && param.type != "object") { content.Append(": "); content.Append(param.type); ppContent.Append(": "); ppContent.Append(param.type); } if (!String.IsNullOrWhiteSpace(param.defaultValue)) { content.Append(" = "); content.Append(param.defaultValue); ppContent.Append(" = "); ppContent.Append(param.defaultValue); } var paramSpan = new Span(start, content.Length - start); var ppParamSpan = new Span(ppStart, ppContent.Length - ppStart); if (param.optional) { content.Append(']'); ppContent.Append(']'); } ppContent.AppendLine(","); if (lastKeywordArg != null && param.name == lastKeywordArg) { paramIndex = i; } parameters[i] = new PythonParameter( this, param, paramSpan, ppParamSpan, param.variables != null ? param.variables.Select(analyzer.ToAnalysisVariable).ToArray() : null ); } content.Append(')'); ppContent.Append(')'); _content = content.ToString(); _ppContent = ppContent.ToString(); _documentation = overload.doc.LimitLines(15, stopAtFirstBlankLine: true); _parameters = new ReadOnlyCollection<IParameter>(parameters); if (lastKeywordArg == null) { for (int i = 0; i < parameters.Length; ++i) { if (i == paramIndex || IsParamArray(parameters[i].Name)) { _currentParameter = parameters[i]; break; } } } else if (paramIndex < parameters.Length) { _currentParameter = parameters[paramIndex]; } }
internal static bool TryGetStartupFileAndDirectory(System.IServiceProvider serviceProvider, out string filename, out string dir, out VsProjectAnalyzer analyzer) { var startupProject = GetStartupProject(serviceProvider); if (startupProject != null) { filename = startupProject.GetStartupFile(); dir = startupProject.GetWorkingDirectory(); analyzer = ((PythonProjectNode)startupProject).GetAnalyzer(); } else { var textView = CommonPackage.GetActiveTextView(serviceProvider); if (textView == null) { filename = null; dir = null; analyzer = null; return false; } filename = textView.GetFilePath(); analyzer = textView.GetAnalyzer(serviceProvider); dir = Path.GetDirectoryName(filename); } return true; }
public void GenericMethodCompletions() { // http://pytools.codeplex.com/workitem/661 var fact = IronPythonInterpreter; var replEval = new PythonReplEvaluator(fact, PythonToolsTestUtilities.CreateMockServiceProvider(), new ReplTestReplOptions()); var replWindow = new MockReplWindow(replEval); replEval._Initialize(replWindow).Wait(); var execute = replEval.ExecuteText("from System.Threading.Tasks import Task"); execute.Wait(); Assert.IsTrue(execute.Result.IsSuccessful); replWindow.ClearScreen(); execute = replEval.ExecuteText("def func1(): print 'hello world'\r\n\r\n"); execute.Wait(); replWindow.ClearScreen(); Assert.IsTrue(execute.Result.IsSuccessful); execute = replEval.ExecuteText("t = Task.Factory.StartNew(func1)"); execute.Wait(); Assert.IsTrue(execute.Result.IsSuccessful); using (var analyzer = new VsProjectAnalyzer(PythonToolsTestUtilities.CreateMockServiceProvider(), fact, new[] { fact })) { replWindow.TextView.TextBuffer.Properties.AddProperty(typeof(VsProjectAnalyzer), analyzer); MemberResult[] names = null; for (int retries = 0; retries < 5 && names == null; retries += 1) { names = replEval.GetMemberNames("t"); } Assert.IsNotNull(names, "GetMemberNames call timed out"); foreach (var name in names) { Debug.WriteLine(name.Name); } } }
internal NormalCompletionAnalysis(VsProjectAnalyzer analyzer, ICompletionSession session, ITextView view, ITextSnapshot snapshot, ITrackingSpan span, ITextBuffer textBuffer, CompletionOptions options, IServiceProvider serviceProvider) : base(analyzer._serviceProvider, session, view, span, textBuffer, options) { _snapshot = snapshot; _analyzer = analyzer; _serviceProvider = serviceProvider; }
private static void CodeFormattingTest(string input, object selection, string expected, object expectedSelection, CodeFormattingOptions options, bool selectResult = true) { var fact = InterpreterFactoryCreator.CreateAnalysisInterpreterFactory(new Version(2, 7)); var serviceProvider = PythonToolsTestUtilities.CreateMockServiceProvider(); using (var analyzer = new VsProjectAnalyzer(serviceProvider, fact, new[] { fact })) { var buffer = new MockTextBuffer(input, PythonCoreConstants.ContentType, "C:\\fob.py"); buffer.AddProperty(typeof(VsProjectAnalyzer), analyzer); var view = new MockTextView(buffer); var selectionSpan = new SnapshotSpan( buffer.CurrentSnapshot, ExtractMethodTests.GetSelectionSpan(input, selection) ); view.Selection.Select(selectionSpan, false); new CodeFormatter(serviceProvider, view, options).FormatCode( selectionSpan, selectResult ); Assert.AreEqual(expected, view.TextBuffer.CurrentSnapshot.GetText()); if (expectedSelection != null) { Assert.AreEqual( ExtractMethodTests.GetSelectionSpan(expected, expectedSelection), view.Selection.StreamSelectionSpan.SnapshotSpan.Span ); } } }
internal async Task AddAnalyzedAssembly(VsProjectAnalyzer interp) { if (interp != null) { var asmName = AssemblyName; string outFile; try { outFile = ReferencedProjectOutputPath; } catch (COMException) { _failedToAnalyze = true; return; } _failedToAnalyze = false; _curReference = null; if (!string.IsNullOrEmpty(asmName)) { _asmName = new AssemblyName(asmName); _curReference = new ProjectAssemblyReference(_asmName, ReferencedProjectOutputPath); } else if (File.Exists(outFile)) { _asmName = null; _curReference = new ProjectReference(outFile, ProjectReferenceKind.ExtensionModule); } else { if (ReferencedProjectObject == null || !Utilities.GuidEquals(PythonConstants.ProjectFactoryGuid, ReferencedProjectObject.Kind)) { // Only failed if the reference isn't to another Python // project. _failedToAnalyze = true; } } if (_curReference != null) { try { await interp.AddReferenceAsync(_curReference); } catch (Exception) { _failedToAnalyze = true; } } } }
private static void RegisterExtension(VsProjectAnalyzer newAnalyzer) { newAnalyzer.RegisterExtension(typeof(DjangoAnalyzer).Assembly.CodeBase); }
public AddZipArchiveAnalysis(string zipFileName, Action<IProjectEntry> onFileAnalyzed, VsProjectAnalyzer analyzer) { _zipFileName = zipFileName; _onFileAnalyzed = onFileAnalyzed; _analyzer = analyzer; }
internal static IVsInteractiveWindow/*!*/ EnsureReplWindow(IServiceProvider serviceProvider, VsProjectAnalyzer analyzer, PythonProjectNode project) { return EnsureReplWindow(serviceProvider, analyzer.InterpreterFactory, project); }
public override void Dispose() { if (_ownsAnalyzer && _replAnalyzer != null) { _replAnalyzer.Dispose(); _replAnalyzer = null; } base.Dispose(); }
public AnalyzerChangingEventArgs(VsProjectAnalyzer oldAnalyzer, VsProjectAnalyzer newAnalyzer) { _old = oldAnalyzer; _new = newAnalyzer; }
public PythonEditor( string content = null, PythonLanguageVersion version = PythonLanguageVersion.V27, MockVs vs = null, IPythonInterpreterFactory factory = null, VsProjectAnalyzer analyzer = null, string filename = null ) { if (vs == null) { _disposeVS = true; vs = new MockVs(); } MockVsTextView view = null; try { AdvancedOptions = vs.GetPyService().AdvancedOptions; AdvancedOptions.AutoListMembers = true; AdvancedOptions.AutoListIdentifiers = false; if (factory == null) { _disposeFactory = true; factory = InterpreterFactoryCreator.CreateAnalysisInterpreterFactory(version.ToVersion()); } if (analyzer == null) { _disposeAnalyzer = true; analyzer = new VsProjectAnalyzer(vs.ServiceProvider, factory); var task = analyzer.ReloadTask; if (task != null) { task.WaitAndUnwrapExceptions(); } } var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30)); using (var mre = new ManualResetEventSlim()) { EventHandler evt = (s, e) => mre.Set(); analyzer.AnalysisStarted += evt; view = vs.CreateTextView(PythonCoreConstants.ContentType, content ?? "", v => { v.TextView.TextBuffer.Properties.AddProperty(typeof(VsProjectAnalyzer), analyzer); }, filename); try { mre.Wait(cts.Token); analyzer.WaitForCompleteAnalysis(x => !cts.IsCancellationRequested); } catch (OperationCanceledException) { } finally { analyzer.AnalysisStarted -= evt; } if (cts.IsCancellationRequested) { Assert.Fail("Timed out waiting for code analysis"); } } View = view; view = null; Analyzer = analyzer; analyzer = null; Factory = factory; factory = null; VS = vs; vs = null; } finally { if (view != null) { view.Dispose(); } if (analyzer != null && _disposeAnalyzer) { analyzer.Dispose(); } if (factory != null && _disposeFactory) { var disp = factory as IDisposable; if (disp != null) { disp.Dispose(); } } if (vs != null && _disposeVS) { vs.Dispose(); } } }
public AddDirectoryAnalysis(string dir, Action<IProjectEntry> onFileAnalyzed, VsProjectAnalyzer analyzer) { _dir = dir; _onFileAnalyzed = onFileAnalyzed; _analyzer = analyzer; }
async void InterpretersChanged(object sender, EventArgs e) { var current = _interpreter; if (current == null) { return; } var interpreter = _interpreterService.FindInterpreter(current.Id, current.Configuration.Version); if (interpreter != null && interpreter != current) { // the interpreter has been reconfigured, we want the new settings _interpreter = interpreter; if (_replAnalyzer != null) { var oldAnalyser = _replAnalyzer; bool disposeOld = _ownsAnalyzer && oldAnalyser != null; _replAnalyzer = null; var newAnalyzer = ReplAnalyzer; if (newAnalyzer != null && oldAnalyser != null) { newAnalyzer.SwitchAnalyzers(oldAnalyser); } if (disposeOld) { oldAnalyser.Dispose(); } } // if the previous interpreter was not available, we will want // to reset afterwards if (current is UnavailableFactory) { await Reset(); } } }
internal void SwitchAnalyzers(VsProjectAnalyzer oldAnalyzer) { lock (_openFiles) { // copy the Keys here as ReAnalyzeTextBuffers can mutuate the dictionary foreach (var bufferParser in oldAnalyzer._openFiles.Keys.ToArray()) { ReAnalyzeTextBuffers(bufferParser); } } }
public void LoadAndUnloadModule() { var factories = new[] { InterpreterFactoryCreator.CreateAnalysisInterpreterFactory(new Version(3, 3)) }; using (var analyzer = new VsProjectAnalyzer(PythonToolsTestUtilities.CreateMockServiceProvider(), factories[0], factories)) { var m1Path = TestData.GetPath("TestData\\SimpleImport\\module1.py"); var m2Path = TestData.GetPath("TestData\\SimpleImport\\module2.py"); var entry1 = analyzer.AnalyzeFile(m1Path) as IPythonProjectEntry; var entry2 = analyzer.AnalyzeFile(m2Path) as IPythonProjectEntry; analyzer.WaitForCompleteAnalysis(_ => true); AssertUtil.ContainsExactly( analyzer.Project.GetEntriesThatImportModule("module1", true).Select(m => m.ModuleName), "module2" ); AssertUtil.ContainsExactly( entry2.Analysis.GetValuesByIndex("x", 0).Select(v => v.TypeId), BuiltinTypeId.Int ); analyzer.UnloadFile(entry1); analyzer.WaitForCompleteAnalysis(_ => true); // Even though module1 has been unloaded, we still know that // module2 imports it. AssertUtil.ContainsExactly( analyzer.Project.GetEntriesThatImportModule("module1", true).Select(m => m.ModuleName), "module2" ); AssertUtil.ContainsExactly( entry2.Analysis.GetValuesByIndex("x", 0).Select(v => v.TypeId) ); analyzer.AnalyzeFile(m1Path); analyzer.WaitForCompleteAnalysis(_ => true); AssertUtil.ContainsExactly( analyzer.Project.GetEntriesThatImportModule("module1", true).Select(m => m.ModuleName), "module2" ); AssertUtil.ContainsExactly( entry2.Analysis.GetValuesByIndex("x", 0).Select(v => v.TypeId), BuiltinTypeId.Int ); } }