зеркало из https://github.com/microsoft/BuildXL.git
Inline unsafe ambients when arguments are literals (#907)
This commit is contained in:
Родитель
16792bb60a
Коммит
edb30886a2
|
@ -14,13 +14,13 @@ namespace BuildXL.FrontEnd.Script.Ambients
|
|||
/// </summary>
|
||||
public sealed class AmbientUnsafe : AmbientDefinitionBase
|
||||
{
|
||||
private const string UnsafeName = "Unsafe";
|
||||
private const string OutputFile = "outputFile";
|
||||
private const string ExOutputDirectory = "exOutputDirectory";
|
||||
private const string UnsafeNamespace = Constants.Names.UnsafeNamespace;
|
||||
private const string OutputFile = Constants.Names.UnsafeOutputFile;
|
||||
private const string ExOutputDirectory = Constants.Names.UnsafeExOutputDirectory;
|
||||
|
||||
/// <nodoc />
|
||||
public AmbientUnsafe(PrimitiveTypes knownTypes)
|
||||
: base(UnsafeName, knownTypes)
|
||||
: base(UnsafeNamespace, knownTypes)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ namespace BuildXL.FrontEnd.Script.Ambients
|
|||
protected override AmbientNamespaceDefinition? GetNamespaceDefinition()
|
||||
{
|
||||
return new AmbientNamespaceDefinition(
|
||||
UnsafeName,
|
||||
UnsafeNamespace,
|
||||
new[]
|
||||
{
|
||||
Function(OutputFile, UnsafeOutputFile, UnsafeOutputFileSignature),
|
||||
|
|
|
@ -43,6 +43,16 @@ namespace BuildXL.FrontEnd.Script.Literals
|
|||
Value = FileArtifact.CreateSourceFile(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor that takes path literal and rewrite count.
|
||||
/// </summary>
|
||||
public FileLiteral(AbsolutePath value, int rewriteCount, LineInfo location)
|
||||
: base(location)
|
||||
{
|
||||
Contract.Requires(value.IsValid);
|
||||
Value = new FileArtifact(value, rewriteCount);
|
||||
}
|
||||
|
||||
/// <nodoc />
|
||||
public FileLiteral(DeserializationContext context, LineInfo location)
|
||||
: base(location)
|
||||
|
|
|
@ -22,6 +22,10 @@ namespace BuildXL.FrontEnd.Script.RuntimeModel.AstBridge
|
|||
internal readonly SymbolAtom TemplateReference;
|
||||
internal readonly SymbolAtom RuntimeRootNamespaceSymbol;
|
||||
|
||||
internal readonly FullSymbol UnsafeNamespace;
|
||||
internal readonly SymbolAtom UnsafeOutputFile;
|
||||
internal readonly SymbolAtom UnsafeExOutputDirectory;
|
||||
|
||||
public AstConversionContext(
|
||||
RuntimeModelContext runtimeModelContext,
|
||||
AbsolutePath currentSpecPath,
|
||||
|
@ -40,12 +44,15 @@ namespace BuildXL.FrontEnd.Script.RuntimeModel.AstBridge
|
|||
ModuleKeyword = CreateSymbol(Constants.Names.ModuleConfigurationFunctionCall);
|
||||
TemplateReference = CreateSymbol(Constants.Names.TemplateReference);
|
||||
RuntimeRootNamespaceSymbol = CreateSymbol(Constants.Names.RuntimeRootNamespaceAlias);
|
||||
|
||||
UnsafeNamespace = CreateFullSymbol(Constants.Names.UnsafeNamespace);
|
||||
UnsafeOutputFile = CreateSymbol(Constants.Names.UnsafeOutputFile);
|
||||
UnsafeExOutputDirectory = CreateSymbol(Constants.Names.UnsafeExOutputDirectory);
|
||||
}
|
||||
|
||||
private SymbolAtom CreateSymbol(string name)
|
||||
{
|
||||
return SymbolAtom.Create(RuntimeModelContext.StringTable, name);
|
||||
}
|
||||
private SymbolAtom CreateSymbol(string name) => SymbolAtom.Create(RuntimeModelContext.StringTable, name);
|
||||
|
||||
private FullSymbol CreateFullSymbol(string name) => FullSymbol.Create(RuntimeModelContext.SymbolTable, name);
|
||||
|
||||
public RuntimeModelContext RuntimeModelContext { get; }
|
||||
|
||||
|
|
|
@ -2511,26 +2511,65 @@ namespace BuildXL.FrontEnd.Script.RuntimeModel.AstBridge
|
|||
}
|
||||
|
||||
var selector = functor as SelectorExpressionBase;
|
||||
if (selector?.Selector == m_conversionContext.WithQualifierKeyword)
|
||||
if (selector != null)
|
||||
{
|
||||
Contract.Assert(arguments.Length != 0, "withQualifier should have at least one argument.");
|
||||
var qualifierExpression = arguments[0];
|
||||
if (selector.Selector == m_conversionContext.WithQualifierKeyword)
|
||||
{
|
||||
Contract.Assert(arguments.Length != 0, "withQualifier should have at least one argument.");
|
||||
var qualifierExpression = arguments[0];
|
||||
|
||||
var resolvedSymbol = ResolveSymbolAtPositionAndReportWarningIfObsolete(source.Expression);
|
||||
Contract.Assert(resolvedSymbol != null);
|
||||
var targetQualifierSpaceId = ExtractSourceQualifierSpace(resolvedSymbol);
|
||||
var resolvedSymbol = ResolveSymbolAtPositionAndReportWarningIfObsolete(source.Expression);
|
||||
Contract.Assert(resolvedSymbol != null);
|
||||
var targetQualifierSpaceId = ExtractSourceQualifierSpace(resolvedSymbol);
|
||||
|
||||
return new WithQualifierExpression(
|
||||
selector.ThisExpression,
|
||||
qualifierExpression,
|
||||
sourceQualifierSpaceId: context.CurrentQualifierSpaceId,
|
||||
targetQualifierSpaceId: targetQualifierSpaceId,
|
||||
location: Location(source));
|
||||
return new WithQualifierExpression(
|
||||
selector.ThisExpression,
|
||||
qualifierExpression,
|
||||
sourceQualifierSpaceId: context.CurrentQualifierSpaceId,
|
||||
targetQualifierSpaceId: targetQualifierSpaceId,
|
||||
location: Location(source));
|
||||
}
|
||||
|
||||
if (selector.ThisExpression is ModuleIdExpression moduleIdExpression
|
||||
&& moduleIdExpression.Name == m_conversionContext.UnsafeNamespace)
|
||||
{
|
||||
Expression inlineExpression = TryInlineUnsafeCall(source, selector, arguments);
|
||||
|
||||
if (inlineExpression != null)
|
||||
{
|
||||
return inlineExpression;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ApplyExpression.Create(functor, typeArguments, arguments, Location(source));
|
||||
}
|
||||
|
||||
private Expression TryInlineUnsafeCall(INode source, SelectorExpressionBase selector, Expression[] arguments)
|
||||
{
|
||||
if (arguments.Length == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!(arguments[0] is PathLiteral path))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (selector.Selector == m_conversionContext.UnsafeOutputFile)
|
||||
{
|
||||
int rewriteCount = arguments.Length > 1 && arguments[1] is NumberLiteral rc ? rc.UnboxedValue : 1;
|
||||
return new FileLiteral(path.Value, rewriteCount, Location(source));
|
||||
}
|
||||
else if (selector.Selector == m_conversionContext.UnsafeExOutputDirectory)
|
||||
{
|
||||
return new DirectoryLiteralExpression(path, Location(source));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private bool IsObsolete(ISymbol symbol, out string message)
|
||||
{
|
||||
foreach (var declaration in symbol.DeclarationList)
|
||||
|
|
|
@ -288,5 +288,24 @@ namespace BuildXL.FrontEnd.Script.Constants
|
|||
public const string ConfigModuleName = "__ConfigModule__";
|
||||
|
||||
#endregion Packages
|
||||
|
||||
#region Unsafe
|
||||
|
||||
/// <summary>
|
||||
/// Unsafe namespace.
|
||||
/// </summary>
|
||||
public const string UnsafeNamespace = "Unsafe";
|
||||
|
||||
/// <summary>
|
||||
/// Unsafe output file.
|
||||
/// </summary>
|
||||
public const string UnsafeOutputFile = "outputFile";
|
||||
|
||||
/// <summary>
|
||||
/// Unsafe exclusive output directory.
|
||||
/// </summary>
|
||||
public const string UnsafeExOutputDirectory = "exOutputDirectory";
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче