private static EvaluationResult ForEach(Context context, OrderedSet receiver, EvaluationResult arg, EvaluationStackFrame captures) { var cls = Converter.ExpectClosure(arg); var result = new EvaluationResult[receiver.Count]; int paramsCount = cls.Function.Params; using (var frame = EvaluationStackFrame.Create(cls.Function, captures.Frame)) { int i = 0; foreach (var item in receiver) { frame.TrySetArguments(paramsCount, item); result[i] = context.InvokeClosure(cls, frame); if (result[i].IsErrorValue) { return(EvaluationResult.Error); } ++i; } return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(result, context.TopStack.InvocationLocation, context.TopStack.Path))); } }
private static EvaluationResult ForEach(Context context, OrderedMap receiver, EvaluationResult arg, EvaluationStackFrame captures) { var cls = Converter.ExpectClosure(arg); var result = new EvaluationResult[receiver.Count]; int paramsCount = cls.Function.Params; // One frame can be reused for multiple calls of a callback function using (var frame = EvaluationStackFrame.Create(cls.Function, captures.Frame)) { var entry = context.TopStack; int i = 0; foreach (var kvp in receiver) { var kvpAsArray = ArrayLiteral.CreateWithoutCopy(new EvaluationResult[] { kvp.Key, kvp.Value }, entry.InvocationLocation, entry.Path); frame.TrySetArguments(paramsCount, EvaluationResult.Create(kvpAsArray)); result[i] = context.InvokeClosure(cls, frame); if (result[i].IsErrorValue) { return(EvaluationResult.Error); } ++i; } return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(result, entry.InvocationLocation, entry.Path))); } }
private static EvaluationResult ToArray(Context context, string receiver, EvaluationStackFrame captures) { var elems = string.IsNullOrEmpty(receiver) ? CollectionUtilities.EmptyArray <EvaluationResult>() : receiver.ToCharArray().SelectArray(ch => EvaluationResult.Create(ch.ToString())); return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(elems, context.TopStack.InvocationLocation, context.TopStack.Path))); }
private static EvaluationResult GetContent(Context context, StaticDirectory receiver, EvaluationStackFrame captures) { GetProvenance(context, out AbsolutePath path, out LineInfo lineInfo); // Can't use content directly, because there is no IS-A relationship between collection // of value types and collection of objects. So need to box everything any way. var content = receiver.Contents.SelectArray(x => EvaluationResult.Create(x)); return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(content, lineInfo, path))); }
private static ArrayLiteral DeepCloneArray(ArrayLiteral array) { var results = new EvaluationResult[array.Count]; for (int i = 0; i < array.Count; i++) { results[i] = DeepCloneValue(array[i]); } return(ArrayLiteral.CreateWithoutCopy(results, array.Location, array.Path)); }
private static EvaluationResult ToPathAtoms(Context context, RelativePath receiver, EvaluationStackFrame captures) { PathAtom[] atoms = receiver.GetAtoms(); EvaluationResult[] result = new EvaluationResult[atoms.Length]; for (int i = 0; i < atoms.Length; i++) { result[i] = EvaluationResult.Create(atoms[i]); } var entry = context.TopStack; return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(result, entry.InvocationLocation, entry.Path))); }
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 IEnumerable <object> GetDifferentListRepresenations <T>(IReadOnlyList <T> array) { var objectArray = new object[array.Count]; for (var i = 0; i < objectArray.Length; i++) { objectArray[i] = array[i]; } return(new List <object> { array, ArrayLiteral.CreateWithoutCopy(objectArray.Select(e => EvaluationResult.Create(e)).ToArray(), default(LineInfo), AbsolutePath.Invalid) }); }
public void TestAmbientEnvironmentUses() { const string Spec = @" // Any change will break Office. const newLine = Environment.newLine(); const hasVariable = Environment.hasVariable(""ProgramFiles(x86)""); const stringValue = Environment.getStringValue(""UserName""); const pathValue = Environment.getPathValue(""ProgramFiles(x86)""); const fileValue = Environment.getFileValue(""ProgramFiles(x86)""); // yes, I know it's not a file. const pathValues = Environment.getPathValues(""Path"", "";""); "; var results = EvaluateExpressionsWithNoErrors( Spec, "newLine", "hasVariable", "stringValue", "pathValue", "fileValue", "pathValues"); string programFileX86 = Environment.GetEnvironmentVariable("ProgramFiles(x86)"); string userName = Environment.GetEnvironmentVariable("UserName"); string path = Environment.GetEnvironmentVariable("Path"); Assert.Equal(Environment.NewLine, results["newLine"]); Assert.Equal(programFileX86 != null, results["hasVariable"]); Assert.Equal(userName != null ? (object)userName : UndefinedValue.Instance, results["stringValue"]); Assert.Equal( programFileX86 != null ? (object)CreateAbsolutePath(programFileX86).Value : UndefinedValue.Instance, results["pathValue"]); Assert.Equal( programFileX86 != null ? (object)CreateSourceFile(programFileX86).Value : UndefinedValue.Instance, results["fileValue"]); if (path != null) { var paths = ArrayLiteral.CreateWithoutCopy( path.Split(';').Select(p => EvaluationResult.Create(CreateAbsolutePath(p))).ToArray(), default(LineInfo), AbsolutePath.Invalid); Assert.IsAssignableFrom <ArrayLiteral>(results["pathValues"]); CheckUnorderedArray <AbsolutePath>(paths, results["pathValues"]); } else { Assert.Equal(UndefinedValue.Instance, results["pathValues"]); } }
private static ObjectLiteral GetQualifierSpaceValue(EvaluationContext context, QualifierSpaceId qualifierSpaceId) { Contract.Requires(context != null); Contract.Requires(context.FrontEndContext.QualifierTable.IsValidQualifierSpaceId(qualifierSpaceId)); var qualifierSpace = context.FrontEndContext.QualifierTable.GetQualifierSpace(qualifierSpaceId); var bindings = new List <Binding>(qualifierSpace.Keys.Count); foreach (var kvp in qualifierSpace.AsDictionary) { var values = ArrayLiteral.CreateWithoutCopy(kvp.Value.Select(s => EvaluationResult.Create(s.ToString(context.StringTable))).ToArray(), default(LineInfo), AbsolutePath.Invalid); bindings.Add(new Binding(kvp.Key, values, default(LineInfo))); } return(ObjectLiteral.Create(bindings, default(LineInfo), AbsolutePath.Invalid)); }
private EvaluationResult GlobFolders(Context context, ModuleLiteral env, EvaluationStackFrame args) { var dirPath = Args.AsPath(args, 0, false); var pathTable = context.FrontEndContext.PathTable; var path = dirPath.ToString(pathTable); // TODO:ST: add different set of function that will distinguish optional from required arguments! string pattern = Args.AsStringOptional(args, 1) ?? "*"; bool recursive = Args.AsBoolOptional(args, 2); var resultPaths = EnumerateFilesOrDirectories(context, path, pattern, directoriesToSkipRecursively: 0, isRecursive: recursive, enumerateDirectory: true); var entry = context.TopStack; return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(resultPaths, entry.InvocationLocation, entry.Path))); }
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 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 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 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))); }
private EvaluationResult GlobImpl(Context context, EvaluationStackFrame args, SearchOption searchOption) { AbsolutePath dirPath = Args.AsPath(args, 0, false); var pathTable = context.FrontEndContext.PathTable; var path = dirPath.ToString(pathTable); string pattern = Args.AsStringOptional(args, 1) ?? "*"; uint directoriesToSkipRecursively = 0; if (pattern.Length > 2) { if (pattern[0] == '*' && pattern[1] == '/' || pattern[1] == '\\') { pattern = pattern.Substring(2); directoriesToSkipRecursively = 1; } } var sw = Stopwatch.StartNew(); var resultPaths = EnumerateFilesOrDirectories( context, path, pattern, directoriesToSkipRecursively, searchOption == SearchOption.AllDirectories, enumerateDirectory: false); sw.Stop(); Interlocked.Add(ref context.Statistics.TotalGlobTimeInTicks, sw.Elapsed.Ticks); var entry = context.TopStack; return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(resultPaths, entry.InvocationLocation, entry.Path))); }
private ObjectLiteral BuildExecuteOutputs(Context context, ModuleLiteral env, ProcessOutputs processOutputs, bool isService) { var entry = context.TopStack; using (var empty = EvaluationStackFrame.Empty()) { var getOutputFile = new Closure( env, FunctionLikeExpression.CreateAmbient(ExecuteResultGetOutputFile, m_getOutputFileSignature, GetOutputFile, m_getOutputFileStatistic), frame: empty); var getOutputDirectory = new Closure( env, FunctionLikeExpression.CreateAmbient(ExecuteResultGetOutputDirectory, m_getOutputDirectorySignature, GetOutputDirectory, m_getOutputDirectoryStatistic), frame: empty); var getOutputFiles = new Closure( env, FunctionLikeExpression.CreateAmbient(ExecuteResultGetOutputFiles, m_getOutputFilesSignature, GetOutputFiles, m_getOutputFilesStatistic), frame: empty); var getRequiredOutputFiles = new Closure( env, FunctionLikeExpression.CreateAmbient(ExecuteResultGetRequiredOutputFiles, m_getRequiredOutputFilesSignature, GetRequiredOutputFiles, m_getRequiredOutputFilesStatistic), frame: empty); var bindings = new List <Binding>(isService ? 6 : 5) { new Binding(ExecuteResultGetOutputFile, getOutputFile, location: default), new Binding(ExecuteResultGetOutputDirectory, getOutputDirectory, location: default), new Binding(ExecuteResultGetOutputFiles, getOutputFiles, location: default), new Binding(ExecuteResultGetRequiredOutputFiles, getRequiredOutputFiles, location: default), new Binding(ExecuteResultProcessOutputs, new EvaluationResult(processOutputs), location: default), }; if (isService) { bindings.Add(new Binding(CreateServiceResultServiceId, processOutputs.ProcessPipId, location: default)); } return(ObjectLiteral.Create(bindings, entry.InvocationLocation, entry.Path)); } // Local functions EvaluationResult GetOutputFile(Context contextArg, ModuleLiteral envArg, EvaluationStackFrame args) { var outputPath = Args.AsPathOrUndefined(args, 0, false); if (outputPath.IsValid && processOutputs.TryGetOutputFile(outputPath, out var file)) { return(EvaluationResult.Create(file)); } return(EvaluationResult.Undefined); } EvaluationResult GetOutputDirectory(Context contextArg, ModuleLiteral envArg, EvaluationStackFrame args) { var outputDir = Args.AsDirectory(args, 0); if (outputDir.IsValid && processOutputs.TryGetOutputDirectory(outputDir.Path, out var output)) { return(EvaluationResult.Create(output)); } return(EvaluationResult.Undefined); } EvaluationResult GetOutputFiles(Context contextArg, ModuleLiteral envArg, EvaluationStackFrame args) { var outputFiles = processOutputs.GetOutputFiles().Select(f => EvaluationResult.Create(f)).ToArray(); return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(outputFiles, entry.InvocationLocation, entry.Path))); } EvaluationResult GetRequiredOutputFiles(Context contextArg, ModuleLiteral envArg, EvaluationStackFrame args) { var outputFiles = processOutputs.GetRequiredOutputFiles().Select(f => EvaluationResult.Create(f)).ToArray(); return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(outputFiles, entry.InvocationLocation, entry.Path))); } }
/// <inheritdoc/> protected override EvaluationResult DoEval(Context context, ModuleLiteral env, EvaluationStackFrame frame) { if (context.TrackMethodInvocationStatistics) { Interlocked.Increment(ref context.Statistics.ArrayEvaluations); } // First, evaluating spread expressions to find out what the final size of the array will be. // If the element is null in the array then the result of the evaluation was 'undefined'. var spreadElements = new ArrayLiteral[m_spreadExpressionCount]; int spreadElementsIndex = 0; int finalLength = m_elements.Length - m_spreadExpressionCount; for (int i = 0; i < m_elements.Length; i++) { var element = m_elements[i]; if (element.IsSpreadOperator()) { var result = element.Eval(context, env, frame); // If any of the elements evaluate to an error, we shortcut the evaluation if (result.IsErrorValue) { return(result); } // spreads returning undefined add undefined as a single element when // they are not the first element of the array. // E.g [...undefined, 1] --> fail due to undefined // [1, ...undefined, 2] --> [1, undefined, 2] // [...undefined] --> fail due to undefined if (result.IsUndefined) { if (i == 0) { var spread = element as UnaryExpression; return(ReportError(context, spread)); } finalLength++; } if (result.Value is ArrayLiteral arrayResult) { spreadElements[spreadElementsIndex] = arrayResult; spreadElementsIndex++; finalLength += arrayResult.Length; } else { context.Errors.ReportUnexpectedValueType( env, this, result, typeof(ArrayLiteral)); return(EvaluationResult.Error); } } } // The final result of the evaluation var evaluatedArray = new EvaluationResult[finalLength]; spreadElementsIndex = 0; int currentPosition = 0; for (int i = 0; i < m_elements.Length; i++) { var element = m_elements[i]; if (element.IsSpreadOperator()) { var evaluatedArrayElement = spreadElements[spreadElementsIndex]; if (evaluatedArrayElement == null) { // Null means that the result was undefined. evaluatedArray[currentPosition] = EvaluationResult.Undefined; } else { evaluatedArrayElement.Copy(0, evaluatedArray, currentPosition, evaluatedArrayElement.Length); currentPosition += evaluatedArrayElement.Length; } spreadElementsIndex++; } else { var result = element.Eval(context, env, frame); if (result.IsErrorValue) { return(result); } evaluatedArray[currentPosition] = result; currentPosition++; } } return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(evaluatedArray, Location, m_path))); }
private static EvaluationResult Keys(Context context, ObjectLiteral receiver, EvaluationStackFrame captures) { var keys = receiver.Keys.Select(id => EvaluationResult.Create(context.FrontEndContext.StringTable.GetString(id))); return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(keys.ToArray(), receiver.Location, receiver.Path))); }
private ArrayLiteral CreateArray(params object[] elements) { return(ArrayLiteral.CreateWithoutCopy(elements.Select(e => EvaluationResult.Create(e)).ToArray(), default(LineInfo), AbsolutePath.Invalid)); }
private static EvaluationResult Values(Context context, OrderedMap receiver, EvaluationStackFrame captures) { var entry = context.TopStack; return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(receiver.Values(), entry.InvocationLocation, entry.Path))); }
private static EvaluationResult ToArray(Context context, MutableSet receiver, EvaluationStackFrame captures) { var entry = context.TopStack; return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(receiver.ToArray(), entry.InvocationLocation, entry.Path))); }