提交 bf7f5976 编写于 作者: M mattwar

Added MSBuildWorkspace.SkipUnrecognizedProjects property.

This property controls what happens when referenced projects are not recognized as supported project types during solution or project open. If set to false, an exception is thrown the first time an unrecognized project is encountered.  If set to false (the default) it raises an WorkspaceFailed event and continues, omitting the project from the resulting solution and leaving dangling project references.  Of course, if the project type is unrecognized but its metadata can be identified, the project reference is turned into a metadata references (as per existing behavior).

Added tests for all cases of unrecognized projects; bad path, non-existing project file, unrecognized file extensions, unrecognized project type and unrecognized language.

Updated HostWorkspaceServices to allow for searching for language services without forcing the language to be loaded.  Added ProjectFileExtensionAttribute and ProjectTypeGuidAttribute so ProjectFileLoader's can declare via MEF metadata information used to find them.

Removed Project GUID from ProjectFileReference.  Project GUID's cannot be trusted. :-)
 (changeset 1279722)
上级 48178e6b
......@@ -73,16 +73,10 @@ private IEnumerable<ProjectFileReference> GetProjectReferencesCore(ProjectInstan
{
foreach (var projectReference in GetProjectReferenceItems(executedProject))
{
Guid guid;
if (!Guid.TryParse(projectReference.GetMetadataValue("Project"), out guid))
{
continue;
}
var filePath = projectReference.EvaluatedInclude;
var aliases = GetAliases(projectReference);
yield return new ProjectFileReference(guid, filePath, aliases);
yield return new ProjectFileReference(filePath, aliases);
}
}
......@@ -103,10 +97,13 @@ private ProjectFileInfo CreateProjectFileInfo(CSharpCompilerInputs compilerInput
IEnumerable<AnalyzerReference> analyzerRefs;
this.GetReferences(compilerInputs, executedProject, out metadataRefs, out analyzerRefs);
var outputPath = Path.Combine(this.GetOutputDirectory(), compilerInputs.OutputFileName);
var assemblyName = this.GetAssemblyName();
return new ProjectFileInfo(
this.Guid,
this.GetTargetPath(),
this.GetAssemblyName(),
outputPath,
assemblyName,
compilerInputs.CompilationOptions,
compilerInputs.ParseOptions,
docs,
......@@ -273,6 +270,7 @@ private class CSharpCompilerInputs :
internal IReadOnlyList<string> LibPaths { get; private set; }
internal bool NoStandardLib { get; private set; }
internal Dictionary<string, ReportDiagnostic> Warnings { get; private set; }
internal string OutputFileName { get; private set; }
private static readonly CSharpParseOptions defaultParseOptions = new CSharpParseOptions(languageVersion: LanguageVersion.CSharp6, documentationMode: DocumentationMode.Parse);
......@@ -280,15 +278,7 @@ internal CSharpCompilerInputs(CSharpProjectFile projectFile)
{
this.projectFile = projectFile;
var projectDirectory = Path.GetDirectoryName(projectFile.FilePath);
var outputDirectory = projectFile.GetTargetPath();
if (!string.IsNullOrEmpty(outputDirectory) && Path.IsPathRooted(outputDirectory))
{
outputDirectory = Path.GetDirectoryName(outputDirectory);
}
else
{
outputDirectory = projectDirectory;
}
var outputDirectory = projectFile.GetOutputDirectory();
this.ParseOptions = defaultParseOptions;
this.CompilationOptions = new CSharpCompilationOptions(
......@@ -620,6 +610,7 @@ public bool SetOptimize(bool optimize)
public bool SetOutputAssembly(string outputAssembly)
{
// ?? looks to be output file in obj directory not binaries\debug directory
this.OutputFileName = Path.GetFileName(outputAssembly);
return true;
}
......
......@@ -23,18 +23,6 @@ public override string Language
get { return LanguageNames.CSharp; }
}
private static readonly Guid projectTypeGuid = new Guid("FAE04EC0-301F-11D3-BF4B-00C04F79EFBC");
public override bool IsProjectTypeGuid(Guid guid)
{
return guid == projectTypeGuid;
}
public override bool IsProjectFileExtension(string fileExtension)
{
return string.Equals("csproj", fileExtension, StringComparison.OrdinalIgnoreCase);
}
protected override ProjectFile CreateProjectFile(MSB.Evaluation.Project loadedProject)
{
return new CSharpProjectFile(this, loadedProject, this.workspaceServices.GetService<IMetadataReferenceProviderService>());
......
......@@ -7,6 +7,8 @@
namespace Microsoft.CodeAnalysis.CSharp
{
[ExportLanguageServiceFactory(typeof(IProjectFileLoader), LanguageNames.CSharp)]
[ProjectFileExtension("csproj")]
[ProjectTypeGuid("FAE04EC0-301F-11D3-BF4B-00C04F79EFBC")]
internal class CSharpProjectFileLoaderFactory : ILanguageServiceFactory
{
public ILanguageService CreateLanguageService(HostLanguageServices languageServices)
......
......@@ -92,7 +92,7 @@ public override async Task<TextAndVersion> LoadTextAndVersionAsync(Workspace wor
// TODO: remove this once we know how often this can happen.
// I am leaving this here for now for diagnostic purpose.
var message = string.Format(WorkspacesResources.FileWasExternallyModified, this.path);
workspace.OnWorkspaceFailed(new DocumentDiagnostic(WorkspaceDiagnosticKind.FileAccessFailure, message, documentId));
workspace.OnWorkspaceFailed(new DocumentDiagnostic(WorkspaceDiagnosticKind.Failure, message, documentId));
}
return textAndVersion;
......
......@@ -72,5 +72,12 @@ public virtual HostLanguageServices GetLanguageServices(string languageName)
{
throw new NotSupportedException(WorkspacesResources.UnsupportedLanguage);
}
public delegate bool MetadataFilter(IReadOnlyDictionary<string, object> metadata);
/// <summary>
/// Finds all language services of the corresponding type across all supported languages that match the filter criteria.
/// </summary>
public abstract IEnumerable<TLanguageService> FindLanguageServices<TLanguageService>(MetadataFilter filter);
}
}
\ No newline at end of file
......@@ -14,23 +14,14 @@ internal class LanguageServiceMetadata : LanguageMetadata
public string ServiceType { get; private set; }
public string Layer { get; private set; }
public LanguageServiceMetadata(string language, Type serviceType, string layer)
: this(language, serviceType.AssemblyQualifiedName, layer)
{
}
public IReadOnlyDictionary<string, object> Data { get; private set; }
public LanguageServiceMetadata(IDictionary<string, object> data)
: base(data)
{
this.ServiceType = (string)data.GetValueOrDefault("ServiceType");
this.Layer = (string)data.GetValueOrDefault("Layer");
}
public LanguageServiceMetadata(string language, string serviceType, string layer)
: base(language)
{
this.ServiceType = serviceType;
this.Layer = layer;
this.Data = (IReadOnlyDictionary<string, object>)data;
}
}
}
\ No newline at end of file
......@@ -84,9 +84,11 @@ private class MefWorkspaceServices : HostWorkspaceServices
private readonly MefHostServices host;
private readonly Workspace workspace;
private readonly ImmutableArray<Lazy<IWorkspaceService, WorkspaceServiceMetadata>> services;
// map of type name to workspace service
private ImmutableDictionary<Type, IWorkspaceService> serviceMap
= ImmutableDictionary<Type, IWorkspaceService>.Empty;
private ImmutableDictionary<Type, Lazy<IWorkspaceService, WorkspaceServiceMetadata>> serviceMap
= ImmutableDictionary<Type, Lazy<IWorkspaceService, WorkspaceServiceMetadata>>.Empty;
// accumulated cache for language services
private ImmutableDictionary<string, MefLanguageServices> languageServicesMap
......@@ -96,6 +98,10 @@ public MefWorkspaceServices(MefHostServices host, Workspace workspace)
{
this.host = host;
this.workspace = workspace;
this.services = host.GetExports<IWorkspaceService, WorkspaceServiceMetadata>()
.Concat(host.GetExports<IWorkspaceServiceFactory, WorkspaceServiceMetadata>()
.Select(lz => new Lazy<IWorkspaceService, WorkspaceServiceMetadata>(() => lz.Value.CreateService(this), lz.Metadata)))
.ToImmutableArray();
}
public override HostServices HostServices
......@@ -110,69 +116,67 @@ public override Workspace Workspace
public override TWorkspaceService GetService<TWorkspaceService>()
{
IWorkspaceService service;
Lazy<IWorkspaceService, WorkspaceServiceMetadata> service;
if (TryGetService(typeof(TWorkspaceService), out service))
{
return (TWorkspaceService)service.Value;
}
else
{
return default(TWorkspaceService);
}
}
var currentMap = this.serviceMap;
var key = typeof(TWorkspaceService);
if (!currentMap.TryGetValue(key, out service))
private bool TryGetService(Type serviceType, out Lazy<IWorkspaceService, WorkspaceServiceMetadata> service)
{
if (!this.serviceMap.TryGetValue(serviceType, out service))
{
service = ImmutableInterlocked.GetOrAdd(ref this.serviceMap, key, _ =>
service = ImmutableInterlocked.GetOrAdd(ref this.serviceMap, serviceType, svctype =>
{
// pick from list of exported factories and instances
var serviceType = key.AssemblyQualifiedName;
return PickWorkspaceService(
this.host.GetExports<IWorkspaceServiceFactory, WorkspaceServiceMetadata>()
.Where(lz => lz.Metadata.ServiceType == serviceType)
.Select(lz => new KeyValuePair<string, Func<MefWorkspaceServices, IWorkspaceService>>(lz.Metadata.Layer, ws => lz.Value.CreateService(ws)))
.Concat(
this.host.GetExports<IWorkspaceService, WorkspaceServiceMetadata>()
.Where(lz => lz.Metadata.ServiceType == serviceType)
.Select(lz => new KeyValuePair<string, Func<MefWorkspaceServices, IWorkspaceService>>(lz.Metadata.Layer, ws => lz.Value))));
return PickWorkspaceService(this.services.Where(lz => lz.Metadata.ServiceType == svctype.AssemblyQualifiedName));
});
}
return (TWorkspaceService)service;
return service != default(Lazy<IWorkspaceService, WorkspaceServiceMetadata>);
}
private IWorkspaceService PickWorkspaceService(IEnumerable<KeyValuePair<string, Func<MefWorkspaceServices, IWorkspaceService>>> services)
private Lazy<IWorkspaceService, WorkspaceServiceMetadata> PickWorkspaceService(IEnumerable<Lazy<IWorkspaceService, WorkspaceServiceMetadata>> services)
{
Lazy<IWorkspaceService, WorkspaceServiceMetadata> service;
// workspace specific kind is best
var pair = services.SingleOrDefault(s => s.Key == this.workspace.Kind);
if (pair.Key != null)
if (TryGetServiceByLayer(this.workspace.Kind, services, out service))
{
return pair.Value(this);
return service;
}
// host services override editor or default
pair = services.SingleOrDefault(s => s.Key == ServiceLayer.Host);
if (pair.Key != null)
// host layer overrides editor or default
if (TryGetServiceByLayer(ServiceLayer.Host, services, out service))
{
return pair.Value(this);
return service;
}
// editor services override default
pair = services.SingleOrDefault(s => s.Key == ServiceLayer.Editor);
if (pair.Key != null)
// editor layer overrides default
if (TryGetServiceByLayer(ServiceLayer.Editor, services, out service))
{
return pair.Value(this);
return service;
}
// services marked as any are default
pair = services.SingleOrDefault(s => s.Key == ServiceLayer.Default);
if (pair.Key != null)
// that just leaves default
if (TryGetServiceByLayer(ServiceLayer.Default, services, out service))
{
return pair.Value(this);
return service;
}
pair = services.SingleOrDefault();
if (pair.Key != null)
{
return pair.Value(this);
}
else
{
return default(IWorkspaceService);
}
// no service.
return default(Lazy<IWorkspaceService, WorkspaceServiceMetadata>);
}
private bool TryGetServiceByLayer(string layer, IEnumerable<Lazy<IWorkspaceService, WorkspaceServiceMetadata>> services, out Lazy<IWorkspaceService, WorkspaceServiceMetadata> service)
{
service = services.SingleOrDefault(lz => lz.Metadata.Layer == layer);
return service != default(Lazy<IWorkspaceService, WorkspaceServiceMetadata>);
}
public override IEnumerable<string> SupportedLanguages
......@@ -205,7 +209,25 @@ public override HostLanguageServices GetLanguageServices(string languageName)
return base.GetLanguageServices(languageName);
}
}
public override IEnumerable<TLanguageService> FindLanguageServices<TLanguageService>(MetadataFilter filter)
{
foreach (var language in this.SupportedLanguages)
{
var services = (MefLanguageServices)this.GetLanguageServices(language);
Lazy<ILanguageService, LanguageServiceMetadata> service;
if (services.TryGetService(typeof(TLanguageService), out service))
{
if (filter(service.Metadata.Data))
{
yield return (TLanguageService)service.Value;
}
}
}
}
}
#endregion
#region LanguageServices
......@@ -214,9 +236,9 @@ private class MefLanguageServices : HostLanguageServices
private readonly MefWorkspaceServices workspaceServices;
private readonly string language;
private readonly ImmutableArray<Lazy<ILanguageService, LanguageServiceMetadata>> services;
private readonly ImmutableArray<Lazy<ILanguageServiceFactory, LanguageServiceMetadata>> factories;
private ImmutableDictionary<Type, ILanguageService> serviceMap = ImmutableDictionary<Type, ILanguageService>.Empty;
private ImmutableDictionary<Type, Lazy<ILanguageService, LanguageServiceMetadata>> serviceMap
= ImmutableDictionary<Type, Lazy<ILanguageService, LanguageServiceMetadata>>.Empty;
public MefLanguageServices(
MefWorkspaceServices workspaceServices,
......@@ -225,8 +247,11 @@ private class MefLanguageServices : HostLanguageServices
this.workspaceServices = workspaceServices;
this.language = language;
var hostServices = (MefHostServices)workspaceServices.HostServices;
this.services = hostServices.GetExports<ILanguageService, LanguageServiceMetadata>().Where(lz => lz.Metadata.Language == language).ToImmutableArray();
this.factories = hostServices.GetExports<ILanguageServiceFactory, LanguageServiceMetadata>().Where(lz => lz.Metadata.Language == language).ToImmutableArray();
this.services = hostServices.GetExports<ILanguageService, LanguageServiceMetadata>()
.Concat(hostServices.GetExports<ILanguageServiceFactory, LanguageServiceMetadata>()
.Select(lz => new Lazy<ILanguageService, LanguageServiceMetadata>(() => lz.Value.CreateLanguageService(this), lz.Metadata)))
.Where(lz => lz.Metadata.Language == language).ToImmutableArray();
}
public override HostWorkspaceServices WorkspaceServices
......@@ -241,75 +266,71 @@ public override string Language
public bool HasServices
{
get { return this.services.Length > 0 || this.factories.Length > 0; }
get { return this.services.Length > 0; }
}
public override TLanguageService GetService<TLanguageService>()
{
ILanguageService service;
var currentMap = this.serviceMap;
var key = typeof(TLanguageService);
Lazy<ILanguageService, LanguageServiceMetadata> service;
if (TryGetService(typeof(TLanguageService), out service))
{
return (TLanguageService)service.Value;
}
else
{
return default(TLanguageService);
}
}
if (!currentMap.TryGetValue(key, out service))
internal bool TryGetService(Type serviceType, out Lazy<ILanguageService, LanguageServiceMetadata> service)
{
if (!this.serviceMap.TryGetValue(serviceType, out service))
{
service = ImmutableInterlocked.GetOrAdd(ref this.serviceMap, key, _ =>
service = ImmutableInterlocked.GetOrAdd(ref this.serviceMap, serviceType, svctype =>
{
// pick from list of exported factories and instances
var serviceType = key.AssemblyQualifiedName;
return PickLanguageService(
this.factories
.Where(lz => lz.Metadata.ServiceType == serviceType)
.Select(lz => new KeyValuePair<string, Func<MefLanguageServices, ILanguageService>>(lz.Metadata.Layer, ls => lz.Value.CreateLanguageService(ls)))
.Concat(
this.services
.Where(lz => lz.Metadata.ServiceType == serviceType)
.Select(lz => new KeyValuePair<string, Func<MefLanguageServices, ILanguageService>>(lz.Metadata.Layer, ls => lz.Value))));
return PickLanguageService(this.services.Where(lz => lz.Metadata.ServiceType == svctype.AssemblyQualifiedName));
});
}
return (TLanguageService)service;
return service != default(Lazy<ILanguageService, LanguageServiceMetadata>);
}
private ILanguageService PickLanguageService(IEnumerable<KeyValuePair<string, Func<MefLanguageServices, ILanguageService>>> services)
private Lazy<ILanguageService, LanguageServiceMetadata> PickLanguageService(IEnumerable<Lazy<ILanguageService, LanguageServiceMetadata>> services)
{
Lazy<ILanguageService, LanguageServiceMetadata> service;
// workspace specific kind is best
var pair = services.SingleOrDefault(s => s.Key == this.workspaceServices.Workspace.Kind);
if (pair.Key != null)
if (TryGetServiceByLayer(this.workspaceServices.Workspace.Kind, services, out service))
{
return pair.Value(this);
return service;
}
// host services override editor or default
pair = services.SingleOrDefault(s => s.Key == ServiceLayer.Host);
if (pair.Key != null)
// host layer overrides editor or default
if (TryGetServiceByLayer(ServiceLayer.Host, services, out service))
{
return pair.Value(this);
return service;
}
// editor services override default
pair = services.SingleOrDefault(s => s.Key == ServiceLayer.Editor);
if (pair.Key != null)
// editor layer overrides default
if (TryGetServiceByLayer(ServiceLayer.Editor, services, out service))
{
return pair.Value(this);
return service;
}
// services marked as any are default
pair = services.SingleOrDefault(s => s.Key == ServiceLayer.Default);
if (pair.Key != null)
// that just leaves default
if (TryGetServiceByLayer(ServiceLayer.Default, services, out service))
{
return pair.Value(this);
return service;
}
pair = services.SingleOrDefault();
if (pair.Key != null)
{
return pair.Value(this);
}
else
{
return default(ILanguageService);
}
// no service
return default(Lazy<ILanguageService, LanguageServiceMetadata>);
}
private static bool TryGetServiceByLayer(string layer, IEnumerable<Lazy<ILanguageService, LanguageServiceMetadata>> services, out Lazy<ILanguageService, LanguageServiceMetadata> service)
{
service = services.SingleOrDefault(lz => lz.Metadata.Layer == layer);
return service != default(Lazy<ILanguageService, LanguageServiceMetadata>);
}
}
#endregion
......
......@@ -11,8 +11,6 @@ namespace Microsoft.CodeAnalysis.MSBuild
internal interface IProjectFileLoader : ILanguageService
{
string Language { get; }
bool IsProjectTypeGuid(Guid guid);
bool IsProjectFileExtension(string fileExtension);
Task<IProjectFile> LoadProjectFileAsync(string path, IDictionary<string, string> globalProperties, CancellationToken cancellationToken);
}
}
......@@ -80,7 +80,7 @@ protected async Task<BuildResult> BuildAsync(string taskName, MSB.Framework.ITas
var buildTargets = new BuildTargets(loadedProject, "Compile");
// Don't execute this one. It will build referenced projects.
// Even when DesignTimeBuild is defined above, it will still add the referenced project's output to the references list
// Even when DesignTimeBuild is defined, it will still add the referenced project's output to the references list
// which we don't want.
buildTargets.Remove("ResolveProjectReferences");
......@@ -103,47 +103,17 @@ protected async Task<BuildResult> BuildAsync(string taskName, MSB.Framework.ITas
var result = await this.BuildAsync(buildParameters, buildRequestData, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
if (result.Exception != null)
{
throw result.Exception;
}
return new BuildResult(result, executedProject);
}
// this lock is static because we are using the default build manager, and there is only one per process
// this lock is static because we are using the default build manager, and there is only one per process
private static readonly AsyncSemaphore buildManagerLock = new AsyncSemaphore(1);
private MSB.Execution.BuildResult Build(MSB.Execution.BuildParameters parameters, MSB.Execution.BuildRequestData requestData, CancellationToken cancellationToken)
{
using (buildManagerLock.DisposableWait())
{
var buildManager = MSB.Execution.BuildManager.DefaultBuildManager;
buildManager.BeginBuild(parameters);
// enable cancellation of build
CancellationTokenRegistration registration = default(CancellationTokenRegistration);
if (cancellationToken.CanBeCanceled)
{
registration = cancellationToken.Register(() =>
{
buildManager.CancelAllSubmissions();
});
}
// execute build sync
try
{
return buildManager.BuildRequest(requestData);
}
finally
{
if (registration != default(CancellationTokenRegistration))
{
registration.Dispose();
}
buildManager.EndBuild();
}
}
}
private async Task<MSB.Execution.BuildResult> BuildAsync(MSB.Execution.BuildParameters parameters, MSB.Execution.BuildRequestData requestData, CancellationToken cancellationToken)
{
// only allow one build to use the default build manager at a time
......@@ -205,21 +175,34 @@ private static Task<MSB.Execution.BuildResult> BuildAsync(MSB.Execution.BuildMan
return taskSource.Task;
}
protected virtual string GetTargetPath()
protected virtual string GetOutputDirectory()
{
return this.GetAbsolutePath(this.loadedProject.GetPropertyValue("TargetPath"));
var targetPath = this.loadedProject.GetPropertyValue("TargetPath");
if (string.IsNullOrEmpty(targetPath))
{
targetPath = loadedProject.DirectoryPath;
}
return Path.GetDirectoryName(this.GetAbsolutePath(targetPath));
}
protected virtual string GetAssemblyName()
{
return PathUtilities.GetFileName(this.loadedProject.GetPropertyValue("AssemblyName"));
var assemblyName = this.loadedProject.GetPropertyValue("AssemblyName");
if (string.IsNullOrEmpty(assemblyName))
{
assemblyName = Path.GetFileNameWithoutExtension(loadedProject.FullPath);
}
return PathUtilities.GetFileName(assemblyName);
}
protected virtual IEnumerable<ProjectFileReference> GetProjectReferences(MSB.Execution.ProjectInstance executedProject)
{
return executedProject.GetItems("ProjectReference")
.Select(reference => new ProjectFileReference(
guid: Guid.Parse(reference.GetMetadataValue("Project")),
path: reference.EvaluatedInclude,
aliases: default(ImmutableArray<string>)));
}
......
// Copyright (c) Microsoft Open Technologies, Inc. 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.ComponentModel.Composition;
namespace Microsoft.CodeAnalysis.MSBuild
{
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
internal class ProjectFileExtensionAttribute : Attribute
{
public ProjectFileExtensionAttribute(string extension)
{
this.ProjectFileExtension = extension;
}
public string ProjectFileExtension { get; set; }
}
}
\ No newline at end of file
......@@ -9,7 +9,6 @@
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
using MSB = Microsoft.Build;
namespace Microsoft.CodeAnalysis.MSBuild
......@@ -21,8 +20,6 @@ public ProjectFileLoader()
}
public abstract string Language { get; }
public abstract bool IsProjectTypeGuid(Guid guid);
public abstract bool IsProjectFileExtension(string fileExtension);
protected abstract ProjectFile CreateProjectFile(MSB.Evaluation.Project loadedProject);
......@@ -84,5 +81,19 @@ private static async Task<MemoryStream> ReadFileAsync(string path, CancellationT
memoryStream.Position = 0;
return memoryStream;
}
public static IProjectFileLoader GetLoaderForProjectTypeGuid(Workspace workspace, Guid guid)
{
return workspace.Services.FindLanguageServices<IProjectFileLoader>(
d => ((string[])d["ProjectTypeGuid"]).Any(g => guid == new Guid(g)))
.FirstOrDefault();
}
public static IProjectFileLoader GetLoaderForProjectFileExtension(Workspace workspace, string extension)
{
return workspace.Services.FindLanguageServices<IProjectFileLoader>(
d => ((string[])d["ProjectFileExtension"]).Any(e => string.Equals(e, extension, StringComparison.OrdinalIgnoreCase)))
.FirstOrDefault();
}
}
}
\ No newline at end of file
......@@ -13,11 +13,6 @@ namespace Microsoft.CodeAnalysis.MSBuild
/// </summary>
internal sealed class ProjectFileReference
{
/// <summary>
/// The unique GUID of the referenced project.
/// </summary>
public Guid Guid { get; private set; }
/// <summary>
/// The path on disk to the other project file.
/// This path may be relative to the referencing project's file or an absolute path.
......@@ -29,9 +24,8 @@ internal sealed class ProjectFileReference
/// </summary>
public ImmutableArray<string> Aliases { get; private set; }
public ProjectFileReference(Guid guid, string path, ImmutableArray<string> aliases)
public ProjectFileReference(string path, ImmutableArray<string> aliases)
{
this.Guid = guid;
this.Path = path;
this.Aliases = aliases;
}
......
// Copyright (c) Microsoft Open Technologies, Inc. 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.ComponentModel.Composition;
namespace Microsoft.CodeAnalysis.MSBuild
{
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
internal class ProjectTypeGuidAttribute : Attribute
{
public ProjectTypeGuidAttribute(string guid)
{
this.ProjectTypeGuid = guid;
}
public string ProjectTypeGuid { get; set; }
}
}
\ No newline at end of file
......@@ -122,7 +122,7 @@ private static async Task<TextAndVersion> LoadTextAsync(TextLoader loader, Docum
}
catch (IOException e)
{
services.Workspace.OnWorkspaceFailed(new DocumentDiagnostic(WorkspaceDiagnosticKind.FileAccessFailure, e.Message, documentId));
services.Workspace.OnWorkspaceFailed(new DocumentDiagnostic(WorkspaceDiagnosticKind.Failure, e.Message, documentId));
return TextAndVersion.Create(SourceText.From(string.Empty, Encoding.UTF8), VersionStamp.Default, documentId.GetDebuggerDisplay());
}
}
......
......@@ -5,7 +5,7 @@
namespace Microsoft.CodeAnalysis
{
[DebuggerDisplay("{GetDebuggerDisplay(),nq}")]
public abstract class WorkspaceDiagnostic
public class WorkspaceDiagnostic
{
public WorkspaceDiagnosticKind Kind { get; private set; }
public string Message { get; private set; }
......
......@@ -4,8 +4,7 @@ namespace Microsoft.CodeAnalysis
{
public enum WorkspaceDiagnosticKind
{
FileAccessFailure,
Failure,
Warning
}
}
\ No newline at end of file
......@@ -83,31 +83,19 @@ protected Task RaiseWorkspaceChangedEventAsync(WorkspaceChangeKind kind, Solutio
}
}
private Task RaiseWorkspaceFailedEventAsync(WorkspaceDiagnostic diagnostic)
protected internal virtual void OnWorkspaceFailed(WorkspaceDiagnostic diagnostic)
{
var handlers = this.eventMap.GetEventHandlers<EventHandler<WorkspaceDiagnosticEventArgs>>(WorkspaceFailedEventName);
if (handlers.Length > 0)
{
return this.ScheduleTask(() =>
var args = new WorkspaceDiagnosticEventArgs(diagnostic);
foreach (var handler in handlers)
{
var args = new WorkspaceDiagnosticEventArgs(diagnostic);
foreach (var handler in handlers)
{
handler(this, args);
}
}, "Workspace.WorkspaceFailed");
}
else
{
return SpecializedTasks.EmptyTask;
handler(this, args);
}
}
}
protected internal virtual void OnWorkspaceFailed(WorkspaceDiagnostic diagnostic)
{
this.RaiseWorkspaceFailedEventAsync(diagnostic);
}
/// <summary>
/// An event that is fired when a documents is opened in the editor.
/// </summary>
......
......@@ -834,12 +834,14 @@
<Compile Include="Workspace\MSBuild\MSBuildWorkspace.cs" />
<Compile Include="Workspace\MSBuild\ProjectFile\BuildTargets.cs" />
<Compile Include="Workspace\MSBuild\ProjectFile\DocumentFileInfo.cs" />
<Compile Include="Workspace\MSBuild\ProjectFile\ProjectFileExtensionAttribute.cs" />
<Compile Include="Workspace\MSBuild\ProjectFile\IProjectFile.cs" />
<Compile Include="Workspace\MSBuild\ProjectFile\IProjectFileLoader.cs" />
<Compile Include="Workspace\MSBuild\ProjectFile\ProjectFile.cs" />
<Compile Include="Workspace\MSBuild\ProjectFile\ProjectFileInfo.cs" />
<Compile Include="Workspace\MSBuild\ProjectFile\ProjectFileLoader.cs" />
<Compile Include="Workspace\MSBuild\ProjectFile\ProjectFileReference.cs" />
<Compile Include="Workspace\MSBuild\ProjectFile\ProjectTypeGuidAttribute.cs" />
<Compile Include="Workspace\MSBuild\SolutionFile\LineScanner.cs" />
<Compile Include="Workspace\MSBuild\SolutionFile\ProjectBlock.cs" />
<Compile Include="Workspace\MSBuild\SolutionFile\SectionBlock.cs" />
......
......@@ -114,6 +114,24 @@ internal class WorkspacesResources {
}
}
/// <summary>
/// Looks up a localized string similar to Cannot open project &apos;{0}&apos; because the file extension &apos;{1}&apos; is not associated with a language..
/// </summary>
internal static string CannotOpenProjectUnrecognizedFileExtension {
get {
return ResourceManager.GetString("CannotOpenProjectUnrecognizedFileExtension", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Cannot open project &apos;{0}&apos; because the language &apos;{1}&apos; is not supported..
/// </summary>
internal static string CannotOpenProjectUnsupportedLanguage {
get {
return ResourceManager.GetString("CannotOpenProjectUnsupportedLanguage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Can&apos;t resolve analyzer reference: &apos;{0}&apos;..
/// </summary>
......@@ -393,6 +411,24 @@ internal class WorkspacesResources {
}
}
/// <summary>
/// Looks up a localized string similar to Invalid project file path: &apos;{0}&apos;.
/// </summary>
internal static string InvalidProjectFilePath {
get {
return ResourceManager.GetString("InvalidProjectFilePath", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Invalid solution file path: &apos;{0}&apos;.
/// </summary>
internal static string InvalidSolutionFilePath {
get {
return ResourceManager.GetString("InvalidSolutionFilePath", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to This submission already references another submission project..
/// </summary>
......@@ -519,6 +555,15 @@ internal class WorkspacesResources {
}
}
/// <summary>
/// Looks up a localized string similar to Project file not found: &apos;{0}&apos;.
/// </summary>
internal static string ProjectFileNotFound {
get {
return ResourceManager.GetString("ProjectFileNotFound", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The solution does not contain the specified project..
/// </summary>
......@@ -591,6 +636,15 @@ internal class WorkspacesResources {
}
}
/// <summary>
/// Looks up a localized string similar to Solution file not found: &apos;{0}&apos;.
/// </summary>
internal static string SolutionFileNotFound {
get {
return ResourceManager.GetString("SolutionFileNotFound", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &quot;{0}&quot; must be a non-null and non-empty string..
/// </summary>
......@@ -627,15 +681,6 @@ internal class WorkspacesResources {
}
}
/// <summary>
/// Looks up a localized string similar to Unrecognized project type..
/// </summary>
internal static string UnrecognizedProjectType {
get {
return ResourceManager.GetString("UnrecognizedProjectType", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The language &apos;{0}&apos; is not supported..
/// </summary>
......
......@@ -237,9 +237,6 @@
<data name="FileWasExternallyModified" xml:space="preserve">
<value>File was externally modified: {0}.</value>
</data>
<data name="UnrecognizedProjectType" xml:space="preserve">
<value>Unrecognized project type.</value>
</data>
<data name="UnrecognizedLanguageName" xml:space="preserve">
<value>Unrecognized language name.</value>
</data>
......@@ -318,4 +315,22 @@
<data name="AbsolutePathExpected" xml:space="preserve">
<value>Absolute path expected.</value>
</data>
<data name="CannotOpenProjectUnrecognizedFileExtension" xml:space="preserve">
<value>Cannot open project '{0}' because the file extension '{1}' is not associated with a language.</value>
</data>
<data name="CannotOpenProjectUnsupportedLanguage" xml:space="preserve">
<value>Cannot open project '{0}' because the language '{1}' is not supported.</value>
</data>
<data name="InvalidProjectFilePath" xml:space="preserve">
<value>Invalid project file path: '{0}'</value>
</data>
<data name="InvalidSolutionFilePath" xml:space="preserve">
<value>Invalid solution file path: '{0}'</value>
</data>
<data name="ProjectFileNotFound" xml:space="preserve">
<value>Project file not found: '{0}'</value>
</data>
<data name="SolutionFileNotFound" xml:space="preserve">
<value>Solution file not found: '{0}'</value>
</data>
</root>
\ No newline at end of file
// Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.CodeAnalysis.MSBuild;
using Roslyn.Test.Utilities;
namespace Microsoft.CodeAnalysis.UnitTests
{
public static class MSBuildWorkspaceTestExtensions
{
internal static EventWaiter VerifyWorkspaceChangedEvent(this MSBuildWorkspace workspace, Action<WorkspaceChangeEventArgs> action)
{
var wew = new EventWaiter();
workspace.WorkspaceChanged += wew.Wrap<WorkspaceChangeEventArgs>((sender, args) => action(args));
return wew;
}
internal static EventWaiter VerifyWorkspaceFailedEvent(this MSBuildWorkspace workspace, Action<WorkspaceDiagnosticEventArgs> action)
{
var wew = new EventWaiter();
workspace.WorkspaceFailed += wew.Wrap<WorkspaceDiagnosticEventArgs>((sender, args) => action(args));
return wew;
}
}
}
......@@ -75,8 +75,8 @@
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "></PropertyGroup>
<ItemGroup>
<Compile Include="AssemblyAttributes.cs" />
<Compile Include="AsyncLazyTests.cs" />
<Compile Include="AsyncLazyTests.StopTheThreadPoolContext.cs" />
<Compile Include="UtilityTest\AsyncLazyTests.cs" />
<Compile Include="UtilityTest\AsyncLazyTests.StopTheThreadPoolContext.cs" />
<Compile Include="CodeCleanup\AddMissingTokensTests.cs" />
<Compile Include="CodeCleanup\CodeCleanupTests.cs" />
<Compile Include="CodeCleanup\Extensions.cs" />
......@@ -84,18 +84,19 @@
<Compile Include="CodeCleanup\NormalizeModifiersOrOperatorsTests.cs" />
<Compile Include="CodeCleanup\ReduceTokenTests.cs" />
<Compile Include="CodeCleanup\RemoveUnnecessaryLineContinuationTests.cs" />
<Compile Include="CommandLineProjectTests.cs" />
<Compile Include="WorkspaceTests\CommandLineProjectTests.cs" />
<Compile Include="WorkspaceTests\CustomWorkspaceTests.cs" />
<Compile Include="Differencing\MatchTests.cs" />
<Compile Include="Differencing\TestNode.cs" />
<Compile Include="Differencing\TestTreeComparer.cs" />
<Compile Include="DocumentationCommentIdTests.cs" />
<Compile Include="DocumentationCommentTests.cs" />
<Compile Include="EditDistanceTests.cs" />
<Compile Include="EtwLoggingTests.cs" />
<Compile Include="ExceptionHelpersTests.cs">
<Compile Include="UtilityTest\DocumentationCommentIdTests.cs" />
<Compile Include="UtilityTest\DocumentationCommentTests.cs" />
<Compile Include="UtilityTest\EditDistanceTests.cs" />
<Compile Include="UtilityTest\EtwLoggingTests.cs" />
<Compile Include="UtilityTest\ExceptionHelpersTests.cs">
<ExcludeFromStyleCop>true</ExcludeFromStyleCop>
</Compile>
<Compile Include="FileSet.cs" />
<Compile Include="WorkspaceTests\FileSet.cs" />
<Compile Include="FindAllDeclarationsTests.cs" />
<Compile Include="FindAllDeclarationsTests.TestSolutionsAndProject.cs" />
<Compile Include="FindReferencesTests.cs" />
......@@ -105,33 +106,33 @@
<Compile Include="Host\WorkspaceServices\Caching\TestSyntaxTreeCacheService.cs" />
<Compile Include="Host\WorkspaceServices\TemporaryStorage\TestTemporaryStorage.cs" />
<Compile Include="Host\WorkspaceServices\TemporaryStorage\TestTemporaryStorageService.cs" />
<Compile Include="LanguageServices\SyntaxTreeFactoryServiceTests.cs" />
<Compile Include="MSBuildWorkspaceTests.cs" />
<Compile Include="MSBuildWorkspaceTests.Extensions.cs" />
<Compile Include="MSBuildWorkspaceTests.HelperMethods.cs" />
<Compile Include="NotKeptAliveCompilationCacheServiceFactory.cs" />
<Compile Include="NotKeptAliveSyntaxTreeCacheServiceFactory.cs" />
<Compile Include="NotKeptAliveTextCacheServiceFactory.cs" />
<Compile Include="ProjectDependencyGraphTests.cs" />
<Compile Include="ProjectInfoTests.cs" />
<Compile Include="LanguageServiceTests\SyntaxTreeFactoryServiceTests.cs" />
<Compile Include="WorkspaceTests\MSBuildWorkspaceTests.cs" />
<Compile Include="WorkspaceTests\MSBuildWorkspaceTestBase.cs" />
<Compile Include="WorkspaceTests\WorkspaceTestBase.cs" />
<Compile Include="SolutionTests\NotKeptAliveCompilationCacheServiceFactory.cs" />
<Compile Include="SolutionTests\NotKeptAliveSyntaxTreeCacheServiceFactory.cs" />
<Compile Include="SolutionTests\NotKeptAliveTextCacheServiceFactory.cs" />
<Compile Include="SolutionTests\ProjectDependencyGraphTests.cs" />
<Compile Include="SolutionTests\ProjectInfoTests.cs" />
<Compile Include="ReferencedSymbolTests.cs" />
<Compile Include="SerializableBytesTests.cs" />
<Compile Include="UtilityTest\SerializableBytesTests.cs" />
<Compile Include="SerializationTests.cs" />
<Compile Include="SolutionGeneration.cs" />
<Compile Include="SolutionParsingTests.cs" />
<Compile Include="SolutionTests.cs" />
<Compile Include="WorkspaceTests\SolutionParsingTests.cs" />
<Compile Include="SolutionTests\SolutionTests.cs" />
<Compile Include="SolutionUtilities.cs" />
<Compile Include="SyntaxNodeTests.cs" />
<Compile Include="SyntaxPathTests.cs" />
<Compile Include="SyntaxReferenceTests.cs" />
<Compile Include="SyntaxTreeStorageServiceTests.cs" />
<Compile Include="TemporaryStorageServiceTests.cs" />
<Compile Include="TestOptionService.cs" />
<Compile Include="WorkspaceServiceTests\SyntaxTreeStorageServiceTests.cs" />
<Compile Include="WorkspaceServiceTests\TemporaryStorageServiceTests.cs" />
<Compile Include="Host\WorkspaceServices\TestOptionService.cs" />
<Compile Include="TestWorkspace.cs" />
<Compile Include="WorkspaceExtensions.cs" />
<Compile Include="WorkspaceServices\OptionServiceTests.cs" />
<Compile Include="WorkspaceServices\TestPersistenceService.cs" />
<Compile Include="WorkspaceServices\TestHost.cs" />
<Compile Include="WorkspaceTests\WorkspaceExtensions.cs" />
<Compile Include="WorkspaceServiceTests\OptionServiceTests.cs" />
<Compile Include="Host\WorkspaceServices\TestPersistenceService.cs" />
<Compile Include="Host\TestHost.cs" />
<EmbeddedResource Include="TestFiles\CSharpProject_App.xaml">
<SubType>Designer</SubType>
</EmbeddedResource>
......@@ -141,8 +142,6 @@
<EmbeddedResource Include="TestFiles\CSharpProject_CSharpClass_WithConditionalAttributes.cs" />
<EmbeddedResource Include="TestFiles\CSharpProject_CSharpConsole.cs" />
<EmbeddedResource Include="TestFiles\CSharpProject_CSharpExternAlias.cs" />
<EmbeddedResource Include="TestFiles\CSharpProject_CSharpProject_AssemblyNameIsPath.csproj" />
<EmbeddedResource Include="TestFiles\CSharpProject_CSharpProject_AssemblyNameIsPath2.csproj" />
<EmbeddedResource Include="TestFiles\CSharpProject_CSharpProject_BadHintPath.csproj" />
<EmbeddedResource Include="TestFiles\CSharpProject_CSharpProject_DuplicateFile.csproj" />
<EmbeddedResource Include="TestFiles\CSharpProject_CSharpProject_ExternAlias.csproj" />
......@@ -226,6 +225,34 @@
<ItemGroup>
<Folder Include="Host\Utilities\" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="TestFiles\TestSolution_InvalidProjectPath.sln" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="TestFiles\TestSolution_NonExistentProject.sln" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="TestFiles\CSharpProject_CSharpProject_AssemblyNameIsPath.csproj" />
<EmbeddedResource Include="TestFiles\CSharpProject_CSharpProject_AssemblyNameIsPath2.csproj" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="TestFiles\TestSolution_CSharp_UnknownProjectTypeGuid.sln" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="TestFiles\TestSolution_CSharp_UnknownProjectTypeGuidAndUnknownExtension.sln" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="TestFiles\TestSolution_CSharp_UnknownProjectExtension.sln" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="TestFiles\VisualBasicProject_VisualBasicProject_InvalidProjectReference.vbproj" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="TestFiles\VisualBasicProject_VisualBasicProject_NonExistentProjectReference.vbproj" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="TestFiles\VisualBasicProject_VisualBasicProject_UnknownProjectExtension.vbproj" />
</ItemGroup>
<ImportGroup Label="Targets">
<Import Project="..\..\Tools\Microsoft.CodeAnalysis.Toolset.Open\Targets\VSL.Imports.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
......
......@@ -1255,7 +1255,7 @@ public void TestDocumentFileAccessFailureMissingFile()
var dd = diagnostic as DocumentDiagnostic;
Assert.NotNull(dd);
Assert.Equal(did, dd.DocumentId);
Assert.Equal(WorkspaceDiagnosticKind.FileAccessFailure, dd.Kind);
Assert.Equal(WorkspaceDiagnosticKind.Failure, dd.Kind);
}
[Fact]
......

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpProject", "CSharpProject\CSharpProject.noproj", "{686DD036-86AA-443E-8A10-DDB43266A8C4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{686DD036-86AA-443E-8A10-DDB43266A8C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{686DD036-86AA-443E-8A10-DDB43266A8C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{686DD036-86AA-443E-8A10-DDB43266A8C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{686DD036-86AA-443E-8A10-DDB43266A8C4}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-000000000000}") = "CSharpProject", "CSharpProject\CSharpProject.csproj", "{686DD036-86AA-443E-8A10-DDB43266A8C4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{686DD036-86AA-443E-8A10-DDB43266A8C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{686DD036-86AA-443E-8A10-DDB43266A8C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{686DD036-86AA-443E-8A10-DDB43266A8C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{686DD036-86AA-443E-8A10-DDB43266A8C4}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-000000000000}") = "CSharpProject", "CSharpProject\CSharpProject.noproj", "{686DD036-86AA-443E-8A10-DDB43266A8C4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{686DD036-86AA-443E-8A10-DDB43266A8C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{686DD036-86AA-443E-8A10-DDB43266A8C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{686DD036-86AA-443E-8A10-DDB43266A8C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{686DD036-86AA-443E-8A10-DDB43266A8C4}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpProject", "http://localhost/CSharpProject/CSharpProject.csproj", "{686DD036-86AA-443E-8A10-DDB43266A8C4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{686DD036-86AA-443E-8A10-DDB43266A8C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{686DD036-86AA-443E-8A10-DDB43266A8C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{686DD036-86AA-443E-8A10-DDB43266A8C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{686DD036-86AA-443E-8A10-DDB43266A8C4}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpProject", "CSharpProject/NoProject.csproj", "{686DD036-86AA-443E-8A10-DDB43266A8C4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{686DD036-86AA-443E-8A10-DDB43266A8C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{686DD036-86AA-443E-8A10-DDB43266A8C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{686DD036-86AA-443E-8A10-DDB43266A8C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{686DD036-86AA-443E-8A10-DDB43266A8C4}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion></ProductVersion>
<SchemaVersion></SchemaVersion>
<ProjectGuid>{AC25ECDA-DE94-4FCF-A688-EB3A2BE3670C}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>VisualBasicProject</RootNamespace>
<AssemblyName>VisualBasicProject</AssemblyName>
<FileAlignment>512</FileAlignment>
<MyType>Windows</MyType>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<OutDir>..\..\..\..\Binaries\$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<DefineDebug>true</DefineDebug>
<DefineTrace>true</DefineTrace>
<OutputPath>bin\Debug\</OutputPath>
<DocumentationFile>VisualBasicProject.xml</DocumentationFile>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
<RemoveIntegerChecks>true</RemoveIntegerChecks>
<AssemblyOriginatorKeyFile>snKey.snk</AssemblyOriginatorKeyFile>
<DefineConstants>FURBY</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<DefineDebug>false</DefineDebug>
<DefineTrace>true</DefineTrace>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DocumentationFile>VisualBasicProject.xml</DocumentationFile>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
</PropertyGroup>
<PropertyGroup>
<OptionExplicit>On</OptionExplicit>
</PropertyGroup>
<PropertyGroup>
<OptionCompare>Binary</OptionCompare>
</PropertyGroup>
<PropertyGroup>
<OptionStrict>Off</OptionStrict>
</PropertyGroup>
<PropertyGroup>
<OptionInfer>On</OptionInfer>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
</ItemGroup>
<ItemGroup>
<Import Include="Microsoft.VisualBasic" />
<Import Include="System" />
<Import Include="System.Collections" />
<Import Include="System.Collections.Generic" />
<Import Include="System.Diagnostics" />
<Import Include="System.Linq" />
</ItemGroup>
<ItemGroup>
<Compile Include="My Project\Application.Designer.vb">
<AutoGen>True</AutoGen>
<DependentUpon>Application.myapp</DependentUpon>
</Compile>
<Compile Include="My Project\AssemblyInfo.vb" />
<Compile Include="My Project\Resources.Designer.vb">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="My Project\Settings.Designer.vb">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<Compile Include="VisualBasicClass.vb" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="My Project\Resources.resx">
<Generator>VbMyResourcesResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.vb</LastGenOutput>
<CustomToolNamespace>My.Resources</CustomToolNamespace>
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="My Project\Application.myapp">
<Generator>MyApplicationCodeGenerator</Generator>
<LastGenOutput>Application.Designer.vb</LastGenOutput>
</None>
<None Include="My Project\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<CustomToolNamespace>My</CustomToolNamespace>
<LastGenOutput>Settings.Designer.vb</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="http://localhost/Invalid/InvalidProject.csproj">
<Project>{686DD036-86AA-443E-8A10-DDB43266A8C4}</Project>
<Name>CSharpProject</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion></ProductVersion>
<SchemaVersion></SchemaVersion>
<ProjectGuid>{AC25ECDA-DE94-4FCF-A688-EB3A2BE3670C}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>VisualBasicProject</RootNamespace>
<AssemblyName>VisualBasicProject</AssemblyName>
<FileAlignment>512</FileAlignment>
<MyType>Windows</MyType>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<OutDir>..\..\..\..\Binaries\$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<DefineDebug>true</DefineDebug>
<DefineTrace>true</DefineTrace>
<OutputPath>bin\Debug\</OutputPath>
<DocumentationFile>VisualBasicProject.xml</DocumentationFile>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
<RemoveIntegerChecks>true</RemoveIntegerChecks>
<AssemblyOriginatorKeyFile>snKey.snk</AssemblyOriginatorKeyFile>
<DefineConstants>FURBY</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<DefineDebug>false</DefineDebug>
<DefineTrace>true</DefineTrace>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DocumentationFile>VisualBasicProject.xml</DocumentationFile>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
</PropertyGroup>
<PropertyGroup>
<OptionExplicit>On</OptionExplicit>
</PropertyGroup>
<PropertyGroup>
<OptionCompare>Binary</OptionCompare>
</PropertyGroup>
<PropertyGroup>
<OptionStrict>Off</OptionStrict>
</PropertyGroup>
<PropertyGroup>
<OptionInfer>On</OptionInfer>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
</ItemGroup>
<ItemGroup>
<Import Include="Microsoft.VisualBasic" />
<Import Include="System" />
<Import Include="System.Collections" />
<Import Include="System.Collections.Generic" />
<Import Include="System.Diagnostics" />
<Import Include="System.Linq" />
</ItemGroup>
<ItemGroup>
<Compile Include="My Project\Application.Designer.vb">
<AutoGen>True</AutoGen>
<DependentUpon>Application.myapp</DependentUpon>
</Compile>
<Compile Include="My Project\AssemblyInfo.vb" />
<Compile Include="My Project\Resources.Designer.vb">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="My Project\Settings.Designer.vb">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<Compile Include="VisualBasicClass.vb" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="My Project\Resources.resx">
<Generator>VbMyResourcesResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.vb</LastGenOutput>
<CustomToolNamespace>My.Resources</CustomToolNamespace>
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="My Project\Application.myapp">
<Generator>MyApplicationCodeGenerator</Generator>
<LastGenOutput>Application.Designer.vb</LastGenOutput>
</None>
<None Include="My Project\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<CustomToolNamespace>My</CustomToolNamespace>
<LastGenOutput>Settings.Designer.vb</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CSharpProject\NonExistentProject.csproj">
<Project>{686DD036-86AA-443E-8A10-DDB43266A8C4}</Project>
<Name>CSharpProject</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion></ProductVersion>
<SchemaVersion></SchemaVersion>
<ProjectGuid>{AC25ECDA-DE94-4FCF-A688-EB3A2BE3670C}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>VisualBasicProject</RootNamespace>
<AssemblyName>VisualBasicProject</AssemblyName>
<FileAlignment>512</FileAlignment>
<MyType>Windows</MyType>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<OutDir>..\..\..\..\Binaries\$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<DefineDebug>true</DefineDebug>
<DefineTrace>true</DefineTrace>
<OutputPath>bin\Debug\</OutputPath>
<DocumentationFile>VisualBasicProject.xml</DocumentationFile>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
<RemoveIntegerChecks>true</RemoveIntegerChecks>
<AssemblyOriginatorKeyFile>snKey.snk</AssemblyOriginatorKeyFile>
<DefineConstants>FURBY</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<DefineDebug>false</DefineDebug>
<DefineTrace>true</DefineTrace>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DocumentationFile>VisualBasicProject.xml</DocumentationFile>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
</PropertyGroup>
<PropertyGroup>
<OptionExplicit>On</OptionExplicit>
</PropertyGroup>
<PropertyGroup>
<OptionCompare>Binary</OptionCompare>
</PropertyGroup>
<PropertyGroup>
<OptionStrict>Off</OptionStrict>
</PropertyGroup>
<PropertyGroup>
<OptionInfer>On</OptionInfer>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
</ItemGroup>
<ItemGroup>
<Import Include="Microsoft.VisualBasic" />
<Import Include="System" />
<Import Include="System.Collections" />
<Import Include="System.Collections.Generic" />
<Import Include="System.Diagnostics" />
<Import Include="System.Linq" />
</ItemGroup>
<ItemGroup>
<Compile Include="My Project\Application.Designer.vb">
<AutoGen>True</AutoGen>
<DependentUpon>Application.myapp</DependentUpon>
</Compile>
<Compile Include="My Project\AssemblyInfo.vb" />
<Compile Include="My Project\Resources.Designer.vb">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="My Project\Settings.Designer.vb">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<Compile Include="VisualBasicClass.vb" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="My Project\Resources.resx">
<Generator>VbMyResourcesResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.vb</LastGenOutput>
<CustomToolNamespace>My.Resources</CustomToolNamespace>
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="My Project\Application.myapp">
<Generator>MyApplicationCodeGenerator</Generator>
<LastGenOutput>Application.Designer.vb</LastGenOutput>
</None>
<None Include="My Project\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<CustomToolNamespace>My</CustomToolNamespace>
<LastGenOutput>Settings.Designer.vb</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CSharpProject\CSharpProject.noproj">
<Project>{686DD036-86AA-443E-8A10-DDB43266A8C4}</Project>
<Name>CSharpProject</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
\ No newline at end of file
// Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Immutable;
using System.Threading;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.UnitTests;
using Roslyn.Test.Utilities;
using Xunit;
using CS = Microsoft.CodeAnalysis.CSharp;
namespace Microsoft.CodeAnalysis.Host.UnitTests
{
public class ProjectDependencyServiceTests : TestBase
{
[WorkItem(8683, "DevDiv_Projects/Roslyn"), WorkItem(542393)]
[Fact, Trait(Traits.Feature, Traits.Features.Workspace)]
public void TestMoveToLatestSolution()
{
var workspace = new TestWorkspace();
var solution = workspace.CurrentSolution;
var project1 = workspace.AddProject("P1");
var graph = ProjectDependencyService.GetDependencyGraphAsync(workspace.CurrentSolution, CancellationToken.None).Result;
var project2 = workspace.AddProject("P2");
graph = ProjectDependencyService.GetDependencyGraphAsync(workspace.CurrentSolution, CancellationToken.None).Result;
var sortedProjects = graph.GetTopologicallySortedProjects();
AssertEx.SetEqual(sortedProjects, project1, project2);
workspace.OnAssemblyNameChanged(project1, "ChangedP1");
}
[Fact, Trait(Traits.Feature, Traits.Features.Workspace)]
public void Test_WorkspaceChanges()
{
var workspace = new TestWorkspace();
var solution = workspace.CurrentSolution;
var project1 = workspace.AddProject("P1");
var graph = ProjectDependencyService.GetDependencyGraphAsync(workspace.CurrentSolution, CancellationToken.None).Result;
var project2 = workspace.AddProject("P2");
graph = ProjectDependencyService.GetDependencyGraphAsync(workspace.CurrentSolution, CancellationToken.None).Result;
var sortedProjects = graph.GetTopologicallySortedProjects();
AssertEx.SetEqual(sortedProjects, project1, project2);
Project ps = workspace.CurrentSolution.GetProject(project1);
int startCount = ps.MetadataReferences.Count;
var source2 = @"
using System;
public class X
{
}
";
MetadataReference comp1 = CreateCSharpCompilation(source2).ToMetadataReference();
workspace.OnMetadataReferenceAdded(project1, comp1);
workspace.OnAssemblyNameChanged(project1, "ChangedP1");
Assert.False(ps.CompilationOptions.CheckOverflow);
CompilationOptions co = new CSharp.CSharpCompilationOptions(outputKind: OutputKind.DynamicallyLinkedLibrary, checkOverflow: true);
workspace.OnCompilationOptionsChanged(project1, co);
ps = workspace.CurrentSolution.GetProject(project1);
Assert.Equal(startCount + 1, ps.MetadataReferences.Count);
Assert.Equal(ps.AssemblyName, "ChangedP1");
Assert.True(ps.CompilationOptions.CheckOverflow);
}
[WorkItem(705220)]
[Fact, Trait(Traits.Feature, Traits.Features.Workspace)]
public void Test_WorkspaceOutputFilePathChanges()
{
var workspace = new TestWorkspace();
var solution = workspace.CurrentSolution;
var project = workspace.AddProject("P1");
Project ps = workspace.CurrentSolution.GetProject(project);
Assert.Equal(null, ps.OutputFilePath);
workspace.OnOutputFilePathChanged(project, "NewPath");
ps = workspace.CurrentSolution.GetProject(project);
Assert.Equal("NewPath", ps.OutputFilePath);
}
private CS.CSharpCompilation CreateCSharpCompilation(string sourceText)
{
MetadataReference mscorlib = new MetadataFileReference(typeof(int).Assembly.Location);
var syntaxTree = CS.SyntaxFactory.ParseSyntaxTree(sourceText);
return (CS.CSharpCompilation)CS.CSharpCompilation.Create("foo.exe").AddReferences(mscorlib).AddSyntaxTrees(syntaxTree);
}
}
}
namespace Roslyn.Services.Host.UnitTests
{
public class TestSolutionFactory : ISolutionFactoryService
{
public ISolution CreateSolution(SolutionId id)
{
return Solution.Create(id);
}
public ISolution CreateSolution(ISolutionInfo info)
{
return Solution.Create(info);
}
}
}
// Copyright (c) Microsoft Open Technologies, Inc. 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.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Threading;
using System.Xml.Linq;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Text;
using Microsoft.CodeAnalysis.UnitTests.SolutionGeneration;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Xunit;
using CS = Microsoft.CodeAnalysis.CSharp;
using VB = Microsoft.CodeAnalysis.VisualBasic;
namespace Microsoft.CodeAnalysis.UnitTests
{
public partial class CustomWorkspaceTests : WorkspaceTestBase
{
[Fact, Trait(Traits.Feature, Traits.Features.Workspace)]
public void TestAddProject_FromCommandLineArgs()
{
CreateFiles(GetSimpleCSharpSolutionFiles());
string commandLine = @"CSharpClass.cs /out:foo.dll /target:library";
var baseDirectory = Path.Combine(this.SolutionDirectory.Path, "CSharpProject");
using (var ws = new CustomWorkspace())
{
var info = CommandLineProject.CreateProjectInfo(ws, "TestProject", LanguageNames.CSharp, commandLine, baseDirectory);
ws.AddProject(info);
var project = ws.CurrentSolution.GetProject(info.Id);
Assert.Equal("TestProject", project.Name);
Assert.Equal("foo", project.AssemblyName);
Assert.Equal(OutputKind.DynamicallyLinkedLibrary, project.CompilationOptions.OutputKind);
Assert.Equal(1, project.Documents.Count());
var fooDoc = project.Documents.First(d => d.Name == "CSharpClass.cs");
Assert.Equal(0, fooDoc.Folders.Count);
var expectedPath = Path.Combine(baseDirectory, "CSharpClass.cs");
Assert.Equal(expectedPath, fooDoc.FilePath);
var text = fooDoc.GetTextAsync().Result.ToString();
Assert.NotEqual("", text);
var tree = fooDoc.GetSyntaxRootAsync().Result;
Assert.Equal(false, tree.ContainsDiagnostics);
var compilation = project.GetCompilationAsync().Result;
}
}
}
}
\ No newline at end of file
// Copyright (c) Microsoft Open Technologies, Inc. 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.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.MSBuild;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Text;
using Microsoft.CodeAnalysis.UnitTests.SolutionGeneration;
using Roslyn.Test.Utilities;
using Xunit;
using VB = Microsoft.CodeAnalysis.VisualBasic;
namespace Microsoft.CodeAnalysis.UnitTests
{
public class MSBuildWorkspaceTestBase : WorkspaceTestBase
{
protected const string MSBuildNamespace = "http://schemas.microsoft.com/developer/msbuild/2003";
protected void AssertOptions<T>(T expected, Func<Microsoft.CodeAnalysis.CSharp.CSharpCompilationOptions, T> actual)
{
var options = LoadCSharpCompilationOptions();
Assert.Equal(expected, actual(options));
}
protected void AssertOptions<T>(T expected, Func<Microsoft.CodeAnalysis.CSharp.CSharpParseOptions, T> actual)
{
var options = LoadCSharpParseOptions();
Assert.Equal(expected, actual(options));
}
protected void AssertVBOptions<T>(T expected, Func<Microsoft.CodeAnalysis.VisualBasic.VisualBasicCompilationOptions, T> actual)
{
var options = LoadVisualBasicCompilationOptions();
Assert.Equal(expected, actual(options));
}
protected void AssertVBOptions<T>(T expected, Func<Microsoft.CodeAnalysis.VisualBasic.VisualBasicParseOptions, T> actual)
{
var options = LoadVisualBasicParseOptions();
Assert.Equal(expected, actual(options));
}
protected Microsoft.CodeAnalysis.CSharp.CSharpCompilationOptions LoadCSharpCompilationOptions()
{
var sol = MSBuildWorkspace.Create().OpenSolutionAsync(GetSolutionFileName("TestSolution.sln")).Result;
var project = sol.Projects.First();
var options = (Microsoft.CodeAnalysis.CSharp.CSharpCompilationOptions)project.CompilationOptions;
return options;
}
protected Microsoft.CodeAnalysis.CSharp.CSharpParseOptions LoadCSharpParseOptions()
{
var sol = MSBuildWorkspace.Create().OpenSolutionAsync(GetSolutionFileName("TestSolution.sln")).Result;
var project = sol.Projects.First();
var options = (Microsoft.CodeAnalysis.CSharp.CSharpParseOptions)project.ParseOptions;
return options;
}
protected Microsoft.CodeAnalysis.VisualBasic.VisualBasicCompilationOptions LoadVisualBasicCompilationOptions()
{
var sol = MSBuildWorkspace.Create().OpenSolutionAsync(GetSolutionFileName("TestSolution.sln")).Result;
var project = sol.GetProjectsByName("VisualBasicProject").FirstOrDefault();
var options = (Microsoft.CodeAnalysis.VisualBasic.VisualBasicCompilationOptions)project.CompilationOptions;
return options;
}
protected Microsoft.CodeAnalysis.VisualBasic.VisualBasicParseOptions LoadVisualBasicParseOptions()
{
var sol = MSBuildWorkspace.Create().OpenSolutionAsync(GetSolutionFileName("TestSolution.sln")).Result;
var project = sol.GetProjectsByName("VisualBasicProject").FirstOrDefault();
var options = (Microsoft.CodeAnalysis.VisualBasic.VisualBasicParseOptions)project.ParseOptions;
return options;
}
protected void PrepareCrossLanguageProjectWithEmittedMetadata()
{
// Now try variant of CSharpProject that has an emitted assembly
CreateFiles(GetMultiProjectSolutionFiles()
.WithFile(@"CSharpProject\CSharpProject.csproj", GetResourceText("CSharpProject_CSharpProject_ForEmittedOutput.csproj")));
var sol = MSBuildWorkspace.Create().OpenSolutionAsync(GetSolutionFileName("TestSolution.sln")).Result;
var p1 = sol.Projects.First(p => p.Language == LanguageNames.CSharp);
var p2 = sol.Projects.First(p => p.Language == LanguageNames.VisualBasic);
Assert.NotNull(p1.OutputFilePath);
Assert.Equal("EmittedCSharpProject.dll", Path.GetFileName(p1.OutputFilePath));
// if the assembly doesn't already exist, emit it now
if (!File.Exists(p1.OutputFilePath))
{
var c1 = p1.GetCompilationAsync().Result;
var result = c1.Emit(p1.OutputFilePath);
Assert.Equal(true, result.Success);
}
}
protected Solution Solution(params IBuilder[] inputs)
{
var files = GetSolutionFiles(inputs);
CreateFiles(files);
var solutionFileName = files.First(kvp => kvp.Key.EndsWith(".sln", StringComparison.OrdinalIgnoreCase)).Key;
solutionFileName = GetSolutionFileName(solutionFileName);
var solution = MSBuildWorkspace.Create().OpenSolutionAsync(solutionFileName).Result;
return solution;
}
}
}
......@@ -7,7 +7,9 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Host.UnitTests;
using Microsoft.CodeAnalysis.MSBuild;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.UnitTests
......@@ -57,5 +59,19 @@ public static IEnumerable<Project> GetProjectsByName(this Solution solution, str
{
return solution.Projects.Where(p => string.Compare(p.Name, name, StringComparison.OrdinalIgnoreCase) == 0);
}
internal static EventWaiter VerifyWorkspaceChangedEvent(this Workspace workspace, Action<WorkspaceChangeEventArgs> action)
{
var wew = new EventWaiter();
workspace.WorkspaceChanged += wew.Wrap<WorkspaceChangeEventArgs>((sender, args) => action(args));
return wew;
}
internal static EventWaiter VerifyWorkspaceFailedEvent(this Workspace workspace, Action<WorkspaceDiagnosticEventArgs> action)
{
var wew = new EventWaiter();
workspace.WorkspaceFailed += wew.Wrap<WorkspaceDiagnosticEventArgs>((sender, args) => action(args));
return wew;
}
}
}
\ No newline at end of file
......@@ -7,7 +7,6 @@
using System.IO;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.MSBuild;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Test.Utilities;
......@@ -16,29 +15,32 @@
namespace Microsoft.CodeAnalysis.UnitTests
{
public partial class MSBuildWorkspaceTests
public partial class WorkspaceTestBase : TestBase
{
private readonly TempDirectory solutionDirectory;
protected readonly TempDirectory SolutionDirectory;
private static readonly TimeSpan asyncEventTimeout = TimeSpan.FromMinutes(5);
protected static readonly TimeSpan AsyncEventTimeout = TimeSpan.FromMinutes(5);
public MSBuildWorkspaceTests()
public WorkspaceTestBase()
{
solutionDirectory = Temp.CreateDirectory();
this.SolutionDirectory = Temp.CreateDirectory();
}
/// <summary>
/// Gets an absolute file name for a file relative to the tests solution directory.
/// </summary>
public string GetSolutionFileName(string relativeFileName)
{
return Path.Combine(this.solutionDirectory.Path, relativeFileName);
return Path.Combine(this.SolutionDirectory.Path, relativeFileName);
}
private void CreateFiles(params string[] fileNames)
protected void CreateFiles(params string[] fileNames)
{
var dictionary = fileNames.ToDictionary(id => id, fileName => (object)GetResourceText(fileName));
CreateFiles(new FileSet(dictionary));
}
private void CreateFiles(IEnumerable<KeyValuePair<string, object>> fileNameAndContentPairs)
protected void CreateFiles(IEnumerable<KeyValuePair<string, object>> fileNameAndContentPairs)
{
foreach (var pair in fileNameAndContentPairs)
{
......@@ -47,7 +49,7 @@ private void CreateFiles(IEnumerable<KeyValuePair<string, object>> fileNameAndCo
var subdirectory = Path.GetDirectoryName(pair.Key);
var fileName = Path.GetFileName(pair.Key);
var dir = solutionDirectory;
var dir = SolutionDirectory;
if (!string.IsNullOrEmpty(subdirectory))
{
......@@ -68,87 +70,25 @@ private void CreateFiles(IEnumerable<KeyValuePair<string, object>> fileNameAndCo
}
}
private void CreateCSharpFilesWith(string propertyName, string value)
protected void CreateCSharpFilesWith(string propertyName, string value)
{
CreateFiles(GetSimpleCSharpSolutionFiles()
.WithFile(@"CSharpProject\CSharpProject.csproj", GetResourceText(@"CSharpProject_CSharpProject_AllOptions.csproj"))
.ReplaceFileElement(@"CSharpProject\CSharpProject.csproj", propertyName, value));
}
private void CreateVBFilesWith(string propertyName, string value)
protected void CreateVBFilesWith(string propertyName, string value)
{
CreateFiles(GetMultiProjectSolutionFiles()
.ReplaceFileElement(@"VisualBasicProject\VisualBasicProject.vbproj", propertyName, value));
}
private void CreateCSharpFiles()
protected void CreateCSharpFiles()
{
CreateFiles(GetSimpleCSharpSolutionFiles());
}
private void AssertOptions<T>(T expected, Func<Microsoft.CodeAnalysis.CSharp.CSharpCompilationOptions, T> actual)
{
var options = LoadCSharpCompilationOptions();
Assert.Equal(expected, actual(options));
}
private void AssertOptions<T>(T expected, Func<Microsoft.CodeAnalysis.CSharp.CSharpParseOptions, T> actual)
{
var options = LoadCSharpParseOptions();
Assert.Equal(expected, actual(options));
}
private void AssertVBOptions<T>(T expected, Func<Microsoft.CodeAnalysis.VisualBasic.VisualBasicCompilationOptions, T> actual)
{
var options = LoadVisualBasicCompilationOptions();
Assert.Equal(expected, actual(options));
}
private void AssertVBOptions<T>(T expected, Func<Microsoft.CodeAnalysis.VisualBasic.VisualBasicParseOptions, T> actual)
{
var options = LoadVisualBasicParseOptions();
Assert.Equal(expected, actual(options));
}
private Solution LoadSolution(string solutionFilePath, IDictionary<string, string> properties = null)
{
var ws = MSBuildWorkspace.Create(properties ?? ImmutableDictionary<string, string>.Empty);
return ws.OpenSolutionAsync(solutionFilePath).Result;
}
private Microsoft.CodeAnalysis.CSharp.CSharpCompilationOptions LoadCSharpCompilationOptions()
{
var sol = LoadSolution(GetSolutionFileName("TestSolution.sln"));
var project = sol.Projects.First();
var options = (Microsoft.CodeAnalysis.CSharp.CSharpCompilationOptions)project.CompilationOptions;
return options;
}
private Microsoft.CodeAnalysis.CSharp.CSharpParseOptions LoadCSharpParseOptions()
{
var sol = LoadSolution(GetSolutionFileName("TestSolution.sln"));
var project = sol.Projects.First();
var options = (Microsoft.CodeAnalysis.CSharp.CSharpParseOptions)project.ParseOptions;
return options;
}
private Microsoft.CodeAnalysis.VisualBasic.VisualBasicCompilationOptions LoadVisualBasicCompilationOptions()
{
var sol = LoadSolution(GetSolutionFileName("TestSolution.sln"));
var project = sol.GetProjectsByName("VisualBasicProject").FirstOrDefault();
var options = (Microsoft.CodeAnalysis.VisualBasic.VisualBasicCompilationOptions)project.CompilationOptions;
return options;
}
private Microsoft.CodeAnalysis.VisualBasic.VisualBasicParseOptions LoadVisualBasicParseOptions()
{
var sol = LoadSolution(GetSolutionFileName("TestSolution.sln"));
var project = sol.GetProjectsByName("VisualBasicProject").FirstOrDefault();
var options = (Microsoft.CodeAnalysis.VisualBasic.VisualBasicParseOptions)project.ParseOptions;
return options;
}
private FileSet GetSimpleCSharpSolutionFiles()
protected FileSet GetSimpleCSharpSolutionFiles()
{
return new FileSet(new Dictionary<string, object>
{
......@@ -159,7 +99,7 @@ private FileSet GetSimpleCSharpSolutionFiles()
});
}
private FileSet GetMultiProjectSolutionFiles()
protected FileSet GetMultiProjectSolutionFiles()
{
return new FileSet(new Dictionary<string, object>
{
......@@ -179,7 +119,7 @@ private FileSet GetMultiProjectSolutionFiles()
});
}
private FileSet GetProjectReferenceSolutionFiles()
protected FileSet GetProjectReferenceSolutionFiles()
{
return new FileSet(new Dictionary<string, object>
{
......@@ -192,7 +132,7 @@ private FileSet GetProjectReferenceSolutionFiles()
});
}
private FileSet GetAnalyzerReferenceSolutionFiles()
protected FileSet GetAnalyzerReferenceSolutionFiles()
{
return new FileSet(new Dictionary<string, object>
{
......@@ -212,7 +152,7 @@ private FileSet GetAnalyzerReferenceSolutionFiles()
});
}
private FileSet GetSolutionWithDuplicatedGuidFiles()
protected FileSet GetSolutionWithDuplicatedGuidFiles()
{
return new FileSet(new Dictionary<string, object>
{
......@@ -257,36 +197,15 @@ public static string GetResourceText(string fileName)
}
}
private void PrepareCrossLanguageProjectWithEmittedMetadata()
{
// Now try variant of CSharpProject that has an emitted assembly
CreateFiles(GetMultiProjectSolutionFiles()
.WithFile(@"CSharpProject\CSharpProject.csproj", GetResourceText("CSharpProject_CSharpProject_ForEmittedOutput.csproj")));
var sol = LoadSolution(GetSolutionFileName("TestSolution.sln"));
var p1 = sol.Projects.First(p => p.Language == LanguageNames.CSharp);
var p2 = sol.Projects.First(p => p.Language == LanguageNames.VisualBasic);
Assert.NotNull(p1.OutputFilePath);
Assert.Equal("EmittedCSharpProject.dll", Path.GetFileName(p1.OutputFilePath));
// if the assembly doesn't already exist, emit it now
if (!File.Exists(p1.OutputFilePath))
{
var c1 = p1.GetCompilationAsync().Result;
var result = c1.Emit(p1.OutputFilePath);
Assert.Equal(true, result.Success);
}
}
private static string GetParentDirOfParentDirOfContainingDir(string fileName)
protected static string GetParentDirOfParentDirOfContainingDir(string fileName)
{
string containingDir = Directory.GetParent(fileName).FullName;
string parentOfContainingDir = Directory.GetParent(containingDir).FullName;
return Directory.GetParent(parentOfContainingDir).FullName;
}
private static void AssertThrows<TException>(Action action)
protected static void AssertThrows<TException>(Action action, Action<TException> checker = null)
where TException : Exception
{
try
{
......@@ -301,10 +220,15 @@ private static void AssertThrows<TException>(Action action)
}
Assert.Equal(typeof(TException), e.GetType());
if (checker != null)
{
checker((TException)e);
}
}
}
private int GetMethodInsertionPoint(VB.Syntax.ClassBlockSyntax cb)
protected int GetMethodInsertionPoint(VB.Syntax.ClassBlockSyntax cb)
{
if (cb.Implements.Count > 0)
{
......@@ -320,7 +244,7 @@ private int GetMethodInsertionPoint(VB.Syntax.ClassBlockSyntax cb)
}
}
private Document AssertSemanticVersionChanged(Document document, SourceText newText)
protected Document AssertSemanticVersionChanged(Document document, SourceText newText)
{
var docVersion = document.GetTopLevelChangeTextVersionAsync().Result;
var projVersion = document.Project.GetSemanticVersionAsync().Result;
......@@ -337,7 +261,7 @@ private Document AssertSemanticVersionChanged(Document document, SourceText newT
return newDoc;
}
private Document AssertSemanticVersionUnchanged(Document document, SourceText newText)
protected Document AssertSemanticVersionUnchanged(Document document, SourceText newText)
{
var docVersion = document.GetTopLevelChangeTextVersionAsync().Result;
var projVersion = document.Project.GetSemanticVersionAsync().Result;
......
......@@ -26,16 +26,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Get
End Property
Private Shared ReadOnly projectTypeGuid As Guid = New Guid("F184B08F-C81C-45F6-A57F-5ABD9991F28F")
Public Overrides Function IsProjectTypeGuid(guid As Guid) As Boolean
Return guid = projectTypeGuid
End Function
Public Overrides Function IsProjectFileExtension(fileExtension As String) As Boolean
Return String.Equals("vbproj", fileExtension, StringComparison.OrdinalIgnoreCase)
End Function
Protected Overrides Function CreateProjectFile(loadedProject As MSB.Evaluation.Project) As ProjectFile
Return New VisualBasicProjectFile(Me, loadedProject, Me._workspaceServices.GetService(Of IMetadataReferenceProviderService))
End Function
......@@ -85,10 +75,13 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Dim analyzerReferences As IEnumerable(Of AnalyzerReference) = Nothing
GetReferences(compilerInputs, executedProject, metadataReferences, analyzerReferences)
Dim outputPath = Path.Combine(Me.GetOutputDirectory(), compilerInputs.OutputFileName)
Dim assemblyName = Me.GetAssemblyName()
Return New ProjectFileInfo(
Me.Guid,
Me.GetTargetPath(),
Me.GetAssemblyName(),
outputPath,
assemblyName,
compilerInputs.CompilationOptions,
compilerInputs.ParseOptions.WithPreprocessorSymbols(AddPredefinedPreprocessorSymbols(
compilerInputs.CompilationOptions.OutputKind, compilerInputs.ParseOptions.PreprocessorSymbols)),
......@@ -275,12 +268,13 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Private _targetCompactFramework As Boolean
Private _vbRuntime As String
Private _libPaths As IEnumerable(Of String)
Private _outputFileName As String
Public Sub New(projectFile As VisualBasicProjectFile)
Me._projectFile = projectFile
Me._parseOptions = VisualBasicParseOptions.Default.WithDocumentationMode(DocumentationMode.Parse)
Dim projectDirectory = Path.GetDirectoryName(projectFile.FilePath)
Dim outputDirectory = If(Not String.IsNullOrEmpty(projectFile.GetTargetPath()), Path.GetDirectoryName(projectFile.GetTargetPath()), Nothing)
Dim outputDirectory = projectFile.GetOutputDirectory()
Me._compilationOptions = New VisualBasicCompilationOptions(OutputKind.ConsoleApplication,
debugInformationKind:=DebugInformationKind.None,
xmlReferenceResolver:=New XmlFileResolver(projectDirectory),
......@@ -361,6 +355,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Get
End Property
Public ReadOnly Property OutputFileName As String
Get
Return Me._outputFileName
End Get
End Property
Public Sub BeginInitialization() Implements Microsoft.Build.Tasks.Hosting.IVbcHostObject.BeginInitialization
End Sub
......@@ -547,6 +547,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Function
Public Function SetOutputAssembly(outputAssembly As String) As Boolean Implements Microsoft.Build.Tasks.Hosting.IVbcHostObject.SetOutputAssembly
Me._outputFileName = Path.GetFileName(outputAssembly)
Return True
End Function
......
......@@ -12,6 +12,8 @@ Imports MSB = Microsoft.Build
Namespace Microsoft.CodeAnalysis.VisualBasic
<ExportLanguageServiceFactory(GetType(IProjectFileLoader), LanguageNames.VisualBasic)>
<ProjectFileExtension("vbproj")>
<ProjectTypeGuid("F184B08F-C81C-45F6-A57F-5ABD9991F28F")>
Friend Class VisualBasicProjectFileLoaderFactory
Implements ILanguageServiceFactory
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册