private static EvaluationResult NumberToStringMethod(Context context, int receiver, EvaluationResult radixAsObject, EvaluationStackFrame captures) { int? radix = radixAsObject.IsUndefined ? (int?)null : (int)radixAsObject.Value; string result; if (radix != null) { ValidateRadix(radix.Value); result = Convert.ToString(receiver, radix.Value); } else { result = receiver.ToString(CultureInfo.InvariantCulture); } return(EvaluationResult.Create(result)); }
private static EvaluationResult Equals(Context context, PathAtom receiver, EvaluationResult fragment, EvaluationResult ignoreCase, EvaluationStackFrame captures) { var stringTable = context.FrontEndContext.StringTable; PathAtom otherAtom = Converter.ExpectPathAtomFromStringOrPathAtom(stringTable, fragment, new ConversionContext(pos: 1)); if (!ignoreCase.IsUndefined) { bool ignoreCaseBool = Converter.ExpectBool(ignoreCase, new ConversionContext(pos: 2)); if (ignoreCaseBool) { return(EvaluationResult.Create(receiver.CaseInsensitiveEquals(stringTable, otherAtom))); } } // By default comparison is case sensitive return(EvaluationResult.Create(receiver.Equals(otherAtom))); }
private EvaluationResult WithCustomMerge(Context context, ObjectLiteral receiver, EvaluationResult arg, EvaluationStackFrame captures) { var closure = Converter.ExpectClosure(arg); var entry = context.TopStack; var invocationLocation = entry.InvocationLocation; var invocationPath = entry.Path; // Creating a new object with a custom merge is equivalent to override the current object with an object that only has the custom merge // function as an entry. And since the object literal creation process depends on its number of members, let's just do the override // explicitly var newObject = ObjectLiteral.Create( new [] { new NamedValue(m_customMergeFunction.StringId.Value, EvaluationResult.Create(closure)) }, invocationLocation, invocationPath); return(receiver.Combine(context, ObjectLiteral.OverrideFunction, EvaluationResult.Create(newObject))); }
private static EvaluationResult ParseInt(Context context, ModuleLiteral env, EvaluationStackFrame args) { var str = Args.AsString(args, 0); var radix = Args.AsIntOptional(args, 1); if (radix != null) { ValidateRadix(radix.Value); return(EvaluationResult.Create(Convert.ToInt32(str, radix.Value))); } if (int.TryParse(str, NumberStyles.Any, s_numberFormatInfo, out int intValue)) { return(EvaluationResult.Create(intValue)); } return(EvaluationResult.Undefined); }
private static EvaluationResult Equals(Context context, RelativePath receiver, EvaluationResult fragment, EvaluationResult ignoreCase, EvaluationStackFrame captures) { var stringTable = context.FrontEndContext.StringTable; Converter.ExpectPathFragment(stringTable, fragment, out PathAtom pathAtom, out RelativePath relativePath, new ConversionContext(pos: 1)); relativePath = pathAtom.IsValid ? RelativePath.Create(pathAtom) : relativePath; if (!ignoreCase.IsUndefined) { bool ignoreCaseBool = Converter.ExpectBool(ignoreCase, new ConversionContext(pos: 2)); if (ignoreCaseBool) { return(EvaluationResult.Create(receiver.CaseInsensitiveEquals(stringTable, relativePath))); } } return(EvaluationResult.Create(receiver.Equals(relativePath))); }
private static EvaluationResult ToArray(Context context, OrderedMap receiver, EvaluationStackFrame captures) { var result = new EvaluationResult[receiver.Count]; var entry = context.TopStack; var kvps = receiver.ToArray(); int i = 0; foreach (var kvp in kvps) { var pair = ArrayLiteral.CreateWithoutCopy(new[] { kvp.Key, kvp.Value }, entry.InvocationLocation, entry.Path); result[i] = EvaluationResult.Create(pair); ++i; } return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(result, entry.InvocationLocation, entry.Path))); }
private static EvaluationResult Unique(Context context, ArrayLiteral receiver, EvaluationStackFrame captures) { if (receiver.Length == 0) { return(EvaluationResult.Create(receiver)); } // note that HashSet preserves insertion order var unique = new HashSet <EvaluationResult>(receiver.Values).ToArray(); if (unique.Length == receiver.Length) { return(EvaluationResult.Create(receiver)); } var entry = context.TopStack; return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(unique, entry.InvocationLocation, entry.Path))); }
private static EvaluationResult LastIndexOf(Context context, string receiver, EvaluationResult arg0, EvaluationResult arg1, EvaluationStackFrame captures) { var arg0Str = Converter.ExpectString(arg0, new ConversionContext(pos: 1)); var arg1Int = arg1.IsUndefined ? receiver.Length : Converter.ExpectNumber(arg1, context: new ConversionContext(pos: 2)); if (arg1Int < 0) { arg1Int = 0; } if (arg1Int > receiver.Length) { arg1Int = receiver.Length; } return(EvaluationResult.Create(receiver.LastIndexOf(arg0Str, arg1Int, StringComparison.Ordinal))); }
private static EvaluationResult MapWithState(Context context, ArrayLiteral receiver, EvaluationResult arg0, EvaluationResult arg1, EvaluationStackFrame captures) { var closure = Converter.ExpectClosure(arg0); int paramsCount = closure.Function.Params; var state = arg1; var arrays = new EvaluationResult[receiver.Length]; using (var frame = EvaluationStackFrame.Create(closure.Function, captures.Frame)) { var entry = context.TopStack; var stateName = SymbolAtom.Create(context.FrontEndContext.StringTable, "state"); var elemsName = SymbolAtom.Create(context.FrontEndContext.StringTable, "elems"); var elemName = SymbolAtom.Create(context.FrontEndContext.StringTable, "elem"); for (int i = 0; i < receiver.Length; ++i) { frame.TrySetArguments(paramsCount, state, receiver[i], i, EvaluationResult.Create(receiver)); EvaluationResult mapResult = context.InvokeClosure(closure, frame); if (mapResult.IsErrorValue) { return(EvaluationResult.Error); } if (!(mapResult.Value is ObjectLiteral objectResult)) { throw Converter.CreateException <ObjectLiteral>(mapResult, default(ConversionContext)); } arrays[i] = objectResult[elemName]; state = objectResult[stateName]; } var bindings = new List <Binding> { new Binding(elemsName, ArrayLiteral.CreateWithoutCopy(arrays, entry.InvocationLocation, entry.Path), location: default(LineInfo)), new Binding(stateName, state, location: default(LineInfo)), }; return(EvaluationResult.Create(ObjectLiteral.Create(bindings, entry.InvocationLocation, entry.Path))); } }
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)); }
/// <inheritdoc /> protected override EvaluationResult DoEval(Context context, ModuleLiteral env, EvaluationStackFrame frame) { var evaluatedPathExpression = PathExpression.Eval(context, env, frame); if (evaluatedPathExpression.IsErrorValue) { return(EvaluationResult.Error); } try { var path = Converter.ExpectPath(evaluatedPathExpression, strict: true, context: new ConversionContext(pos: 1)); return(EvaluationResult.Create(FileArtifact.CreateSourceFile(path))); } catch (ConvertException e) { context.Errors.ReportUnexpectedValueTypeOnConversion(env, e, Location); return(EvaluationResult.Error); } }
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 CombinePaths(Context context, RelativePath receiver, EvaluationResult arg, EvaluationStackFrame captures) { var stringTable = context.FrontEndContext.StringTable; var argArray = Converter.ExpectArrayLiteral(arg, new ConversionContext(pos: 1)); RelativePath currentRelativePath = receiver; for (int i = 0; i < argArray.Length; i++) { Converter.ExpectPathFragment( stringTable, argArray[i], out PathAtom pathAtom, out RelativePath relativePath, new ConversionContext(pos: i + 1, objectCtx: argArray)); currentRelativePath = relativePath.IsValid ? currentRelativePath.Combine(relativePath) : currentRelativePath.Combine(pathAtom); } return(EvaluationResult.Create(currentRelativePath)); }
private static EvaluationResult AppendRepeat(Context context, StringBuilderWrapper receiver, EvaluationResult arg1, EvaluationResult arg2, EvaluationStackFrame captures) { var stringValue = Converter.ExpectString(arg1); var repeatValue = Math.Max(0, Converter.ExpectNumber(arg2)); var builder = receiver.StringBuilder; if (stringValue.Length == 1) { builder.Append(stringValue[0], repeatValue); } else { for (var i = 0; i < repeatValue; i++) { builder.Append(stringValue); } } return(EvaluationResult.Create(receiver)); }
private static EvaluationResult Slice(Context context, string receiver, EvaluationResult arg0, EvaluationResult arg1, EvaluationStackFrame captures) { var start = arg0.IsUndefined ? 0 : Converter.ExpectNumber(arg0, context: new ConversionContext(pos: 1)); var end = arg1.IsUndefined ? receiver.Length : Converter.ExpectNumber(arg1, context: new ConversionContext(pos: 2)); // this seems to be the semantics in JavaScript (if 'end' is greater than length, // it's trimmed down to length; but if 'start' is less than 0, the result is the empty string) if (end > receiver.Length) { end = receiver.Length; } return((start < 0 || start >= receiver.Length || end <= 0 || end > receiver.Length || end <= start) ? EvaluationResult.Create(string.Empty) : EvaluationResult.Create(receiver.Substring(start, end - start))); }
private static EvaluationResult SomeOrAll(Context context, ArrayLiteral receiver, EvaluationResult arg, EvaluationStackFrame captures, bool isSome) { var closure = Converter.ExpectClosure(arg); if (receiver.Length == 0) { return(EvaluationResult.Create(!isSome)); } int paramsCount = closure.Function.Params; using (var frame = EvaluationStackFrame.Create(closure.Function, captures.Frame)) { for (int i = 0; i < receiver.Length; ++i) { frame.TrySetArguments(paramsCount, receiver[i], i, EvaluationResult.Create(receiver)); EvaluationResult lambdaResult = context.InvokeClosure(closure, frame); if (lambdaResult.IsErrorValue) { return(EvaluationResult.Error); } bool isTrue = Expression.IsTruthy(lambdaResult); if (isSome && isTrue) { return(EvaluationResult.True); } if (!isSome && !isTrue) { return(EvaluationResult.False); } } // if isSome ("some") and we've exhausted the loop (no elem matched) ==> return false // if !isSome ("all") and we've exhausted the loop (all elems matched) ==> return true return(EvaluationResult.Create(!isSome)); } }
private EvaluationResult IpcSend(Context context, ModuleLiteral env, EvaluationStackFrame args) { var obj = Args.AsObjectLiteral(args, 0); if (!TryScheduleIpcPip(context, obj, allowUndefinedTargetService: false, isServiceFinalization: false, out var outputFile, out _)) { // Error has been logged return(EvaluationResult.Error); } // create and return result var result = ObjectLiteral.Create( new List <Binding> { new Binding(m_ipcSendResultOutputFile, outputFile, location: default(LineInfo)), }, context.TopStack.InvocationLocation, context.TopStack.Path); return(EvaluationResult.Create(result)); }
private static EvaluationResult GetPathValues(Context context, EvaluationStackFrame args, Type type) { var name = Args.AsString(args, 0); var separator = Args.AsString(args, 1); string strValue = GetRawValue(context, name); var entry = context.TopStack; if (string.IsNullOrWhiteSpace(strValue)) { return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(CollectionUtilities.EmptyArray <EvaluationResult>(), entry.InvocationLocation, entry.Path))); } var values = separator.Length == 0 ? new[] { strValue } : strValue.Split(new[] { separator }, StringSplitOptions.RemoveEmptyEntries); var pathsOrFiles = new List <EvaluationResult>(); for (int i = 0; i < values.Length; ++i) { if (!string.IsNullOrWhiteSpace(values[i])) { AbsolutePath path = ParsePath(context, name, values[i], 1); EvaluationResult result = type == typeof(AbsolutePath) ? EvaluationResult.Create(path) : type == typeof(FileArtifact) ? EvaluationResult.Create(FileArtifact.CreateSourceFile(path)) : type == typeof(DirectoryArtifact) ? EvaluationResult.Create(DirectoryArtifact.CreateWithZeroPartialSealId(path)) : EvaluationResult.Undefined; if (result.IsUndefined) { throw Contract.AssertFailure(I($"Cannot convert paths to typeof({type.Name})")); } pathsOrFiles.Add(result); } } return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(pathsOrFiles.ToArray(), entry.InvocationLocation, entry.Path))); }
private EvaluationResult[] EnumerateFilesOrDirectories( Context context, string directoryPath, string searchPattern, bool isRecursive, bool enumerateDirectory) { var fileSystem = context.FrontEndContext.FileSystem; if (enumerateDirectory) { return(fileSystem .EnumerateDirectories(AbsolutePath.Create(context.PathTable, directoryPath), searchPattern, isRecursive) .Select(ap => EvaluationResult.Create(DirectoryArtifact.CreateWithZeroPartialSealId(ap))) .ToArray()); } return(fileSystem .EnumerateFiles(AbsolutePath.Create(context.PathTable, directoryPath), searchPattern, isRecursive) .Select(ap => EvaluationResult.Create(FileArtifact.CreateSourceFile(ap))) .ToArray()); }
private static EvaluationResult Split(Context context, string receiver, EvaluationResult arg0, EvaluationResult arg1, EvaluationStackFrame captures) { var separator = Converter.ExpectString(arg0, new ConversionContext(pos: 1)); var resultAsStrs = receiver.Split(new[] { separator }, int.MaxValue, StringSplitOptions.None); // Here, C# and ECMAScript semantics differ: // ECMAScript: ";aa;;bb;".split(";", 3) will yield ["", "aa", ""] // C#: ";aa;;bb;".split(";", 3) will yield ["", "aa", ";bb;"] // (i.e., C# stops splitting, and ECMAScript truncates) var len = arg1.IsUndefined ? resultAsStrs.Length : Converter.ExpectNumber(arg1, context: new ConversionContext(pos: 2)); var result = new EvaluationResult[len]; for (int i = 0; i < len; i++) { result[i] = EvaluationResult.Create(resultAsStrs[i]); } var entry = context.TopStack; return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(result, entry.InvocationLocation, entry.Path))); }
private EvaluationResult AddIfLazy(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))); } // Call the function passed in and return that result var closure = Args.AsClosure(args, 1); var result = context.InvokeClosure(closure, closure.Frame); if (result.IsErrorValue) { return(EvaluationResult.Error); } return(result); }
private EvaluationResult GetMount(Context context, ModuleLiteral env, EvaluationStackFrame args) { var engine = context.FrontEndHost.Engine; var name = Convert.ToString(args[0].Value, CultureInfo.InvariantCulture); GetProvenance(context, out AbsolutePath path, out LineInfo lineInfo); var result = engine.TryGetMount(name, "Script", AmbientTypes.ScriptModuleId, out IMount mount); switch (result) { case TryGetMountResult.Success: return (EvaluationResult.Create(ObjectLiteral.Create( new Binding(MountNameObject, mount.Name, location: lineInfo), new Binding(MountPathObject, mount.Path, location: lineInfo)))); case TryGetMountResult.NameNullOrEmpty: throw TryGetMountException.MountNameNullOrEmpty(env, new ErrorContext(pos: 1), lineInfo); case TryGetMountResult.NameNotFound: // Check for case mismatch. var mountNames = engine.GetMountNames("Script", BuildXL.Utilities.ModuleId.Invalid); foreach (var mountName in mountNames) { if (string.Equals(name, mountName, StringComparison.OrdinalIgnoreCase)) { throw TryGetMountException.MountNameCaseMismatch(env, name, mountName, new ErrorContext(pos: 1), lineInfo); } } throw TryGetMountException.MountNameNotFound(env, name, mountNames, new ErrorContext(pos: 1), lineInfo); default: Contract.Assume(false, "Unexpected TryGetMountResult"); return(EvaluationResult.Undefined); } }
private static EvaluationResult MapDefined(Context context, ArrayLiteral receiver, EvaluationResult arg, EvaluationStackFrame captures) { var closure = Converter.ExpectClosure(arg); int paramsCount = closure.Function.Params; if (receiver.Length == 0) { return(EvaluationResult.Create(receiver)); } var result = new EvaluationResult[receiver.Length]; using (var frame = EvaluationStackFrame.Create(closure.Function, captures.Frame)) { int j = 0; for (int i = 0; i < receiver.Length; ++i) { frame.TrySetArguments(paramsCount, receiver[i], i, EvaluationResult.Create(receiver)); EvaluationResult r = context.InvokeClosure(closure, frame); if (r.IsErrorValue) { return(EvaluationResult.Error); } // Skip the result if undefined. if (!r.IsUndefined) { result[j] = r; ++j; } } var definedResult = new EvaluationResult[j]; Array.Copy(result, 0, definedResult, 0, j); return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(definedResult, context.TopStack.InvocationLocation, context.TopStack.Path))); } }
/// <inheritdoc/> protected override EvaluationResult DoEval(Context context, ModuleLiteral env, EvaluationStackFrame frame) { var result = m_expression.Eval(context, env, frame); if (result.IsErrorValue) { return(result); } if (!(result.Value is ModuleLiteral module)) { var thisNodeType = nameof(ModuleToObjectLiteral); throw Contract.AssertFailure( $"AstConverter should never create a '{thisNodeType}' node that wraps an expression that evaluates to something other than {nameof(ModuleLiteral)}. " + $"Instead, this '{thisNodeType}' wraps an expression of type '{m_expression.GetType().Name}' which evaluated to an instance of type '{result.Value?.GetType().Name}'."); } var bindings = module .GetAllBindings(context) .Where(kvp => kvp.Key != Constants.Names.RuntimeRootNamespaceAlias) .Select(kvp => { var name = SymbolAtom.Create(context.StringTable, kvp.Key); var location = kvp.Value.Location; var evalResult = module.GetOrEvalFieldBinding(context, name, kvp.Value, location); return(new Binding(name, evalResult.Value, location)); }) .ToArray(); if (bindings.Any(b => b.Body.IsErrorValue())) { return(EvaluationResult.Error); } var objectLiteral = ObjectLiteral.Create(bindings); return(EvaluationResult.Create(objectLiteral)); }
private static EvaluationResult ReadAllText(Context context, ModuleLiteral env, EvaluationStackFrame args) { // File that is read here will be tracked by the input tracker in the same way the spec file. var file = Args.AsFile(args, 0); if (!file.IsSourceFile) { // Do not read output file. throw new FileOperationException( new Exception( I($"Failed reading '{file.Path.ToString(context.PathTable)}' because the file is not a source file"))); } var possibleContent = context.FrontEndHost.Engine.GetFileContentAsync(file.Path).GetAwaiter().GetResult(); if (possibleContent.Succeeded) { return(EvaluationResult.Create(possibleContent.Result.GetContentAsString())); } throw new FileOperationException( new Exception(I($"Failed reading '{file.Path.ToString(context.PathTable)}'"), possibleContent.Failure.Exception)); }
private static EvaluationResult AssertFileExistence(Context context, StaticDirectory receiver, EvaluationResult arg, EvaluationStackFrame captures) { var path = GetPathFromArgument(context, receiver, arg); // For non-opaque outputs, this is just a getFile() call. if (!receiver.SealDirectoryKind.IsOpaqueOutput()) { return(GetFile(context, receiver, arg, captures)); } if (!path.IsWithin(context.PathTable, receiver.Root.Path)) { // If the path is not within the directory, we already know it is not there throw new FileNotFoundInStaticDirectoryException(path.ToString(context.PathTable), new ErrorContext(objectCtx: arg.Value, pos: 0)); } if (!context.GetPipConstructionHelper().TryAssertOutputExistenceInOpaqueDirectory(receiver.Root, path, out FileArtifact fileArtifact)) { throw new InvalidOutputAssertionUnderOpaqueDirectoryException(path.ToString(context.PathTable), new ErrorContext(objectCtx: arg.Value, pos: 0)); } return(EvaluationResult.Create(fileArtifact)); }
private static EvaluationResult AddRange(Context context, ArrayLiteral receiver, EvaluationResult arg, EvaluationStackFrame captures) { var arrayArg = Converter.ExpectArrayLiteral(arg); if (arrayArg.Length == 0) { return(EvaluationResult.Create(receiver)); } if (receiver.Length == 0) { return(EvaluationResult.Create(arrayArg)); } var result = new EvaluationResult[receiver.Length + arrayArg.Length]; receiver.Copy(0, result, 0, receiver.Length); arrayArg.Copy(0, result, receiver.Length, arrayArg.Length); var entry = context.TopStack; return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(result, entry.InvocationLocation, entry.Path))); }
private EvaluationResult DumpData(Context context, ModuleLiteral env, EvaluationStackFrame args) { var pathTable = context.FrontEndContext.PathTable; var data = Args.AsIs(args, 0); string dataAsString = null; switch (data) { case string s: dataAsString = s; break; case IImplicitPath pathData: dataAsString = pathData.Path.ToString(context.PathTable); break; case PathAtom pathAtom: dataAsString = pathAtom.ToString(context.StringTable); break; case RelativePath relativePath: dataAsString = relativePath.ToString(context.StringTable); break; case int n: dataAsString = n.ToString(CultureInfo.InvariantCulture); break; default: // This is effectively only for object literals // Slow path dataAsString = DataProcessor.ProcessData(context.StringTable, m_dataSeparator, m_dataContents, context.FrontEndContext.PipDataBuilderPool, EvaluationResult.Create(data), new ConversionContext(pos: 1)).ToString(context.PathTable); break; } return(EvaluationResult.Create(dataAsString)); }
private static EvaluationResult GetFiles(Context context, StaticDirectory receiver, EvaluationResult argument, EvaluationStackFrame captures) { ArrayLiteral args = Converter.ExpectArrayLiteral(argument); var result = new EvaluationResult[args.Length]; for (int i = 0; i < args.Length; i++) { var arg = args[i]; AbsolutePath path; if (arg.Value is AbsolutePath absolutePath) { path = absolutePath; } else { var stringTable = context.FrontEndContext.StringTable; var pathTable = context.FrontEndContext.PathTable; Converter.ExpectPathFragment(stringTable, arg, out PathAtom pathAtom, out RelativePath relativePath, new ConversionContext(pos: 1)); path = receiver.Root.Path; path = pathAtom.IsValid ? path.Combine(pathTable, pathAtom) : path.Combine(pathTable, relativePath); } if (receiver.TryGetFileArtifact(path, out FileArtifact file)) { result[i] = EvaluationResult.Create(file); } else { throw new FileNotFoundInStaticDirectoryException(path.ToString(context.PathTable), new ErrorContext(objectCtx: arg.Value, pos: i)); } } return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(result, context.TopStack.InvocationLocation, context.TopStack.Path))); }