Example #1
0
        /// <inheritdoc />
        protected override EvaluationResult DoEval(Context context, ModuleLiteral env, EvaluationStackFrame frame)
        {
            var receiver = ThisExpression.Eval(context, env, frame);

            if (receiver.IsErrorValue)
            {
                return(EvaluationResult.Error);
            }

            if (receiver.Value is ObjectLiteral obj)
            {
                if (Selector.GetParent(context.FrontEndContext.SymbolTable) != FullSymbol.Invalid)
                {
                    context.Errors.ReportFailResolveModuleSelector(env, this);
                    return(EvaluationResult.Error);
                }

                return(obj.GetOrEvalField(
                           context,
                           Selector.GetName(context.FrontEndContext.SymbolTable),
                           recurs: false,
                           origin: env,
                           location: Location));
            }

            context.Errors.ReportUnexpectedValueType(
                env,
                ThisExpression,
                receiver, new[] { typeof(ModuleLiteral), typeof(ObjectLiteral) });

            return(EvaluationResult.Error);
        }
Example #2
0
        /// <inheritdoc />
        protected override EvaluationResult DoEval(Context context, ModuleLiteral env, EvaluationStackFrame frame)
        {
            var e = ThisExpression.Eval(context, env, frame);

            if (e.IsErrorValue)
            {
                return(EvaluationResult.Error);
            }

            var indexObj = Index.Eval(context, env, frame);

            if (indexObj.IsErrorValue)
            {
                return(EvaluationResult.Error);
            }

            // Extracting local to avoid casting multiple times
            var stringIndexer = indexObj.Value as string;

            if (e.Value is ArrayLiteral arrayLiteral)
            {
                if (indexObj.Value is int index)
                {
                    if (index < 0 || index >= arrayLiteral.Length)
                    {
                        // This behavior is different from the TypeScript one, but this is actually helpful
                        context.Errors.ReportArrayIndexOufOfRange(env, this, index, arrayLiteral.Length);
                        return(EvaluationResult.Error);
                    }

                    return(arrayLiteral[index]);
                }

                // indexer for an array can be a number for getting elements, or string
                if (stringIndexer == null)
                {
                    context.Errors.ReportUnexpectedValueType(env, Index, indexObj, typeof(int), typeof(string));
                    return(EvaluationResult.Error);
                }

                // Falling back to object literal case if the indexer is a string.
            }

            if (e.Value is ObjectLiteral objectLiteral)
            {
                if (stringIndexer != null)
                {
                    var selectorId = context.FrontEndContext.StringTable.AddString(stringIndexer);
                    return(objectLiteral.GetOrEvalField(context, selectorId, recurs: false, origin: env, location: Location));
                }

                context.Errors.ReportUnexpectedValueType(env, Index, indexObj, typeof(string));
                return(EvaluationResult.Error);
            }

            // Indexer in typescript never fails and return undefined.
            // Following this pattern.
            return(EvaluationResult.Undefined);
        }
Example #3
0
        /// <inheritdoc />
        protected override EvaluationResult DoEval(Context context, ModuleLiteral env, EvaluationStackFrame frame)
        {
            var receiver = ThisExpression.Eval(context, env, frame);

            if (receiver.IsErrorValue)
            {
                return(EvaluationResult.Error);
            }

            if (receiver.IsUndefined)
            {
                context.Errors.ReportFailResolveSelectorDueToUndefined(env, this);
                return(EvaluationResult.Error);
            }

            if (receiver.Value is Expression thisExpressionResult)
            {
                if (thisExpressionResult.TryProject(context, Selector, env, context.PredefinedTypes, out EvaluationResult projectionResult, Location))
                {
                    return(projectionResult);
                }

                context.Errors.ReportUnexpectedValueType(
                    env,
                    ThisExpression,
                    receiver, typeof(ObjectLiteral), typeof(ArrayLiteral), typeof(ModuleLiteral));
                return(EvaluationResult.Error);
            }

            // Trying to find member function for well-known types.
            var boundMember = context.PredefinedTypes.ResolveMember(receiver.Value, Selector);

            if (boundMember != null)
            {
                // If bound member represents a property we need to evaluate it.
                return(boundMember.IsProperty ? EvaluateAmbientProperty(context, env, boundMember) : EvaluationResult.Create(boundMember));
            }

            context.Errors.ReportMissingProperty(env, Selector, receiver.Value, Location);
            return(EvaluationResult.Error);
        }