示例#1
0
        // Sometimes, for the purpose of overload resolution, it doesn't matter which overload
        // you pick, because they all take the same callable type and only differ in the rest of
        // the param list
        private IMethod ResolveAmbiguousInvocationContext(Ambiguous entity, int argumentIndex)
        {
            var candidates = entity.Entities
                             .OfType <IMethod>()
                             .Where(m => m.GetParameters().Length > argumentIndex && m.GetParameters()[argumentIndex].Type is ICallableType)
                             .ToArray();

            if (candidates.Length > 0)
            {
                var first = candidates[0];
                if (candidates.Length == 1)
                {
                    return(first);
                }
                var correspondingType = first.GetParameters()[argumentIndex].Type;
                if (candidates.Skip(1).All(m => m.GetParameters()[argumentIndex].Type == correspondingType))
                {
                    return(first);
                }
                var returnType = ((ICallableType)first.GetParameters()[argumentIndex].Type).GetSignature().ReturnType;
                if (candidates.Skip(1).All(m => ((ICallableType)m.GetParameters()[argumentIndex].Type).GetSignature().ReturnType == returnType))
                {
                    _closure["$InferredReturnType"] = returnType;
                }
            }
            AstAnnotations.MarkAmbiguousSignature(MethodInvocationContext);
            AstAnnotations.MarkAmbiguousSignature(_closure);
            return(null);
        }
示例#2
0
        private static SlicingExpression CreateRawArraySlicing(ReferenceExpression arrayRef, Expression numRef, IType elementType)
        {
            SlicingExpression expression = new SlicingExpression(arrayRef.CloneNode(), numRef.CloneNode());

            expression.ExpressionType = elementType;
            AstAnnotations.MarkRawArrayIndexing(expression);
            return(expression);
        }
示例#3
0
        override public void OnBlock(Block block)
        {
            var currentChecked = _checked;

            _checked = AstAnnotations.IsChecked(block, Parameters.Checked);

            Visit(block.Statements);

            _checked = currentChecked;
        }
示例#4
0
        override public void OnLabelStatement(LabelStatement node)
        {
            AstAnnotations.SetTryBlockDepth(node, _state.TryBlockDepth);

            if (_state.ResolveLabel(node.Name) != null)
            {
                Error(CompilerErrorFactory.LabelAlreadyDefined(node, _currentMethod, node.Name));
                return;
            }

            _state.AddLabel(new InternalLabel(node));
        }
示例#5
0
        override public void OnLabelStatement(LabelStatement node)
        {
            AstAnnotations.SetTryBlockDepth(node, _state.CurrentTryBlockDepth);

            if (null == _state.ResolveLabel(node.Name))
            {
                _state.AddLabel(new InternalLabel(node));
            }
            else
            {
                Error(
                    CompilerErrorFactory.LabelAlreadyDefined(node,
                                                             _currentMethod.FullName,
                                                             node.Name));
            }
        }
示例#6
0
        override public void OnGotoStatement(GotoStatement node)
        {
            LabelStatement target = ((InternalLabel)node.Label.Entity).LabelStatement;

            int gotoDepth   = AstAnnotations.GetTryBlockDepth(node);
            int targetDepth = AstAnnotations.GetTryBlockDepth(target);

            if (gotoDepth < targetDepth)
            {
                BranchError(node, target);
            }
            else if (gotoDepth == targetDepth)
            {
                Node gotoParent  = AstUtil.GetParentTryExceptEnsure(node);
                Node labelParent = AstUtil.GetParentTryExceptEnsure(target);
                if (gotoParent != labelParent)
                {
                    BranchError(node, target);
                }
            }
        }
示例#7
0
        /// <summary>
        /// Optimize the <c>for item in array</c> construct
        /// </summary>
        /// <param name="node">the for statement to check</param>
        private void CheckForItemInArrayLoop(ForStatement node)
        {
            ArrayType enumeratorType = GetExpressionType(node.Iterator) as ArrayType;

            if (enumeratorType == null || enumeratorType.GetArrayRank() > 1)
            {
                return;
            }
            IType elementType = enumeratorType.GetElementType();

            if (elementType is InternalCallableType)
            {
                return;
            }

            Block body = new Block(node.LexicalInfo);

            InternalLocal indexVariable  = DeclareTempLocal(TypeSystemServices.IntType);
            Expression    indexReference = CodeBuilder.CreateReference(indexVariable);

            // __num = 0
            body.Add(
                CodeBuilder.CreateAssignment(
                    indexReference,
                    CodeBuilder.CreateIntegerLiteral(0)));


            InternalLocal       arrayVar = DeclareTempLocal(node.Iterator.ExpressionType);
            ReferenceExpression arrayRef = CodeBuilder.CreateReference(arrayVar);

            // __arr = <arr>
            body.Add(
                CodeBuilder.CreateAssignment(
                    arrayRef,
                    node.Iterator));

            InternalLocal endVar = CodeBuilder.DeclareTempLocal(
                _currentMethod,
                TypeSystemServices.IntType);
            ReferenceExpression endRef = CodeBuilder.CreateReference(endVar);

            // __end = __arr.Length
            body.Add(
                CodeBuilder.CreateAssignment(
                    endRef,
                    CodeBuilder.CreateMethodInvocation(
                        arrayRef,
                        Array_get_Length)));

            // while __num < __end:
            WhileStatement ws = new WhileStatement(node.LexicalInfo);

            ws.Condition = CodeBuilder.CreateBoundBinaryExpression(
                TypeSystemServices.BoolType,
                BinaryOperatorType.LessThan,
                indexReference,
                endRef);

            if (1 == node.Declarations.Count)
            {
                IEntity loopVariable = node.Declarations[0].Entity;
                node.Block.ReplaceNodes(
                    new NodePredicate(new EntityPredicate(loopVariable).Matches),
                    CreateRawArraySlicing(arrayRef, indexReference, elementType));
            }
            else
            {
                //  alpha, bravo, charlie = arr[__num]
                UnpackExpression(
                    ws.Block,
                    CreateRawArraySlicing(arrayRef, indexReference, elementType),
                    node.Declarations);
            }

            //	<block>
            ws.Block.Add(node.Block);

            FixContinueStatements(node, ws);

            //  __num += 1
            BinaryExpression assignment = CodeBuilder.CreateAssignment(
                indexReference,
                CodeBuilder.CreateBoundBinaryExpression(
                    TypeSystemServices.IntType,
                    BinaryOperatorType.Addition,
                    indexReference,
                    CodeBuilder.CreateIntegerLiteral(1)));

            AstAnnotations.MarkUnchecked(assignment);

            ws.Block.Add(assignment);
            body.Add(ws);
            ReplaceCurrentNode(body);
        }
示例#8
0
        override public void OnGotoStatement(GotoStatement node)
        {
            AstAnnotations.SetTryBlockDepth(node, _state.CurrentTryBlockDepth);

            _state.AddLabelReference(node.Label);
        }