提交 95fc0080 编写于 作者: H Heejae Chang

changed bing search to use bing dev search

上级 85caf941
......@@ -6,6 +6,8 @@ namespace Microsoft.CodeAnalysis.Editor.Host
{
internal interface IPreviewPaneService : IWorkspaceService
{
object GetPreviewPane(Diagnostic diagnostic, object previewContent);
// TODO: we should move this API to use DiagnosticData not Diagnostic. but it required too much changes so for now,
// I created an issue https://github.com/dotnet/roslyn/issues/3111 and making this API to accept bunch of extra information.
object GetPreviewPane(Diagnostic diagnostic, string language, string projectType, object previewContent);
}
}
......@@ -7,6 +7,7 @@
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.Editor.Host;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.Extensions;
using Microsoft.CodeAnalysis.Text;
......@@ -163,6 +164,9 @@ public virtual async Task<object> GetPreviewAsync(CancellationToken cancellation
// Light bulb will always invoke this function on the UI thread.
AssertIsForeground();
var preferredDocumentId = Workspace.GetDocumentIdInCurrentContext(SubjectBuffer.AsTextContainer());
var preferredProjectid = preferredDocumentId == null ? null : preferredDocumentId.ProjectId;
var extensionManager = this.Workspace.Services.GetService<IExtensionManager>();
var previewContent = await extensionManager.PerformFunctionAsync(Provider, async () =>
{
......@@ -175,9 +179,6 @@ public virtual async Task<object> GetPreviewAsync(CancellationToken cancellation
}
else
{
var preferredDocumentId = Workspace.GetDocumentIdInCurrentContext(SubjectBuffer.AsTextContainer());
var preferredProjectid = preferredDocumentId == null ? null : preferredDocumentId.ProjectId;
// TakeNextPreviewAsync() needs to run on UI thread.
AssertIsForeground();
return await previewResult.TakeNextPreviewAsync(preferredDocumentId, preferredProjectid, cancellationToken).ConfigureAwait(true);
......@@ -196,7 +197,12 @@ public virtual async Task<object> GetPreviewAsync(CancellationToken cancellation
// GetPreviewPane() needs to run on the UI thread.
AssertIsForeground();
return previewPaneService.GetPreviewPane(GetDiagnostic(), previewContent);
string language;
string projectType;
Workspace.GetLanguageAndProjectType(preferredProjectid, out language, out projectType);
return previewPaneService.GetPreviewPane(GetDiagnostic(), language, projectType, previewContent);
}
protected virtual Diagnostic GetDiagnostic()
......
......@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Threading;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
......@@ -48,5 +49,29 @@ internal static Solution UpdateDocument(this Solution solution, DocumentId id, I
var newText = oldText.WithChanges(textChanges);
return solution.WithDocumentText(id, newText, PreservationMode.PreserveIdentity);
}
internal static void GetLanguageAndProjectType(this Workspace workspace, ProjectId projectId, out string language, out string projectType)
{
language = string.Empty;
projectType = string.Empty;
if (workspace == null)
{
return;
}
var hostContext = workspace.Services.GetService<IHostContextService>();
projectType = hostContext.GetProjectType(workspace, projectId);
// if projectId doesn't exist, not much we need to do.
if (projectId == null)
{
return;
}
var project = workspace.CurrentSolution.GetProject(projectId);
language = project?.Language ?? string.Empty;
}
}
}
......@@ -56,7 +56,7 @@ private static Image GetSeverityIconForDiagnostic(Diagnostic diagnostic)
return null;
}
private static Uri GetHelpLink(Diagnostic diagnostic, out string helpLinkToolTipText)
private static Uri GetHelpLink(Diagnostic diagnostic, string language, string projectType, out string helpLinkToolTipText)
{
var isBing = false;
helpLinkToolTipText = string.Empty;
......@@ -65,7 +65,7 @@ private static Uri GetHelpLink(Diagnostic diagnostic, out string helpLinkToolTip
if (!BrowserHelper.TryGetUri(diagnostic.Descriptor.HelpLinkUri, out helpLink))
{
// We use the ENU version of the message for bing search.
helpLink = BrowserHelper.CreateBingQueryUri(diagnostic.Id, diagnostic.GetMessage(DiagnosticData.USCultureInfo));
helpLink = BrowserHelper.CreateBingQueryUri(diagnostic.Id, diagnostic.GetMessage(DiagnosticData.USCultureInfo), language, projectType);
isBing = true;
}
......@@ -80,7 +80,7 @@ private static Uri GetHelpLink(Diagnostic diagnostic, out string helpLinkToolTip
return helpLink;
}
object IPreviewPaneService.GetPreviewPane(Diagnostic diagnostic, object previewContent)
object IPreviewPaneService.GetPreviewPane(Diagnostic diagnostic, string language, string projectType, object previewContent)
{
var title = diagnostic?.GetMessage();
......@@ -99,7 +99,7 @@ object IPreviewPaneService.GetPreviewPane(Diagnostic diagnostic, object previewC
}
var helpLinkToolTipText = string.Empty;
Uri helpLink = GetHelpLink(diagnostic, out helpLinkToolTipText);
Uri helpLink = GetHelpLink(diagnostic, language, projectType, out helpLinkToolTipText);
return new PreviewPane(
severityIcon: GetSeverityIconForDiagnostic(diagnostic),
......
......@@ -87,6 +87,11 @@ internal abstract partial class AbstractProject : IVisualStudioHostProject
/// </summary>
private Guid _guid;
/// <summary>
/// string (Guid) of the _hierarchy project type
/// </summary>
private string _projectType;
// PERF: Create these event handlers once to be shared amongst all documents (the sender arg identifies which document and project)
private static readonly EventHandler<bool> s_documentOpenedEventHandler = OnDocumentOpened;
private static readonly EventHandler<bool> s_documentClosingEventHandler = OnDocumentClosing;
......@@ -116,6 +121,9 @@ internal abstract partial class AbstractProject : IVisualStudioHostProject
// get project id guid
_guid = GetProjectIDGuid(hierarchy);
// get project type guid
_projectType = GetProjectType(hierarchy);
var componentModel = (IComponentModel)serviceProvider.GetService(typeof(SComponentModel));
_contentTypeRegistryService = componentModel.GetService<IContentTypeRegistryService>();
......@@ -150,7 +158,24 @@ internal abstract partial class AbstractProject : IVisualStudioHostProject
SetIsWebstite(hierarchy);
}
private Guid GetProjectIDGuid(IVsHierarchy hierarchy)
private static string GetProjectType(IVsHierarchy hierarchy)
{
var aggregatableProject = hierarchy as IVsAggregatableProject;
if (aggregatableProject == null)
{
return string.Empty;
}
string projectType;
if (ErrorHandler.Succeeded(aggregatableProject.GetAggregateProjectTypeGuids(out projectType)))
{
return projectType;
}
return string.Empty;
}
private static Guid GetProjectIDGuid(IVsHierarchy hierarchy)
{
Guid guid;
if (hierarchy.TryGetGuidProperty(__VSHPROPID.VSHPROPID_ProjectIDGuid, out guid))
......@@ -221,6 +246,8 @@ private static bool TryGetProjectDisplayName(IVsHierarchy hierarchy, out string
public Guid Guid => _guid;
public string ProjectType => _projectType;
public Workspace Workspace => (Workspace)_visualStudioWorkspaceOpt ?? _miscellaneousFilesWorkspaceOpt;
public VersionStamp Version => _version;
......
......@@ -18,6 +18,7 @@ internal interface IVisualStudioHostProject
IVsHierarchy Hierarchy { get; }
Guid Guid { get; }
string ProjectType { get; }
Workspace Workspace { get; }
string ProjectSystemName { get; }
......
......@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using EnvDTE;
using Microsoft.CodeAnalysis;
using Roslyn.Utilities;
......@@ -65,6 +66,8 @@ public ProjectInfo CreateProjectInfoForCurrentState()
public Guid Guid => Guid.Empty;
public string ProjectType => Constants.vsProjectKindMisc;
public Workspace Workspace => _workspace;
public string ProjectSystemName => "MiscellaneousFiles";
......
......@@ -64,7 +64,7 @@ public static string GetHelpLink(DiagnosticData item)
if (!string.IsNullOrWhiteSpace(item.Id))
{
return BrowserHelper.CreateBingQueryUri(item.Id, item.ENUMessageForBingSearch).AbsoluteUri;
return BrowserHelper.CreateBingQueryUri(item).AbsoluteUri;
}
return null;
......@@ -76,7 +76,7 @@ public static string GetHelpLinkToolTipText(DiagnosticData item)
Uri helpUri = null;
if (!BrowserHelper.TryGetUri(item.HelpLink, out helpUri) && !string.IsNullOrWhiteSpace(item.Id))
{
helpUri = BrowserHelper.CreateBingQueryUri(item.Id, item.ENUMessageForBingSearch);
helpUri = BrowserHelper.CreateBingQueryUri(item);
isBing = true;
}
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Diagnostics;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.Utilities
{
internal static class BrowserHelper
{
private const string BingSearchString = "http://www.bing.com/search?form=VSHELP&q={0}";
/// <summary>
/// unique VS session id
/// </summary>
private static readonly string RequestId = Guid.NewGuid().ToString();
private const string BingSearchString = "http://bingdev.cloudapp.net/BingUrl.svc/Get?selectedText={0}&mainLanguage={1}&projectType={2}&requestId={3}&clientId={4}&errorCode={5}";
public static bool TryGetUri(string link, out Uri uri)
{
......@@ -29,14 +34,27 @@ public static bool TryGetUri(string link, out Uri uri)
return true;
}
public static Uri CreateBingQueryUri(string errorCode, string title)
public static Uri CreateBingQueryUri(DiagnosticData diagnostic)
{
if (string.IsNullOrWhiteSpace(title))
{
return new Uri(string.Format(BingSearchString, errorCode));
}
var errorCode = diagnostic.Id;
var title = diagnostic.ENUMessageForBingSearch;
string language;
string projectType;
diagnostic.Workspace.GetLanguageAndProjectType(diagnostic.ProjectId, out language, out projectType);
return CreateBingQueryUri(errorCode, title, language, projectType);
}
public static Uri CreateBingQueryUri(string errorCode, string title, string language, string projectType)
{
errorCode = errorCode ?? string.Empty;
title = title ?? string.Empty;
language = language ?? string.Empty;
projectType = projectType ?? string.Empty;
return new Uri(string.Format(BingSearchString, errorCode + " " + title));
var url = string.Format(BingSearchString, Uri.EscapeDataString(title), Uri.EscapeDataString(language), Uri.EscapeDataString(projectType), Uri.EscapeDataString(RequestId), Uri.EscapeDataString(string.Empty), Uri.EscapeDataString(errorCode));
return new Uri(url);
}
public static void StartBrowser(Uri uri)
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Linq;
using System.Windows.Media;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.Internal.VisualStudio.PlatformUI;
using Microsoft.VisualStudio.Imaging;
using Microsoft.VisualStudio.Imaging.Interop;
using Microsoft.VisualStudio.Language.Intellisense;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer
{
......
......@@ -7,10 +7,8 @@
using System.Windows;
using System.Windows.Media;
using Microsoft.Internal.VisualStudio.PlatformUI;
using Microsoft.VisualStudio.Imaging;
using Microsoft.VisualStudio.Imaging.Interop;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer
{
......
......@@ -6,6 +6,7 @@
using System.Xml.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
using Microsoft.Internal.VisualStudio.PlatformUI;
using Microsoft.VisualStudio.Imaging;
using Microsoft.VisualStudio.Imaging.Interop;
......@@ -87,9 +88,13 @@ public Uri GetHelpLink()
if (!string.IsNullOrWhiteSpace(Descriptor.Id))
{
string language;
string projectType;
_analyzerItem.AnalyzersFolder.Workspace.GetLanguageAndProjectType(_analyzerItem.AnalyzersFolder.ProjectId, out language, out projectType);
// we use message format here since we don't have actual instance of diagnostic here.
// (which means we do not have a message)
return BrowserHelper.CreateBingQueryUri(Descriptor.Id, Descriptor.MessageFormat.ToString(DiagnosticData.USCultureInfo));
return BrowserHelper.CreateBingQueryUri(Descriptor.Id, Descriptor.MessageFormat.ToString(DiagnosticData.USCultureInfo), language, projectType);
}
return null;
......
......@@ -456,7 +456,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Diagnostics
Dim helpLink As Object = Nothing
Assert.True(snapshot.TryGetValue(0, StandardTableKeyNames.HelpLink, helpLink))
Assert.Equal("http://www.bing.com/search?form=VSHELP&q=test%20test%20format", helpLink.ToString())
Assert.True(helpLink.ToString().IndexOf("http://bingdev.cloudapp.net/BingUrl.svc/Get?selectedText=test%20format&mainLanguage=C%23&projectType=%7BFAE04EC0-301F-11D3-BF4B-00C04F79EFBC%7D") = 0)
End Using
End Sub
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Composition;
using Microsoft.CodeAnalysis.Host.Mef;
namespace Microsoft.CodeAnalysis.Host.HostContext
{
[ExportWorkspaceService(typeof(IHostContextService), ServiceLayer.Default), Shared]
internal class HostContextService : IHostContextService
{
private const string CSharpProjectType = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}";
private const string VisualBasicProjectType = "{F184B08F-C81C-45F6-A57F-5ABD9991F28F}";
public string GetProjectType(Workspace workspace, ProjectId projectId)
{
if (workspace == null || projectId == null)
{
return string.Empty;
}
var project = workspace.CurrentSolution.GetProject(projectId);
var language = project?.Language;
switch (language)
{
case LanguageNames.CSharp:
return CSharpProjectType;
case LanguageNames.VisualBasic:
return VisualBasicProjectType;
default:
return string.Empty;
}
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.CodeAnalysis.Host
{
/// <summary>
/// Provide host specific information if host supports it.
/// </summary>
internal interface IHostContextService : IWorkspaceService
{
string GetProjectType(Workspace workspace, ProjectId projectId);
}
}
......@@ -567,6 +567,8 @@
<Compile Include="Utilities\ObjectPools\PooledObject.cs" />
<Compile Include="Workspace\Host\Caching\IWorkspaceCacheService.cs" />
<Compile Include="Workspace\Host\CommandLineArgumentsFactory\ICommandLineArgumentsFactoryService.cs" />
<Compile Include="Workspace\Host\HostContext\HostContextService.cs" />
<Compile Include="Workspace\Host\HostContext\IHostContextService.cs" />
<Compile Include="Workspace\Host\Mef\ILanguagesMetadata.cs" />
<Compile Include="Workspace\Host\Mef\CodeChangeProviderMetadata.cs" />
<Compile Include="Workspace\Host\Mef\IMefHostExportProvider.cs" />
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册