Exemplo n.º 1
0
        /// <summary>
        /// Resolves an object creation.
        /// </summary>
        /// <param name="type">Type of the object to create.</param>
        /// <param name="arguments">
        /// Arguments passed to the constructor.
        /// The resolver may mutate this array to wrap elements in <see cref="CastExpression"/>s!
        /// </param>
        /// <param name="argumentNames">
        /// The argument names. Pass the null string for positional arguments.
        /// </param>
        /// <param name="allowProtectedAccess">
        /// Whether to allow calling protected constructors.
        /// This should be false except when resolving constructor initializers.
        /// </param>
        /// <param name="initializerStatements">
        /// Statements for Objects/Collections initializer.
        /// <see cref="InvocationExpression.InitializerStatements"/>
        /// </param>
        /// <returns>InvocationResolveResult or ErrorResolveResult</returns>
        public static Expression ResolveObjectCreation(ResolveContext rc, Location l, IType type, Expression[] arguments, string[] argumentNames = null, bool allowProtectedAccess = false, IList <Expression> initializerStatements = null)
        {
            if (type.Kind == TypeKind.Delegate)
            {
                if (arguments == null || arguments.Length != 1)
                {
                    rc.Report.Error(0, l, "Method name expected");
                    return(null);
                }
                Expression input  = arguments[0];
                IMethod    invoke = input.Type.GetDelegateInvokeMethod();
                if (invoke != null)
                {
                    input = new MethodGroupExpression(
                        input, invoke.Name,
                        methods: new[] { new MethodListWithDeclaringType(input.Type)
                                         {
                                             invoke
                                         } },
                        typeArguments: EmptyList <IType> .Instance
                        );
                }
                return(rc.Convert(input, type));
            }
            OverloadResolution or            = rc.CreateOverloadResolution(arguments, argumentNames);
            MemberLookup       lookup        = rc.CreateMemberLookup();
            List <IMethod>     allApplicable = null;

            foreach (IMethod ctor in type.GetConstructors())
            {
                if (lookup.IsAccessible(ctor, allowProtectedAccess))
                {
                    or.AddCandidate(ctor);
                }
                else
                {
                    or.AddCandidate(ctor, OverloadResolutionErrors.Inaccessible);
                }
            }
            if (or.BestCandidate != null)
            {
                return(or.CreateInvocation(null, initializerStatements));
            }
            else
            {
                rc.Report.Error(0, l,
                                "The type `{0}' does not contain a constructor that takes `{1}' arguments",
                                type.ToString(), arguments != null ? arguments.Length.ToString() : "0");
                return(ErrorResult);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Resolves an indexer access.
        /// </summary>
        /// <param name="target">Target expression.</param>
        /// <param name="arguments">
        /// Arguments passed to the indexer.
        /// The resolver may mutate this array to wrap elements in <see cref="CastExpression"/>s!
        /// </param>
        /// <param name="argumentNames">
        /// The argument names. Pass the null string for positional arguments.
        /// </param>
        /// <returns>ArrayAccessResolveResult, InvocationResolveResult, or ErrorResolveResult</returns>
        public Expression ResolveIndexer(ResolveContext rc, Expression target, Expression[] arguments, string[] argumentNames = null)
        {
            switch (target.Type.Kind)
            {
            case TypeKind.Array:
                // �6.6.1 Array access
                if (argumentNames != null && argumentNames.Length > 0)
                {
                    rc.Report.Error(0, Arguments.args.Where(x => x is NamedArgument).First().loc, "An element access expression cannot use named argument");
                }


                return(new ArrayAccessExpression(((ElementTypeSpec)target.Type).ElementType, target, arguments));

            case TypeKind.Pointer:
                // �.5.3 Pointer element access
                if (argumentNames != null && argumentNames.Length > 0)
                {
                    rc.Report.Error(0, Arguments.args.Where(x => x is NamedArgument).First().loc, "An element access expression cannot use named argument");
                }

                return(new PointerArithmeticExpression(((ElementTypeSpec)target.Type).ElementType, target, arguments));
            }

            // �6.6.2 Indexer access
            MemberLookup lookup   = rc.CreateMemberLookup();
            var          indexers = lookup.LookupIndexers(target);

            OverloadResolution or = rc.CreateOverloadResolution(arguments, argumentNames);

            or.AddMethodLists(indexers);
            if (or.BestCandidate != null)
            {
                return(or.CreateInvocation(target));
            }
            else
            {
                rc.Report.Error(0, loc, "Cannot apply indexing with [] to an expression of type `{0}'",
                                target.Type.ToString());
                return(null);
            }
        }
Exemplo n.º 3
0
        Expression SetUserDefinedOperationInformations(ResolveContext rc, OverloadResolution r)
        {//TODO:Is It OK
            if (r.BestCandidateErrors != OverloadResolutionErrors.None)
            {
                rc.Report.Error(0, loc, "Operator `{0}' is ambiguous on an operand of type `{1}'",
                                OperName(Oper), Expr.Type.ToString());
                return(r.CreateInvocation(null));
            }


            IMethod method   = (IMethod)r.BestCandidate;
            var     operands = r.GetArgumentsWithConversions();

            this.operatortype              = ResolveContext.GetLinqNodeType(this.Oper, rc.checkForOverflow);
            this.isLiftedOperator          = method is OverloadResolution.ILiftedOperator;
            this.ResolvedType              = method.ReturnType;
            this.Expr                      = operands[0];
            this.userDefinedOperatorMethod = method;
            _resolved                      = true;
            return(this);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Resolves an invocation.
        /// </summary>
        /// <param name="target">The target of the invocation. Usually a MethodGroupResolveResult.</param>
        /// <param name="arguments">
        /// Arguments passed to the method.
        /// The resolver may mutate this array to wrap elements in <see cref="ConversionResolveResult"/>s!
        /// </param>
        /// <param name="argumentNames">
        /// The argument names. Pass the null string for positional arguments.
        /// </param>
        /// <returns>InvocationExpression</returns>
        private Expression ResolveInvocation(ResolveContext rc, Expression target, Expression[] arguments, string[] argumentNames, bool allowOptionalParameters)
        {
            // C# 4.0 spec: §7.6.5
            MethodGroupExpression mgrr = target as MethodGroupExpression;

            if (mgrr != null)
            {
                OverloadResolution or = mgrr.PerformOverloadResolution(rc.compilation, arguments, argumentNames, checkForOverflow: rc.checkForOverflow, conversions: rc.conversions, allowOptionalParameters: allowOptionalParameters);
                if (or.BestCandidate != null)
                {
                    var m = or.BestCandidate;

                    if (arguments == null && m.Name == DestructorDeclaration.MetadataName)
                    {
                        rc.Report.Error(0, loc, "Destructors cannot be called directly. Consider calling IDisposable.Dispose if available");
                    }

                    CheckSpecialMethod(rc, m);


                    if (or.BestCandidate.IsStatic && !or.IsExtensionMethodInvocation && !(mgrr.TargetResult is TypeExpression))
                    {
                        return(or.CreateInvocation(new TypeExpression(mgrr.TargetType), returnTypeOverride:  null));
                    }
                    else
                    {
                        return(or.CreateInvocation(mgrr.TargetResult, returnTypeOverride: null));
                    }
                }
                else
                {
                    // No candidate found at all (not even an inapplicable one).
                    // This can happen with empty method groups (as sometimes used with extension methods)
                    rc.Report.Error(0, loc, "`{0}' does not contain a definition for `{1}'",
                                    mgrr.TargetType.ToString(), mgrr.MethodName);
                    return(null);
                }
            }
            if (target == null && expr is SimpleName)
            {
                rc.Report.Error(0, loc, "`{0}' does not contain a definition for `{1}'",
                                rc.CurrentTypeDefinition.ToString(), expr.GetSignatureForError());
                return(null);
            }
            else if (target == null)
            {
                return(null);
            }


            IMethod invokeMethod = target.Type.GetDelegateInvokeMethod();

            if (invokeMethod != null)
            {
                // is it a delegate ?
                if (target.Type.Kind != TypeKind.Delegate)
                {
                    rc.Report.Error(0, loc, "Cannot invoke a non-delegate type `{0}'",
                                    target.Type.ToString());
                    return(null);
                }
                OverloadResolution or = rc.CreateOverloadResolution(arguments, argumentNames);
                or.AddCandidate(invokeMethod);

                return(new Invocation(
                           target, invokeMethod, //invokeMethod.ReturnType.Resolve(context),
                           or.GetArgumentsWithConversionsAndNames(), or.BestCandidateErrors,
                           isExpandedForm: or.BestCandidateIsExpandedForm,
                           isDelegateInvocation: true,
                           argumentToParameterMap: or.GetArgumentToParameterMap(),
                           returnTypeOverride: null));
            }

            rc.Report.Error(0, loc, "The member `{0}' cannot be used as method or delegate",
                            target.GetSignatureForError());

            return(ErrorResult);
        }