コード例 #1
0
 public MethodPatch(
     Method_referenceContext context,
     MethodBodySymbolContext methodBodySymbolContext,
     DiagnosticBag diagnostics) : base(diagnostics)
 {
     _context = context;
     _methodBodySymbolContext = methodBodySymbolContext;
     _method        = new Lazy <IMethod>(BindMethod);
     _typeArguments = new Lazy <ImmutableArray <IType> >(BindTypeArguments);
 }
コード例 #2
0
        public static void WarnIfUseOfMethodWhichCapturesUnassignedLocals(this MethodBodySymbolContext methodBodySymbolContext, IMethod target, DiagnosticBag diagnostics, Method_referenceContext syntax)
        {
            var currentMethod = methodBodySymbolContext.SourceSymbolContext.Scope;

            Release.Assert(currentMethod != null);
            if (target.DeclaringMethod == currentMethod)
            {
                if (target.InScopeAfter is { } declarationStatement)
                {
                    var currentStatement = methodBodySymbolContext.CurrentStatement;
                    Release.Assert(currentStatement != null);
                    if (declarationStatement.OrdinalPositionInMethod >= currentStatement.OrdinalPositionInMethod)
                    {
                        diagnostics.Add(new Diagnostic(
                                            new Location(syntax),
                                            ErrorCode.UseOfMethodWhichCapturesUnassignedLocals,
                                            ImmutableArray.Create <object?>(target)));
                    }
                }
            }
        }
コード例 #3
0
        public static IMethod BindMethod(
            QualifiedName MethodName,
            ImmutableArray <IType> TypeArguments,
            ImmutableArray <IExpression> Arguments,
            Method_referenceContext method_reference,
            MethodBodySymbolContext _methodBodySymbolContext,
            DiagnosticBag _diagnostics)
        {
            var methods = _methodBodySymbolContext.SourceSymbolContext.GetPossibleMethods(MethodName, TypeArguments);

            var matching =
                methods
                .Where(x => x.Parameters.Length == Arguments.Length)
                .Select(x =>
            {
                Diagnostic?diagnostic = null;
                if (TypeArguments.Length > 0)
                {
                    var typeParameters = x.TypeParameters;
                    if (!SourceSymbolContextExtensions.HasValidTypeArguments(
                            TypeArguments,
                            typeParameters,
                            out var diagnosticFunc))
                    {
                        diagnostic = diagnosticFunc(new Location(method_reference));
                    }
                    var substituted = x.Substitute(
                        SourceSymbolContextExtensions.CreateTypeMap(TypeArguments, typeParameters),
                        new Dictionary <IType, IType>());

                    return(method: substituted, diagnostic);
                }
                return(method: x, diagnostic: null);
            })
                .Where(x => x.method.Parameters.Zip(Arguments, (p, a) => a.Type.IsSubtypeOf(p.Type)).All(x => x))
                .ToList();

            if (matching.Count == 1)
            {
                var(target, diagnostic) = matching[0];

                if (diagnostic != null)
                {
                    _diagnostics.Add(diagnostic);
                }

                _methodBodySymbolContext.WarnIfUseOfMethodWhichCapturesUnassignedLocals(target, _diagnostics, method_reference);
                return(target);
            }


            if (matching.Count == 0)
            {
                _diagnostics.Add(new Diagnostic(
                                     new Location(method_reference),
                                     ErrorCode.MethodNotFound,
                                     ImmutableArray.Create <object?>(MethodName, Arguments)));
            }
            else
            {
                _diagnostics.Add(new Diagnostic(
                                     new Location(method_reference),
                                     ErrorCode.AmbigiousMethodReference,
                                     ImmutableArray.Create <object?>(matching)));
            }

            return(new ErrorMethod(MethodName, Arguments.Length));
        }