public UserOperatorCall(MethodGroupExpression method, Arguments args, SourceSpan span) { _method = method; _arguments = args; Type = ((MethodInfo)method).ReturnType; ExpressionClass = ExpressionClass.Value; Span = span; }
public override Expression DoResolve(ParseContext ec) { var typeExpression = _requestedType.ResolveAsTypeTerminal(ec, false); if (typeExpression == null) { return(null); } Type = _resolvedType = typeExpression.Type; if (Arguments == null) { var c = Constantify(_resolvedType); if (c != null) { return(ReducedExpression.Create(c, this)); } } if (TypeManager.IsGenericParameter(_resolvedType)) { var gc = TypeManager.GetTypeParameterConstraints(_resolvedType); if ((gc == null) || (!gc.HasConstructorConstraint && !gc.IsValueType)) { ec.ReportError( 304, string.Format( "Cannot create an instance of the variable type '{0}' because it doesn't have the new() constraint.", TypeManager.GetCSharpName(_resolvedType)), Span); return(null); } if ((_arguments != null) && (_arguments.Count != 0)) { ec.ReportError( 417, string.Format( "'{0}': cannot provide arguments when creating an instance of a variable type.", TypeManager.GetCSharpName(_resolvedType)), Span); return(null); } ExpressionClass = ExpressionClass.Value; return(this); } if (_resolvedType.IsAbstract && _resolvedType.IsSealed) { ec.ReportError( 712, string.Format( "Cannot create an instance of the static class '{0}'.", TypeManager.GetCSharpName(_resolvedType)), Span); return(null); } if (_resolvedType.IsInterface || _resolvedType.IsAbstract) { ec.ReportError( 144, string.Format( "Cannot create an instance of the abstract class or interface '{0}'.", TypeManager.GetCSharpName(_resolvedType)), Span); return(null); } var isStruct = TypeManager.IsStruct(_resolvedType); ExpressionClass = ExpressionClass.Value; // // SRE returns a match for .ctor () on structs (the object constructor), // so we have to manually ignore it. // if (isStruct && (_arguments != null) && !_arguments.Any()) { return(this); } // For member-lookup, treat 'new Foo (bar)' as call to 'foo.ctor (bar)', where 'foo' is of type 'Foo'. var memberLookup = MemberLookupFinal( ec, _resolvedType, _resolvedType, ConstructorInfo.ConstructorName, MemberTypes.Constructor, AllBindingFlags | BindingFlags.DeclaredOnly, Span); if (_arguments != null) { _arguments.Resolve(ec); } if (memberLookup == null) { return(null); } _constructor = memberLookup as MethodGroupExpression; if (_constructor == null) { memberLookup.OnErrorUnexpectedKind(ec, ResolveFlags.MethodGroup, Span); return(null); } _constructor = _constructor.OverloadResolve(ec, ref _arguments, false, Span); return((_constructor == null) ? null : this); }
// // Unary user type overload resolution // private Expression ResolveUserType(ParseContext ec, Expression expr) { Expression bestExpr = ResolveUserOperator(ec, expr); if (bestExpr != null) { return(bestExpr); } var predefined = _predefinedOperators[Operator]; foreach (var t in predefined) { var operExpr = ConvertExpression.MakeExplicitConversion(ec, expr, t, expr.Span); if (operExpr == null) { continue; } // // decimal type is predefined but has user-operators // if (operExpr.Type == TypeManager.CoreTypes.Decimal) { operExpr = ResolveUserType(ec, operExpr); } else { operExpr = ResolvePrimitivePredefinedType(ec, operExpr); } if (operExpr == null) { continue; } if (bestExpr == null) { bestExpr = operExpr; continue; } int result = MethodGroupExpression.BetterTypeConversion(ec, bestExpr.Type, t); if (result == 0) { ec.ReportError( 35, string.Format( "Operator '{0}' is ambiguous on an operand of type '{1}'.", GetOperatorToken(Operator), TypeManager.GetCSharpName(expr.Type)), Span); break; } if (result == 2) { bestExpr = operExpr; } } if (bestExpr == null) { return(null); } // // HACK: Decimal user-operator is included in standard operators // if (bestExpr.Type == TypeManager.CoreTypes.Decimal) { return(bestExpr); } Operand = bestExpr; Type = bestExpr.Type; return(this); }
public override Expression DoResolve(ParseContext ec) { // Don't resolve already resolved expression if (ExpressionClass != ExpressionClass.Invalid) { return(this); } var resolvedTarget = Target.Resolve(ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup); if (resolvedTarget == null) { return(null); } // Next, evaluate all the expressions in the argument list if (_arguments != null && !_argumentsResolved) { _arguments.Resolve(ec); _argumentsResolved = true; } var expressionType = resolvedTarget.Type; MethodGroup = resolvedTarget as MethodGroupExpression; if (MethodGroup == null) { if (expressionType != null && TypeManager.IsDelegateType(expressionType)) { MethodGroup = (resolvedTarget = new MemberAccessExpression { Left = resolvedTarget, Name = "Invoke", Span = Span }.Resolve(ec)) as MethodGroupExpression; } var memberExpression = resolvedTarget as MemberExpression; if (memberExpression == null) { resolvedTarget.OnErrorUnexpectedKind(ec, ResolveFlags.MethodGroup, Span); return(null); } if (MethodGroup == null) { MethodGroup = ec.LookupExtensionMethod( memberExpression.Type, memberExpression.Name, Span); if (MethodGroup != null) { ((ExtensionMethodGroupExpression)MethodGroup).ExtensionExpression = memberExpression.InstanceExpression; } } if (MethodGroup == null) { ec.ReportError( 1955, string.Format( "The member '{0}' cannot be used as method or delegate.", resolvedTarget.GetSignatureForError()), Span); return(null); } } MethodGroup = DoResolveOverload(ec); if (MethodGroup == null) { return(null); } var method = (MethodInfo)MethodGroup; if (method != null) { Type = method.ReturnType; // TODO: this is a copy of mg.ResolveMemberAccess method var instanceExpression = MethodGroup.InstanceExpression; if (method.IsStatic) { if (instanceExpression == null || instanceExpression is EmptyExpression || MethodGroup.IdenticalTypeName) { MethodGroup.InstanceExpression = null; } else { // TODO: MemberExpression.error176(ec, loc, mg.GetSignatureForError()); return(null); } } else { if (instanceExpression == null || instanceExpression == EmptyExpression.Null) { // TODO: SimpleName.Error_ObjectRefRequired(ec, loc, mg.GetSignatureForError()); } } } if (method == null) { return(null); } IsSpecialMethodInvocation(ec, method, Span); ExpressionClass = ExpressionClass.Value; return(this); }
public static Delegate[] GetDelegates(IEnumerable <object> objects) => ( from t in objects from m in t.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance) where m.DeclaringType != typeof(object) select t is Delegate ? (Delegate)t : m.CreateDelegate(MethodGroupExpression.GetDelegateType(m), t) ).ToArray();
void MakeOutputTypeInference(AST.Expression e, IType t) { // If E is an anonymous function with inferred return type U (§7.5.2.12) and T is a delegate type or expression // tree type with return type Tb, then a lower-bound inference (§7.5.2.9) is made from U to Tb. LambdaExpression lrr = e as LambdaExpression; if (lrr != null) { IMethod m = GetDelegateOrExpressionTreeSignature(t); if (m != null) { IType inferredReturnType; if (lrr.IsImplicitlyTyped) { if (m.Parameters.Count != lrr.Parameters.Count) { return; // cannot infer due to mismatched parameter lists } TypeParameterSubstitution substitution = GetSubstitutionForFixedTPs(); IType[] inferredParameterTypes = new IType[m.Parameters.Count]; for (int i = 0; i < inferredParameterTypes.Length; i++) { IType parameterType = m.Parameters[i].Type; inferredParameterTypes[i] = parameterType.AcceptVisitor(substitution); } inferredReturnType = lrr.GetInferredReturnType(inferredParameterTypes); } else { inferredReturnType = lrr.GetInferredReturnType(null); } MakeLowerBoundInference(inferredReturnType, m.ReturnType); return; } } // Otherwise, if E is a method group and T is a delegate type or expression tree type // with parameter types T1…Tk and return type Tb, and overload resolution // of E with the types T1…Tk yields a single method with return type U, then a lower-bound // inference is made from U to Tb. MethodGroupExpression mgrr = e as MethodGroupExpression; if (mgrr != null) { IMethod m = GetDelegateOrExpressionTreeSignature(t); if (m != null) { Expression[] args = new Expression[m.Parameters.Count]; TypeParameterSubstitution substitution = GetSubstitutionForFixedTPs(); for (int i = 0; i < args.Length; i++) { IParameter param = m.Parameters[i]; IType parameterType = param.Type.AcceptVisitor(substitution); if ((param.IsRef || param.IsOut) && parameterType.Kind == TypeKind.ByReference) { parameterType = ((ByReferenceType)parameterType).ElementType; args[i] = new ByReferenceExpression(parameterType, param.IsOut); } else { args[i] = new Expression(parameterType); } } var or = mgrr.PerformOverloadResolution(compilation, args, allowExpandingParams: false, allowOptionalParameters: false); if (or.FoundApplicableCandidate && or.BestCandidateAmbiguousWith == null) { IType returnType = or.GetBestCandidateWithSubstitutedTypeArguments().ReturnType; MakeLowerBoundInference(returnType, m.ReturnType); } } return; } // Otherwise, if E is an expression with type U, then a lower-bound inference is made from U to T. if (IsValidType(e.Type)) { MakeLowerBoundInference(e.Type, t); } }
public ConditionalLogicalOperator(MethodGroupExpression operMethod, Arguments arguments, SourceSpan loc) : base(operMethod, arguments, loc) { }