private static EvaluationResult Sum(Context context, ModuleLiteral env, EvaluationStackFrame args) { // The checker should make sure that the function takes numbers. var values = Args.AsArrayLiteral(args, 0).Values.Select(v => (int)v.Value).ToList(); return(DoMath(() => checked (values.Sum()))); }
private static EvaluationResult ReadGraphFragment(Context context, ModuleLiteral env, EvaluationStackFrame args) { var file = Args.AsFile(args, 0); var deps = Args.AsArrayLiteral(args, 1).Values.Select(v => (AbsolutePath)v.Value).ToArray(); var description = Args.AsStringOptional(args, 2) ?? file.Path.ToString(context.PathTable); if (!file.IsSourceFile) { // Do not read output file. throw new FileOperationException( new Exception( I($"Failed adding pip graph fragment file '{file.Path.ToString(context.PathTable)}' because the file is not a source file"))); } if (!context.FrontEndContext.FileSystem.Exists(file.Path)) { throw new FileOperationException(new FileNotFoundException(I($"File '{file.Path.ToString(context.PathTable)}' does not exist"))); } // Record the file, so that its content is tracked by input tracker. context.FrontEndHost.Engine.RecordFrontEndFile(file.Path, "DScript"); int id = Interlocked.Increment(ref s_uniqueFragmentId); var readFragmentResult = context.FrontEndHost.PipGraphFragmentManager.AddFragmentFileToGraph(file, description, deps); if (!readFragmentResult) { return(EvaluationResult.Error); } return(EvaluationResult.Create(file.Path)); }
/// <summary> /// Implements path interpolation /// </summary> public static EvaluationResult Interpolate(ImmutableContextBase context, ModuleLiteral env, EvaluationStackFrame args) { // TODO: Path.interpolate(x, y, z) is similar to x.combinePaths(y, z). The latter can be slightly more efficient because no look-up for "Path" identifier. Args.CheckArgumentIndex(args, 1); var rest = Args.AsArrayLiteral(args, 1); return(Interpolate(context, args[0], rest.Values)); }
private static EvaluationResult WriteFileHelper(Context context, ModuleLiteral env, EvaluationStackFrame args, WriteFileMode mode) { var path = Args.AsPath(args, 0, false); var tags = Args.AsStringArrayOptional(args, 2); var description = Args.AsStringOptional(args, 3); PipData pipData; switch (mode) { case WriteFileMode.WriteFile: var fileContent = Args.AsIs(args, 1); // WriteFile has a separator argument with default newline var separator = Args.AsStringOptional(args, 3) ?? Environment.NewLine; description = Args.AsStringOptional(args, 4); pipData = CreatePipDataForWriteFile(context, fileContent, separator); break; case WriteFileMode.WriteData: var data = Args.AsIs(args, 1); pipData = DataProcessor.ProcessData(context, context.FrontEndContext.PipDataBuilderPool, EvaluationResult.Create(data), new ConversionContext(pos: 1)); break; case WriteFileMode.WriteAllLines: var lines = Args.AsArrayLiteral(args, 1); var entry = context.TopStack; var newData = ObjectLiteral.Create( new List <Binding> { new Binding(context.Names.DataSeparator, Environment.NewLine, entry.InvocationLocation), new Binding(context.Names.DataContents, lines, entry.InvocationLocation), }, lines.Location, entry.Path); pipData = DataProcessor.ProcessData(context, context.FrontEndContext.PipDataBuilderPool, EvaluationResult.Create(newData), new ConversionContext(pos: 1)); break; case WriteFileMode.WriteAllText: var text = Args.AsString(args, 1); pipData = DataProcessor.ProcessData(context, context.FrontEndContext.PipDataBuilderPool, EvaluationResult.Create(text), new ConversionContext(pos: 1)); break; default: throw Contract.AssertFailure("Unknown WriteFileMode."); } FileArtifact result; if (!context.GetPipConstructionHelper().TryWriteFile(path, pipData, WriteFileEncoding.Utf8, tags, description, out result)) { // Error has been logged return(EvaluationResult.Error); } return(new EvaluationResult(result)); }
/// <summary> /// Implements string interpolation. /// </summary> private static EvaluationResult Interpolate(Context context, ModuleLiteral env, EvaluationStackFrame args) { var firstArgument = ToStringConverter.ObjectToString(context, args[0]); var rest = Args.AsArrayLiteral(args, 1); return(EvaluationResult.Create(string.Concat( firstArgument, string.Join(string.Empty, rest.Values.Select(v => ToStringConverter.ObjectToString(context, v)))))); }
private EvaluationResult ComposeSharedOpaqueDirectories(Context context, ModuleLiteral env, EvaluationStackFrame args) { AbsolutePath root; ArrayLiteral contents; SealDirectoryContentFilter?contentFilter; if (args.Length > 0 && args[0].Value is ObjectLiteral) { var obj = Args.AsObjectLiteral(args, 0); var directory = Converter.ExtractDirectory(obj, m_sealRoot, allowUndefined: false); root = directory.Path; contents = Converter.ExtractArrayLiteral(obj, m_sealDirectories, allowUndefined: false); var filterObj = Converter.ExtractObjectLiteral(obj, m_sealDirectoryContentFilter, allowUndefined: true); extractContentFilter(filterObj, out contentFilter); } else { root = Args.AsPath(args, 0, false); contents = Args.AsArrayLiteral(args, 1); var filterObj = Args.AsObjectLiteralOptional(args, 2); extractContentFilter(filterObj, out contentFilter); } var directories = new DirectoryArtifact[contents.Length]; for (int i = 0; i < contents.Length; ++i) { directories[i] = Converter.ExpectSharedOpaqueDirectory(contents[i], context: new ConversionContext(pos: i, objectCtx: contents)).Root; } if (!context.GetPipConstructionHelper().TryComposeSharedOpaqueDirectory(root, directories, contentFilter, description: null, tags: null, out var compositeSharedOpaque)) { // Error should have been logged return(EvaluationResult.Error); } var result = new StaticDirectory(compositeSharedOpaque, SealDirectoryKind.SharedOpaque, s_emptySealContents.WithCompatibleComparer(OrdinalPathOnlyFileArtifactComparer.Instance)); return(new EvaluationResult(result)); void extractContentFilter(ObjectLiteral obj, out SealDirectoryContentFilter?filter) { filter = null; if (obj != null) { var regex = Converter.ExtractRegex(obj, m_sealDirectoryContentFilterRegex, allowUndefined: false); var kindAsString = Converter.ExtractString(obj, m_sealDirectoryContentFilterKind, allowUndefined: false); filter = new SealDirectoryContentFilter( (SealDirectoryContentFilter.ContentFilterKind)Enum.Parse(typeof(SealDirectoryContentFilter.ContentFilterKind), kindAsString), regex.ToString()); } } }
private static EvaluationResult Min(Context context, ModuleLiteral env, EvaluationStackFrame args) { // The checker should make sure that the function takes numbers. var values = Args.AsArrayLiteral(args, 0).Values.Select(v => (int)v.Value).ToList(); if (values.Count == 0) { return(EvaluationResult.Undefined); } return(DoMath(() => values.Min())); }
private EvaluationResult SealDirectoryHelper(Context context, ModuleLiteral env, EvaluationStackFrame args, SealDirectoryKind sealDirectoryKind) { AbsolutePath path; ArrayLiteral contents; string[] tags; string description; bool scrub; if (args.Length > 0 && args[0].Value is ObjectLiteral) { var obj = Args.AsObjectLiteral(args, 0); var directory = Converter.ExtractDirectory(obj, m_sealRoot, allowUndefined: false); path = directory.Path; contents = Converter.ExtractArrayLiteral(obj, m_sealFiles, allowUndefined: false); tags = Converter.ExtractStringArray(obj, m_sealTags, allowUndefined: true); description = Converter.ExtractString(obj, m_sealDescription, allowUndefined: true); scrub = sealDirectoryKind.IsFull() ? Converter.ExtractOptionalBoolean(obj, m_sealScrub) ?? false : false; } else { path = Args.AsPath(args, 0, false); contents = Args.AsArrayLiteral(args, 1); tags = Args.AsStringArrayOptional(args, 2); description = Args.AsStringOptional(args, 3); // Only do scrub for fully seal directory scrub = sealDirectoryKind.IsFull() ? Args.AsBoolOptional(args, 4) : false; } var fileContents = new FileArtifact[contents.Length]; for (int i = 0; i < contents.Length; ++i) { fileContents[i] = Converter.ExpectFile(contents[i], strict: false, context: new ConversionContext(pos: i, objectCtx: contents)); } var sortedFileContents = SortedReadOnlyArray <FileArtifact, OrdinalFileArtifactComparer> .CloneAndSort(fileContents, OrdinalFileArtifactComparer.Instance); DirectoryArtifact sealedDirectoryArtifact; if (!context.GetPipConstructionHelper().TrySealDirectory(path, sortedFileContents, sealDirectoryKind, tags, description, null, out sealedDirectoryArtifact, scrub)) { // Error has been logged return(EvaluationResult.Error); } var result = new StaticDirectory(sealedDirectoryArtifact, sealDirectoryKind, sortedFileContents.WithCompatibleComparer(OrdinalPathOnlyFileArtifactComparer.Instance)); return(new EvaluationResult(result)); }
private static EvaluationResult DumpArgs(Context context, ModuleLiteral env, EvaluationStackFrame args) { var cmdLineArgs = Args.AsArrayLiteral(args, 0); var pathTable = context.FrontEndContext.PathTable; using (var processBuilder = ProcessBuilder.Create(pathTable, context.FrontEndContext.GetPipDataBuilder(), context.FrontEndHost.Configuration)) { TransformerExecuteArgumentsProcessor.ProcessArguments(context, processBuilder, cmdLineArgs); var pipData = processBuilder.ArgumentsBuilder.ToPipData(" ", PipDataFragmentEscaping.NoEscaping); return(EvaluationResult.Create(pipData.ToString(pathTable))); } }
private static EvaluationResult FromCharCode(Context context, ModuleLiteral env, EvaluationStackFrame args) { var codes = Args.AsArrayLiteral(args, 0); var chars = codes.Values.Select((elem, idx) => { int code = Converter.ExpectNumber(elem, strict: true, context: new ConversionContext(objectCtx: codes, pos: idx)); unchecked { return((char)code); } }).ToArray(); return(EvaluationResult.Create(new string(chars))); }
private EvaluationResult AddIf(Context context, ModuleLiteral env, EvaluationStackFrame args) { var condition = Args.AsBool(args, 0); if (!condition) { // Return empty Array var entry = context.TopStack; return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(new EvaluationResult[0], entry.InvocationLocation, entry.Path))); } var items = Args.AsArrayLiteral(args, 1); return(EvaluationResult.Create(items)); }
private static EvaluationResult FromPathAtoms(Context context, ModuleLiteral env, EvaluationStackFrame args) { var arrayLit = Args.AsArrayLiteral(args, 0); var arrayOfAtoms = new PathAtom[arrayLit.Length]; for (int i = 0; i < arrayLit.Length; ++i) { arrayOfAtoms[i] = Converter.ExpectPathAtomFromStringOrPathAtom( context.FrontEndContext.StringTable, arrayLit[i], new ConversionContext(pos: i, objectCtx: arrayLit)); } return(EvaluationResult.Create(RelativePath.Create(arrayOfAtoms))); }
private EvaluationResult ExpectFailure(Context context, ModuleLiteral env, EvaluationStackFrame args) { var closure = Args.AsClosure(args, 0); var expectedResults = Args.AsArrayLiteral(args, 1); using (var frame = EvaluationStackFrame.Create(closure.Function, args.Frame)) { var result = context.InvokeClosure(closure, frame); if (!result.IsErrorValue) { Assert.True(false, "Expected the code under test to throw a failure, but none was returned."); } if (!m_getDiagnostics().Any(diagnostic => diagnostic.Level == EventLevel.Error)) { Assert.True(false, "Expected to see at least one reported error, but none encountered."); } for (int i = 0; i < expectedResults.Count; i++) { if (expectedResults[i].Value is string expectedContent) { // String case Assert.False(string.IsNullOrEmpty(expectedContent), "Empty strings are not supported as expected error messages"); ValidateExpectedMessageLogged(null, expectedContent); } else { // Object case var obj = Converter.ExpectObjectLiteral( expectedResults[i], new ConversionContext(pos: i, objectCtx: expectedResults)); var code = Converter.ExtractInt(obj, m_testingExpectedMessageCode); expectedContent = Converter.ExtractString(obj, m_testingExpectedMessageContent); ValidateExpectedMessageLogged(code, expectedContent); } } return(EvaluationResult.Undefined); } }
private static EvaluationResult ReadGraphFragment(Context context, ModuleLiteral env, EvaluationStackFrame args) { var file = Args.AsFile(args, 0); var deps = Args.AsArrayLiteral(args, 1).Values.Select(v => (int)v.Value).ToArray(); var description = Args.AsStringOptional(args, 2) ?? file.Path.ToString(context.PathTable); if (!file.IsSourceFile) { // Do not read output file. throw new FileOperationException( new Exception( I($"Failed adding pip graph fragment file '{file.Path.ToString(context.PathTable)}' because the file is not a source file"))); } Contract.Assert(context.FrontEndContext.FileSystem.Exists(file.Path), "Fragment file does not exist"); int id = Interlocked.Increment(ref s_uniqueFragmentId); var readFragmentTask = context.FrontEndHost.PipGraphFragmentManager.AddFragmentFileToGraph(id, file, deps, description); return(EvaluationResult.Create(id)); }
private static EvaluationResult StaticMerge(Context context, ModuleLiteral env, EvaluationStackFrame args) { ObjectLiteral result = null; var arrayOfObjects = Args.AsArrayLiteral(args, 0); for (int i = 0; i < arrayOfObjects.Length; i++) { if (arrayOfObjects[i].IsUndefined) { continue; } var arg = Converter.ExpectObjectLiteral( arrayOfObjects[i], new ConversionContext(pos: i, objectCtx: arrayOfObjects)); if (result == null) { result = arg; } else { var merged = result.Merge(context, EvaluationStackFrame.UnsafeFrom(new EvaluationResult[0]), EvaluationResult.Create(arg)); // Merge can fail due to custom merge functions failing. if (merged.IsErrorValue) { return(merged); } // Left and right are guaranteed to be objects so the result must be object. result = (ObjectLiteral)merged.Value; } } if (result == null) { return(EvaluationResult.Undefined); } return(EvaluationResult.Create(result)); }
/// <summary> /// Implements relative path interpolation /// </summary> private static EvaluationResult Interpolate(Context context, ModuleLiteral env, EvaluationStackFrame args) { Args.CheckArgumentIndex(args, 1); var stringTable = context.FrontEndContext.StringTable; PathAtom pathAtom = Converter.ExpectPathAtomFromStringOrPathAtom(stringTable, args[0], new ConversionContext(pos: 1)); var rest = Args.AsArrayLiteral(args, 1); for (int i = 0; i < rest.Length; i++) { pathAtom = pathAtom.Concat( stringTable, Converter.ExpectPathAtomFromStringOrPathAtom( stringTable, rest[i], new ConversionContext(pos: i + 1, objectCtx: rest))); } return(EvaluationResult.Create(pathAtom)); }
private static EvaluationResult Join(Context context, ModuleLiteral env, EvaluationStackFrame args) { var separator = Args.AsString(args, 0); var arrayOfStrings = Args.AsArrayLiteral(args, 1); using (var pooledInstance = Pools.StringBuilderPool.GetInstance()) { var builder = pooledInstance.Instance; for (var i = 0; i < arrayOfStrings.Length; ++i) { var s = Converter.ExpectString( arrayOfStrings[i], new ConversionContext(pos: i, objectCtx: arrayOfStrings)); builder.Append(s); if (i < arrayOfStrings.Length - 1) { builder.Append(separator); } } return(EvaluationResult.Create(builder.ToString())); } }
private static EvaluationResult ComposeSharedOpaqueDirectories(Context context, ModuleLiteral env, EvaluationStackFrame args) { AbsolutePath root = Args.AsPath(args, 0, false); ArrayLiteral contents = Args.AsArrayLiteral(args, 1); var tags = Args.AsStringArrayOptional(args, 2); var description = Args.AsStringOptional(args, 3); var directories = new DirectoryArtifact[contents.Length]; for (int i = 0; i < contents.Length; ++i) { directories[i] = Converter.ExpectSharedOpaqueDirectory(contents[i], context: new ConversionContext(pos: i, objectCtx: contents)).Root; } if (!context.GetPipConstructionHelper().TryComposeSharedOpaqueDirectory(root, directories, description, tags, out var compositeSharedOpaque)) { // Error should have been logged return(EvaluationResult.Error); } var result = new StaticDirectory(compositeSharedOpaque, SealDirectoryKind.SharedOpaque, s_emptySealContents.WithCompatibleComparer(OrdinalPathOnlyFileArtifactComparer.Instance)); return(new EvaluationResult(result)); }
private EvaluationResult WriteFileHelper(Context context, ModuleLiteral env, EvaluationStackFrame args, WriteFileMode mode) { AbsolutePath path; string[] tags; string description; PipData pipData; if (args.Length > 0 && args[0].Value is ObjectLiteral) { var obj = Args.AsObjectLiteral(args, 0); path = Converter.ExtractPath(obj, m_writeOutputPath, allowUndefined: false); tags = Converter.ExtractStringArray(obj, m_writeTags, allowUndefined: true); description = Converter.ExtractString(obj, m_writeDescription, allowUndefined: true); switch (mode) { case WriteFileMode.WriteData: var data = obj[m_writeContents]; pipData = ProcessData(context, data, new ConversionContext(pos: 1)); break; case WriteFileMode.WriteAllLines: var lines = Converter.ExtractArrayLiteral(obj, m_writeLines); var entry = context.TopStack; var newData = ObjectLiteral.Create( new List <Binding> { new Binding(m_dataSeparator, Environment.NewLine, entry.InvocationLocation), new Binding(m_dataContents, lines, entry.InvocationLocation), }, lines.Location, entry.Path); pipData = ProcessData(context, EvaluationResult.Create(newData), new ConversionContext(pos: 1)); break; case WriteFileMode.WriteAllText: var text = Converter.ExtractString(obj, m_writeText); pipData = ProcessData(context, EvaluationResult.Create(text), new ConversionContext(pos: 1)); break; default: throw Contract.AssertFailure("Unknown WriteFileMode."); } } else { path = Args.AsPath(args, 0, false); tags = Args.AsStringArrayOptional(args, 2); description = Args.AsStringOptional(args, 3); switch (mode) { case WriteFileMode.WriteFile: var fileContent = Args.AsIs(args, 1); // WriteFile has a separator argument with default newline var separator = Args.AsStringOptional(args, 3) ?? Environment.NewLine; description = Args.AsStringOptional(args, 4); pipData = CreatePipDataForWriteFile(context, fileContent, separator); break; case WriteFileMode.WriteData: var data = Args.AsIs(args, 1); pipData = ProcessData(context, EvaluationResult.Create(data), new ConversionContext(pos: 1)); break; case WriteFileMode.WriteAllLines: var lines = Args.AsArrayLiteral(args, 1); var entry = context.TopStack; var newData = ObjectLiteral.Create( new List <Binding> { new Binding(m_dataSeparator, Environment.NewLine, entry.InvocationLocation), new Binding(m_dataContents, lines, entry.InvocationLocation), }, lines.Location, entry.Path); pipData = ProcessData(context, EvaluationResult.Create(newData), new ConversionContext(pos: 1)); break; case WriteFileMode.WriteAllText: var text = Args.AsString(args, 1); pipData = ProcessData(context, EvaluationResult.Create(text), new ConversionContext(pos: 1)); break; default: throw Contract.AssertFailure("Unknown WriteFileMode."); } } FileArtifact result; if (!context.GetPipConstructionHelper().TryWriteFile(path, pipData, WriteFileEncoding.Utf8, tags, description, out result)) { // Error has been logged return(EvaluationResult.Error); } return(new EvaluationResult(result)); }