// 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); }
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); }
override public void OnBlock(Block block) { var currentChecked = _checked; _checked = AstAnnotations.IsChecked(block, Parameters.Checked); Visit(block.Statements); _checked = currentChecked; }
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)); }
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)); } }
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); } } }
/// <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); }
override public void OnGotoStatement(GotoStatement node) { AstAnnotations.SetTryBlockDepth(node, _state.CurrentTryBlockDepth); _state.AddLabelReference(node.Label); }