Ejemplo n.º 1
0
        protected override void VisitMethodCallSyntax(MethodCallSyntax pNode)
        {
            base.VisitMethodCallSyntax(pNode);

            //We only care about methods that aren't in the current module
            if (_module != null || Namespace != null)
            {
                System.Diagnostics.Debug.Assert(_module != null || _unit.HasReference(Namespace));

                //Get the referenced module
                var mod = Namespace == null ? _module : _unit.GetReference(Namespace);

                //Find the method
                foreach (var m in mod.Module.Methods)
                {
                    if (IsCalledMethod(m, pNode))
                    {
                        var rn = new ReferencedNode(m, mod.Cache);
                        if (!MethodNodes.Contains(rn))
                        {
                            MethodNodes.Add(rn);

                            //Get any type/methods that this method references
                            var mrv = new ModuleReferenceVisitor(mod.Cache, _context, mod);
                            mrv.MethodNodes.Add(rn);

                            mrv.Visit(m);
                            MethodNodes.AddRange(mrv.MethodNodes);
                            TypeNodes.AddRange(mrv.TypeNodes);
                        }
                    }
                }
            }
        }
Ejemplo n.º 2
0
        protected virtual SyntaxNode VisitMethodCallSyntax(MethodCallSyntax pNode)
        {
            List <SyntaxNode> arguments = new List <SyntaxNode>(pNode.Arguments.Count);

            foreach (var a in pNode.Arguments)
            {
                arguments.Add(Visit(a));
            }
            return(SyntaxFactory.MethodCall(pNode.Value, arguments));
        }
Ejemplo n.º 3
0
        public static bool HasUndefinedCastAsArg(MethodCallSyntax pMethod)
        {
            for (int i = 0; i < pMethod.Arguments.Count; i++)
            {
                if (pMethod.Arguments[i].Type == SmallTypeCache.Undefined &&
                    pMethod.Arguments[i].SyntaxType == SyntaxType.Cast)
                {
                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 4
0
        protected virtual void VisitMethodCallSyntax(MethodCallSyntax pNode)
        {
            var n = Namespace;

            Namespace = null;

            using (var t = Store.AddValue <SmallType>("__Type", null))
            {
                foreach (var a in pNode.Arguments)
                {
                    Visit(a);
                }
            }

            Namespace = n;
        }
Ejemplo n.º 5
0
        protected override SyntaxNode VisitMethodCallSyntax(MethodCallSyntax pNode)
        {
            if (_methodsToPoly.ContainsKey(pNode.Value))
            {
                var method = _unit.MatchMethod(pNode, _methodsToPoly[pNode.Value]);
                if (method == null)
                {
                    throw new InvalidOperationException("Unable to find matching method");
                }

                if (TryPolyMethod(method, ref pNode))
                {
                    return(pNode);
                }
            }
            return(base.VisitMethodCallSyntax(pNode));
        }
Ejemplo n.º 6
0
        protected override void VisitMethodCallSyntax(MethodCallSyntax pNode)
        {
            SmallType[] types = SyntaxHelper.SelectNodeTypes(pNode.Arguments);

            //Current type can be undefined if we have a method call on a type that isn't defined
            if (CurrentType != SmallTypeCache.Undefined)
            {
                var methodFound = SyntaxHelper.FindMethodOnType(out MethodDefinition m, _unit, Namespace, pNode.Value, CurrentType, types);
                System.Diagnostics.Debug.Assert(methodFound == Compiler.FindResult.Found, "This shouldn't have happened...");

                //Method calls are finally validated, set the mangled method name which we will actually call
                m = m.MakeConcreteDefinition(CurrentType);
                pNode.SetDefinition(m);
            }

            base.VisitMethodCallSyntax(pNode);
        }
Ejemplo n.º 7
0
 private bool IsCalledMethod(MethodSyntax pMethod, MethodCallSyntax pCall)
 {
     if (pMethod.Name != pCall.Value)
     {
         return(false);
     }
     if (pMethod.Parameters.Count != pCall.Arguments.Count)
     {
         return(false);
     }
     for (int i = 0; i < pMethod.Parameters.Count; i++)
     {
         if (!pMethod.Parameters[i].Type.IsAssignableFrom(pCall.Arguments[i].Type))
         {
             return(false);
         }
     }
     return(true);
 }
Ejemplo n.º 8
0
        public MethodSyntax MatchMethod(MethodCallSyntax pCallSite, IEnumerable <MethodSyntax> pMethods)
        {
            var arguments = Utils.SyntaxHelper.SelectNodeTypes(pCallSite.Arguments);

            foreach (var m in pMethods)
            {
                var parameters = Utils.SyntaxHelper.SelectNodeTypes(m.Parameters);
                if (arguments.Length == parameters.Length)
                {
                    bool found = true;
                    for (int i = 0; i < arguments.Length && found; i++)
                    {
                        found = arguments[i].IsAssignableFrom(parameters[i]);
                    }

                    if (found)
                    {
                        return(m);
                    }
                }
            }

            return(null);
        }
Ejemplo n.º 9
0
        protected override void VisitMethodCallSyntax(MethodCallSyntax pNode)
        {
            base.VisitMethodCallSyntax(pNode);

            SmallType[] types = new SmallType[pNode.Arguments.Count];
            for (int i = 0; i < types.Length; i++)
            {
                types[i] = pNode.Arguments[i].Type;
                if (types[i] == SmallTypeCache.NoValue)
                {
                    CompilerErrors.ExpressionNoValue(pNode.Arguments[i].Span);
                }
            }

            if (SyntaxHelper.HasUndefinedCastAsArg(pNode))
            {
                IList <MethodDefinition> matches = _unit.GetAllMatches(Namespace, pNode.Value, pNode.Arguments.Count);
                if (matches.Count > 1)
                {
                    //If multiple matches are found the implicit cast could map to either method, so we can't tell
                    CompilerErrors.InferImplicitCast(pNode.Span);
                    return;
                }
                else if (matches.Count == 1)
                {
                    //Check if we can determine implicit cast type yet
                    for (int j = 0; j < Math.Min(matches[0].ArgumentTypes.Count, pNode.Arguments.Count); j++)
                    {
                        if (SyntaxHelper.IsUndefinedCast(pNode.Arguments[j]))
                        {
                            TrySetImplicitCastType(pNode.Arguments[j], matches[0].ArgumentTypes[j]);
                            types[j] = pNode.Arguments[j].Type;
                        }
                    }
                }
            }



            //Check to ensure this method exists
            var result = SyntaxHelper.FindMethodOnType(out MethodDefinition m, _unit, Namespace, pNode.Value, CurrentType, types);

            switch (result)
            {
            case Compiler.FindResult.NotFound:
                CompilerErrors.MethodNotFound(m, Struct, pNode.Value, pNode.Arguments, pNode.Span);
                return;

            case Compiler.FindResult.IncorrectScope:
                CompilerErrors.MethodNotInScope(m, Struct, pNode.Value, pNode.Arguments, pNode.Span);
                return;
            }

            for (int i = 0; i < m.ArgumentTypes.Count; i++)
            {
                ForceCastLiteral(m.ArgumentTypes[i], pNode.Arguments[i]);
            }

            //Poly our method definition to match any generic types
            m = m.MakeConcreteDefinition(CurrentType);
            pNode.SetType(m.ReturnType);
        }
Ejemplo n.º 10
0
        private bool TryPolyMethod(MethodSyntax pMethod, ref MethodCallSyntax pCallSite)
        {
            System.Diagnostics.Debug.Assert(pMethod.Parameters.Count == pCallSite.Arguments.Count);

            //Get name of the new method
            StringBuilder name = new StringBuilder(pMethod.Name + "!!!");

            for (int i = 0; i < pMethod.Parameters.Count; i++)
            {
                if (pMethod.Parameters[i].Type.IsTrait)
                {
                    name.Append(pCallSite.Arguments[i].Type.Name + "_");
                }
            }
            name = name.Remove(name.Length - 1, 1);

            //Ensure we haven't polymorphed this method before
            if (!_polydMethods.ContainsKey(name.ToString()))
            {
                List <TypedIdentifierSyntax> parameters = new List <TypedIdentifierSyntax>(pMethod.Parameters.Count);
                for (int i = 0; i < pMethod.Parameters.Count; i++)
                {
                    TypedIdentifierSyntax parm;
                    if (pMethod.Parameters[i].Type.IsTrait)
                    {
                        //Ensure the argument implements the proper trait... we haven't done type checking yet
                        if (!pCallSite.Arguments[i].Type.IsAssignableFrom(pMethod.Parameters[i].Type))
                        {
                            return(false);
                        }

                        parm = SyntaxFactory.TypedIdentifier(SyntaxFactory.Type(pCallSite.Arguments[i].Type.Name), pMethod.Parameters[i].Value);
                    }
                    else
                    {
                        parm = (TypedIdentifierSyntax)Visit(pMethod.Parameters[i]);
                    }
                    parameters.Add(parm);
                }

                var method = SyntaxFactory.Method(pMethod.Scope, name.ToString(), pMethod.ReturnValues, parameters, (BlockSyntax)Visit(pMethod.Body)).FromNode(pMethod);
                var tiv    = new Typing.TypeInferenceVisitor(_unit);
                tiv.Visit(method);
                _unit.AddMethod(null, method);

                if (!_polydMethods.ContainsKey(name.ToString()))
                {
                    _polydMethods.Add(name.ToString(), new List <MethodSyntax>());
                }
                _polydMethods[name.ToString()].Add(method);
            }

            //Have the call site point to the new method
            List <SyntaxNode> arguments = new List <SyntaxNode>(pCallSite.Arguments.Count);

            foreach (var a in pCallSite.Arguments)
            {
                arguments.Add(Visit(a));
            }

            pCallSite = SyntaxFactory.MethodCall(name.ToString(), arguments);

            return(true);
        }
Ejemplo n.º 11
0
 public MethodSyntax MatchMethod(MethodCallSyntax pCall, IEnumerable <MethodSyntax> pCandidates)
 {
     return(_methods.MatchMethod(pCall, pCandidates));
 }