Inline unsafe ambients when arguments are literals (#907)

This commit is contained in:
Iman Narasamdya 2019-09-20 10:23:40 -07:00 коммит произвёл GitHub
Родитель 16792bb60a
Коммит edb30886a2
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 96 добавлений и 21 удалений

Просмотреть файл

@ -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
}
}