Example #1
0
        private EvaluationResult EvaluateAmbientProperty(Context context, ModuleLiteral env, CallableValue property)
        {
            context.SetPropertyProvenance(env.Path, Location);

            try
            {
                using (var frame = EvaluationStackFrame.Empty())
                {
                    return(property.Apply(context, frame));
                }
            }
            catch (EvaluationException e)
            {
                e.ReportError(context.Errors, env, Location, expression: this, context: context);
            }
            catch (OperationCanceledException)
            {
                return(EvaluationResult.Canceled);
            }
            catch (Exception exception)
            {
                context.Errors.ReportUnexpectedAmbientException(env, exception, Location);
                throw;
            }
            finally
            {
                context.UnsetPropertyProvenance();
            }

            return(EvaluationResult.Error);
        }
Example #2
0
        private async Task <object> EvaluateResolverCallback(Context context, QualifierId qualifier, FilePosition filePosition, ResolvedEntry resolvedEntry)
        {
            var qualifierValue = QualifierValue.Create(qualifier, context.QualifierValueCache, context.FrontEndContext.QualifierTable, context.StringTable);
            var env            = InstantiateFileModuleLiteral(context.ModuleRegistry, qualifierValue);

            using (var args = EvaluationStackFrame.Empty())
            {
                return(await resolvedEntry.ResolverCallback(context, env, args));
            }
        }
Example #3
0
 private EvaluationResult EvaluateWithNewNamedContextAndTemplate(ImmutableContextBase context, ref MutableContextFactory factory)
 {
     using (var frame = EvaluationStackFrame.Empty())
     {
         return(Evaluate(
                    context: context,
                    env: factory.Module,
                    args: frame,
                    factory: ref factory));
     }
 }
Example #4
0
        internal EvaluationStackFrame GetArgsForFrame(int frameIndex)
        {
            var entry = GetStackEntryForFrame(frameIndex);

            if (entry == null)
            {
                return(EvaluationStackFrame.Empty());
            }

            return(entry.DebugInfo.Frame);
        }
Example #5
0
        /// <summary>
        /// Evaluates this thunk in a new named context
        /// </summary>
        /// <remarks>
        /// V2-specific.
        /// </remarks>
        public EvaluationResult EvaluateWithNewNamedContext(Context context, ModuleLiteral module, FullSymbol contextName, LineInfo location)
        {
            Contract.Assert(CapturedTemplateReference != null);

            // We evaluate the captured template that was captured for this thunk in the same way (context and module) the thunk will be
            using (var frame = EvaluationStackFrame.Empty())
            {
                var templateValue = CapturedTemplateReference.Eval(context, module, frame);
                if (templateValue.IsErrorValue)
                {
                    return(EvaluationResult.Error);
                }

                var factory = new MutableContextFactory(this, contextName, module, templateValue.Value, location);
                return(EvaluateWithNewNamedContextAndTemplate(context, ref factory));
            }
        }
Example #6
0
        /// <summary>
        /// Evaluates given <paramref name="binding"/> that corresponds to field <paramref name="name"/>
        /// (<seealso cref="GetOrEvalField(Context, SymbolAtom, bool, ModuleLiteral, LineInfo)"/>)
        /// </summary>
        public EvaluationResult GetOrEvalFieldBinding(Context context, SymbolAtom name, ModuleBinding binding, LineInfo callingLocation)
        {
            object o = binding.Body;

            if (o is Thunk thunk)
            {
                return(GetOrEvalFieldBindingThunk(context, name, binding, thunk));
            }

            if (o is Expression expr)
            {
                using (var frame = EvaluationStackFrame.Empty())
                {
                    return(expr.Eval(context, this, frame));
                }
            }

            return(EvaluationResult.Create(o));
        }
Example #7
0
        private ObjectInfo CallableValueInfo(EvaluationContext context, CallableValue cv)
        {
            if (cv.IsProperty)
            {
                return(GetObjectInfo(context, cv.Apply(context, EvaluationStackFrame.Empty())));
            }

            var           captures = EvaluationStackFrame.Empty();
            var           @null    = UndefinedValue.Instance;
            Func <object> func     = CreateFunc();

            return(func != null
                ? FuncObjInfo(func, RenderCallableSignature(cv.CallableMember))
                : new ObjectInfo("function(" + RenderCallableSignature(cv.CallableMember) + ")"));

            // Local functions
            Func <object> CreateFunc()
            {
                var undefined = EvaluationResult.Undefined;

                switch (cv.CallableMember.Kind)
                {
                case SyntaxKind.Function0:
                    return(() => cv.Apply(context, captures).Value);

                case SyntaxKind.Function1 when cv.CallableMember.MinArity == 0:
                    return(() => cv.Apply(context, undefined, captures).Value);

                case SyntaxKind.Function2 when cv.CallableMember.MinArity == 0:
                    return(() => cv.Apply(context, undefined, undefined, captures).Value);

                case SyntaxKind.FunctionN when cv.CallableMember.MinArity == 0:
                    return(() => cv.Apply(context, BuildXL.Utilities.Collections.CollectionUtilities.EmptyArray <EvaluationResult>(), captures).Value);
                }

                return(null);
            }
        }
Example #8
0
        /// <summary>
        /// Evaluates a resolved entry that is not a Thunk
        /// </summary>
        internal EvaluationResult EvaluateNonThunkedResolvedSymbol(Context context, ModuleLiteral module, ResolvedEntry resolvedEntry)
        {
            Contract.Assert(resolvedEntry.Thunk == null);

            if (resolvedEntry.ConstantExpression != null)
            {
                return(EvaluationResult.Create(resolvedEntry.ConstantExpression.Value));
            }

            using (var empty = EvaluationStackFrame.Empty())
            {
                if (resolvedEntry.Expression != null)
                {
                    if (resolvedEntry.Expression is TypeOrNamespaceModuleLiteral namespaceExpression)
                    {
                        // If the resolved entry already evaluated to a namespace and the namespace
                        // is already qualified, then there is no reason for instantiating it twice. Just reusing it.
                        if (namespaceExpression.Qualifier.IsQualified())
                        {
                            return(EvaluationResult.Create(namespaceExpression));
                        }

                        return(EvaluationResult.Create(namespaceExpression.Instantiate(context.ModuleRegistry, GetFileQualifier())));
                    }

                    return(resolvedEntry.Expression.Eval(context, module, empty));
                }

                if (resolvedEntry.ResolverCallback != null)
                {
                    return(resolvedEntry.ResolverCallback(context, module, empty).GetAwaiter().GetResult());
                }

                Contract.Assert(resolvedEntry.Function != null);
                return(resolvedEntry.Function.Eval(context, module, empty));
            }
        }
Example #9
0
        /// <inheritdoc />
        protected override EvaluationResult DoEval(Context context, ModuleLiteral env, EvaluationStackFrame frame)
        {
            // There is some code duplication between this type and the CoerceQualifierTypeExpression.
            // But there is not clear how to reuse this because steps are 'slightly' different.
            var moduleCandidate = ModuleReference.Eval(context, env, frame);

            if (moduleCandidate.IsErrorValue || moduleCandidate.IsUndefined)
            {
                return(moduleCandidate);
            }

            // The type checker should make sure that 'this expression' evaluates to a module literal.
            var module = moduleCandidate.Value as ModuleLiteral;

            Contract.Assert(
                module != null,
                I($"The left hand-side of a withQualifier expression should evaluates to 'TypeOrNamespaceModuleLiteral' but got '{moduleCandidate.Value.GetType()}'"));

            Contract.Assert(module.CurrentFileModule != null, "module.CurrentFileModule != null");

            // QualifierExpression can be an object literal or anything that ended up as an object literal.
            EvaluationResult objectQualifier;

            using (var emptyFrame = EvaluationStackFrame.Empty())
            {
                objectQualifier = QualifierExpression.Eval(context, env, emptyFrame);
            }

            if (objectQualifier.IsErrorValue)
            {
                // Error has been reported.
                return(EvaluationResult.Error);
            }

            var qualifierLiteral = objectQualifier.Value as ObjectLiteral;

            Contract.Assert(
                qualifierLiteral != null,
                I($"The right hand-side of a withQualifier expression should evaluates to 'ObjectLiteral' but got '{objectQualifier.Value.GetType()}'"));

            if (!QualifierValue.TryCreate(context, env, qualifierLiteral, out QualifierValue qualifierValue, qualifierLiteral.Location))
            {
                // Error has been reported.
                return(EvaluationResult.Error);
            }

            // Coercing qualifier with a given value
            if (
                !QualifierUtilities.CoerceQualifierValueForV2(
                    context,
                    qualifierValue,
                    SourceQualifierSpaceId,
                    TargetQualifierSpaceId,
                    referencingLocation: Location.AsUniversalLocation(env, context),
                    referencedLocation: module.CurrentFileModule.Location.AsUniversalLocation(module.CurrentFileModule, context),
                    coercedQualifierValue: out QualifierValue coercedQualifierValue))
            {
                // Error has been reported
                return(EvaluationResult.Error);
            }

            var result = module.Instantiate(context.ModuleRegistry, coercedQualifierValue);

            return(EvaluationResult.Create(result));
        }
Example #10
0
        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)));
            }
        }
Example #11
0
        /// <inheritdoc />
        protected override EvaluationResult DoEval(Context context, ModuleLiteral env, EvaluationStackFrame frame)
        {
            // There is some code duplication between this type and the CoerceQualifierTypeExpression.
            // But there is not clear how to reuse this because steps are 'slightly' different.
            var moduleCandidate = ModuleReference.Eval(context, env, frame);

            if (moduleCandidate.IsErrorValue || moduleCandidate.IsUndefined)
            {
                return(moduleCandidate);
            }

            // The type checker should make sure that 'this expression' evaluates to a module literal.
            var module = moduleCandidate.Value as ModuleLiteral;

            Contract.Assert(
                module != null,
                I($"The left hand-side of a withQualifier expression should evaluates to 'TypeOrNamespaceModuleLiteral' but got '{moduleCandidate.Value.GetType()}'"));

            Contract.Assert(module.CurrentFileModule != null, "module.CurrentFileModule != null");
            var currentQualifier = env.CurrentFileModule.Qualifier.Qualifier;

            // QualifierExpression can be an object literal or anything that ended up as an object literal.
            EvaluationResult objectQualifier;

            using (var emptyFrame = EvaluationStackFrame.Empty())
            {
                objectQualifier = QualifierExpression.Eval(context, env, emptyFrame);
            }

            if (objectQualifier.IsErrorValue)
            {
                // Error has been reported.
                return(EvaluationResult.Error);
            }

            var requestedQualifier = objectQualifier.Value as ObjectLiteral;

            Contract.Assert(
                requestedQualifier != null,
                I($"The right hand-side of a withQualifier expression should evaluates to 'ObjectLiteral' but got '{objectQualifier.Value.GetType()}'"));

            // TODO: This can be made more efficient by talking with the qualifier table directly
            // and maintaining a global map of qualifier id to object literal rather than have many copies of
            // object literal floating around, but that would be more changes than warranted at the moment
            // since withqualifier is not used that heavily at the moment, when this starts showing up on profiles
            // we should consider improving the logic here.
            var qualifierBindings = new Dictionary <StringId, Binding>();

            foreach (var member in currentQualifier.Members)
            {
                qualifierBindings[member.Key] = new Binding(member.Key, member.Value, requestedQualifier.Location);
            }

            foreach (var member in requestedQualifier.Members)
            {
                if (member.Value.IsUndefined)
                {
                    // setting a value to undefined implies explicitly removing they qualifier key.
                    qualifierBindings.Remove(member.Key);
                }
                else
                {
                    qualifierBindings[member.Key] = new Binding(member.Key, member.Value, requestedQualifier.Location);
                }
            }
            var qualifierToUse = ObjectLiteral.Create(qualifierBindings.Values.ToArray());


            if (!QualifierValue.TryCreate(context, env, qualifierToUse, out QualifierValue qualifierValue, requestedQualifier.Location))
            {
                // Error has been reported.
                return(EvaluationResult.Error);
            }

            // Coercing qualifier with a given value
            if (
                !QualifierUtilities.CoerceQualifierValueForV2(
                    context,
                    qualifierValue,
                    SourceQualifierSpaceId,
                    TargetQualifierSpaceId,
                    referencingLocation: Location.AsUniversalLocation(env, context),
                    referencedLocation: module.CurrentFileModule.Location.AsUniversalLocation(module.CurrentFileModule, context),
                    coercedQualifierValue: out QualifierValue coercedQualifierValue))
            {
                // Error has been reported
                return(EvaluationResult.Error);
            }

            var result = module.Instantiate(context.ModuleRegistry, coercedQualifierValue);

            return(EvaluationResult.Create(result));
        }