e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
316 lines
10 KiB
C#
316 lines
10 KiB
C#
//------------------------------------------------------------
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//------------------------------------------------------------
|
|
|
|
namespace Microsoft.Build.Tasks.Xaml
|
|
{
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Runtime;
|
|
using Microsoft.Build.Framework;
|
|
using Microsoft.Build.Utilities;
|
|
using XamlBuildTask;
|
|
|
|
[Fx.Tag.XamlVisible(true)]
|
|
public class CompilationPass2Task : Task
|
|
{
|
|
List<ITaskItem> generatedCodeFiles = new List<ITaskItem>();
|
|
|
|
// We will do Dev10 behavior if NONE of the new required properties are specified. This can happen
|
|
// if a Dev10 version of the Microsoft.Xaml.Targets file is being used with Dev11 installed.
|
|
// The new required properties for Dev11 are:
|
|
// Language
|
|
// OutputPath
|
|
// MSBuildProjectDirectory
|
|
// ApplicationMarkupWithTypeName
|
|
//
|
|
// If ANY of these are specified, then ALL must be specified.
|
|
bool supportExtensions = false;
|
|
string language;
|
|
string outputPath;
|
|
string msBuildProjectDirectory;
|
|
ITaskItem[] applicationMarkupWithTypeName;
|
|
|
|
public CompilationPass2Task()
|
|
{
|
|
}
|
|
|
|
[Fx.Tag.KnownXamlExternal]
|
|
public ITaskItem[] ApplicationMarkup { get; set; }
|
|
|
|
public string AssemblyName
|
|
{ get; set; }
|
|
|
|
[Fx.Tag.KnownXamlExternal]
|
|
public ITaskItem[] References { get; set; }
|
|
|
|
// Required in Dev11, but for backward compatibility with a Dev10 targets file, not marking as required.
|
|
public string Language
|
|
{
|
|
get
|
|
{
|
|
return this.language;
|
|
}
|
|
|
|
set
|
|
{
|
|
this.language = value;
|
|
this.supportExtensions = true;
|
|
}
|
|
}
|
|
|
|
// Required in Dev11, but for backward compatibility with a Dev10 targets file, not marking as required.
|
|
public string OutputPath
|
|
{
|
|
get
|
|
{
|
|
return this.outputPath;
|
|
}
|
|
|
|
set
|
|
{
|
|
this.outputPath = value;
|
|
this.supportExtensions = true;
|
|
}
|
|
}
|
|
|
|
// Required in Dev11, but for backward compatibility with a Dev10 targets file, not marking as required.
|
|
public string MSBuildProjectDirectory
|
|
{
|
|
get
|
|
{
|
|
return this.msBuildProjectDirectory;
|
|
}
|
|
|
|
set
|
|
{
|
|
this.msBuildProjectDirectory = value;
|
|
this.supportExtensions = true;
|
|
}
|
|
}
|
|
|
|
public bool IsInProcessXamlMarkupCompile
|
|
{ get; set; }
|
|
|
|
[Fx.Tag.KnownXamlExternal]
|
|
public ITaskItem[] SourceCodeFiles
|
|
{ get; set; }
|
|
|
|
public ITaskItem[] XamlBuildTypeInspectionExtensionNames
|
|
{ get; set; }
|
|
|
|
// Required in Dev11, but for backward compatibility with a Dev10 targets file, not marking as required.
|
|
public ITaskItem[] ApplicationMarkupWithTypeName
|
|
{
|
|
get
|
|
{
|
|
return this.applicationMarkupWithTypeName;
|
|
}
|
|
|
|
set
|
|
{
|
|
this.applicationMarkupWithTypeName = value;
|
|
this.supportExtensions = true;
|
|
}
|
|
}
|
|
|
|
public string LocalAssemblyReference
|
|
{ get; set; }
|
|
|
|
public string RootNamespace
|
|
{ get; set; }
|
|
|
|
public string BuildTaskPath
|
|
{ get; set; }
|
|
|
|
[Output]
|
|
public ITaskItem[] ExtensionGeneratedCodeFiles
|
|
{
|
|
get
|
|
{
|
|
return generatedCodeFiles.ToArray();
|
|
}
|
|
set
|
|
{
|
|
generatedCodeFiles = new List<ITaskItem>(value);
|
|
}
|
|
}
|
|
|
|
public override bool Execute()
|
|
{
|
|
AppDomain appDomain = null;
|
|
|
|
try
|
|
{
|
|
ValidateRequiredDev11Properties();
|
|
|
|
appDomain = XamlBuildTaskServices.CreateAppDomain("CompilationPass2AppDomain_" + Guid.NewGuid(), BuildTaskPath);
|
|
|
|
CompilationPass2TaskInternal wrapper = (CompilationPass2TaskInternal)appDomain.CreateInstanceAndUnwrap(
|
|
Assembly.GetExecutingAssembly().FullName,
|
|
typeof(CompilationPass2TaskInternal).FullName);
|
|
|
|
PopulateBuildArtifacts(wrapper);
|
|
|
|
bool ret = wrapper.Execute();
|
|
|
|
ExtractBuiltArtifacts(wrapper);
|
|
|
|
if (!ret)
|
|
{
|
|
foreach (LogData logData in wrapper.LogData)
|
|
{
|
|
XamlBuildTaskServices.LogException(
|
|
this.Log,
|
|
logData.Message,
|
|
logData.FileName,
|
|
logData.LineNumber,
|
|
logData.LinePosition);
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
if (Fx.IsFatal(e))
|
|
{
|
|
throw;
|
|
}
|
|
|
|
XamlBuildTaskServices.LogException(this.Log, e.Message);
|
|
return false;
|
|
}
|
|
finally
|
|
{
|
|
if (appDomain != null)
|
|
{
|
|
AppDomain.Unload(appDomain);
|
|
}
|
|
}
|
|
}
|
|
|
|
string SeparateWithComma(string originalString, string stringToAppend)
|
|
{
|
|
if (!String.IsNullOrEmpty(originalString))
|
|
{
|
|
return String.Join(", ", originalString, stringToAppend);
|
|
}
|
|
else
|
|
{
|
|
return stringToAppend;
|
|
}
|
|
}
|
|
|
|
void ValidateRequiredDev11Properties()
|
|
{
|
|
if (this.supportExtensions)
|
|
{
|
|
string requiredPropertiesNotSpecified = "";
|
|
if (this.language == null)
|
|
{
|
|
requiredPropertiesNotSpecified = SeparateWithComma(requiredPropertiesNotSpecified, "Language");
|
|
}
|
|
if (this.outputPath == null)
|
|
{
|
|
requiredPropertiesNotSpecified = SeparateWithComma(requiredPropertiesNotSpecified, "OutputPath");
|
|
}
|
|
if (this.msBuildProjectDirectory == null)
|
|
{
|
|
requiredPropertiesNotSpecified = SeparateWithComma(requiredPropertiesNotSpecified, "MSBuildProjectDirectory");
|
|
}
|
|
if (this.applicationMarkupWithTypeName == null)
|
|
{
|
|
requiredPropertiesNotSpecified = SeparateWithComma(requiredPropertiesNotSpecified, "ApplicationMarkupWithTypeName");
|
|
}
|
|
if (!String.IsNullOrEmpty(requiredPropertiesNotSpecified))
|
|
{
|
|
throw FxTrace.Exception.AsError(new InvalidOperationException(SR.MissingRequiredParametersCompilationPass2Task(requiredPropertiesNotSpecified)));
|
|
}
|
|
}
|
|
}
|
|
|
|
void PopulateBuildArtifacts(CompilationPass2TaskInternal wrapper)
|
|
{
|
|
if (!this.supportExtensions)
|
|
{
|
|
IList<string> applicationMarkup = new List<string>(this.ApplicationMarkup.Length);
|
|
foreach (ITaskItem taskItem in this.ApplicationMarkup)
|
|
{
|
|
applicationMarkup.Add(taskItem.ItemSpec);
|
|
}
|
|
wrapper.ApplicationMarkup = applicationMarkup;
|
|
}
|
|
|
|
wrapper.SupportExtensions = this.supportExtensions;
|
|
|
|
wrapper.BuildLogger = this.Log;
|
|
|
|
wrapper.References = this.References
|
|
.Select(i => new DelegatingTaskItem(i) as ITaskItem).ToList();
|
|
|
|
wrapper.LocalAssemblyReference = this.LocalAssemblyReference;
|
|
|
|
wrapper.AssemblyName = this.AssemblyName;
|
|
|
|
wrapper.RootNamespace = this.RootNamespace;
|
|
|
|
wrapper.Language = this.Language;
|
|
|
|
wrapper.OutputPath = this.OutputPath;
|
|
|
|
wrapper.IsInProcessXamlMarkupCompile = this.IsInProcessXamlMarkupCompile;
|
|
|
|
wrapper.MSBuildProjectDirectory = this.MSBuildProjectDirectory;
|
|
|
|
IList<string> sourceCodeFiles = null;
|
|
if (this.SourceCodeFiles != null)
|
|
{
|
|
sourceCodeFiles = new List<string>(this.SourceCodeFiles.Length);
|
|
foreach (ITaskItem taskItem in this.SourceCodeFiles)
|
|
{
|
|
sourceCodeFiles.Add(taskItem.ItemSpec);
|
|
}
|
|
}
|
|
wrapper.SourceCodeFiles = sourceCodeFiles;
|
|
|
|
if (this.supportExtensions)
|
|
{
|
|
wrapper.XamlBuildTaskTypeInspectionExtensionNames = XamlBuildTaskServices.GetXamlBuildTaskExtensionNames(this.XamlBuildTypeInspectionExtensionNames);
|
|
|
|
// Here we create a Dictionary of Type Full Name and corresponding TaskItem
|
|
// This is passed to the extensions which enables them to look up
|
|
// metadata about a type like file name.
|
|
IDictionary<string, ITaskItem> applicationMarkupWithTypeName = null;
|
|
if (this.ApplicationMarkupWithTypeName != null)
|
|
{
|
|
applicationMarkupWithTypeName = new Dictionary<string, ITaskItem>();
|
|
}
|
|
foreach (ITaskItem taskItem in this.ApplicationMarkupWithTypeName)
|
|
{
|
|
string typeName = taskItem.GetMetadata("typeName");
|
|
if (!String.IsNullOrWhiteSpace(typeName))
|
|
{
|
|
applicationMarkupWithTypeName.Add(typeName, new DelegatingTaskItem(taskItem));
|
|
}
|
|
}
|
|
wrapper.ApplicationMarkupWithTypeName = applicationMarkupWithTypeName;
|
|
}
|
|
}
|
|
|
|
void ExtractBuiltArtifacts(CompilationPass2TaskInternal wrapper)
|
|
{
|
|
if (wrapper.GeneratedCodeFiles == null)
|
|
{
|
|
return;
|
|
}
|
|
foreach (string code in wrapper.GeneratedCodeFiles)
|
|
{
|
|
this.generatedCodeFiles.Add(new TaskItem(code));
|
|
}
|
|
}
|
|
}
|
|
}
|