public SyntaxTokenCollection Format(MethodSyntax syntax)
        {
            SyntaxTokenCollection tokens = new SyntaxTokenCollection();

            SyntaxToken inheritanceModifier = FormatInheritance(syntax);

            tokens.AddRange(FormatVisibility(syntax));
            if (inheritanceModifier != null)
            {
                tokens.Add(Constants.Space);
                tokens.Add(inheritanceModifier);
            }
            tokens.Add(Constants.Space);
            tokens.AddRange(FormatReturnType(syntax));
            tokens.Add(Constants.Space);
            tokens.Add(new SyntaxToken(syntax.GetIdentifier(), SyntaxTokens.Text));
            if (syntax.Method.IsGeneric)
            {
                tokens.Add(Constants.GenericStart);
                List <GenericTypeRef> genericTypes = syntax.GetGenericParameters();
                for (int i = 0; i < genericTypes.Count; i++)
                {
                    if (i != 0)
                    {
                        tokens.Add(new SyntaxToken(", ", SyntaxTokens.Text));
                    }
                    tokens.Add(FormatTypeName(genericTypes[i]));
                }
                tokens.Add(Constants.GenericEnd);
            }
            tokens.AddRange(FormatParameters(syntax));

            return(tokens);
        }
 protected override void VisitMethodSyntax(MethodSyntax pNode)
 {
     _locals.AddScope();
     _methodReturns = SyntaxHelper.SelectNodeTypes(pNode.ReturnValues);
     base.VisitMethodSyntax(pNode);
     _locals.RemoveScope();
 }
Exemple #3
0
 public override SyntaxNode Visit(MethodSyntax pNode)
 {
     using (new MetadataCache.LocalScope())
     {
         return(base.Visit(pNode));
     }
 }
        public void MethodSigTestOne()
        {
            var methodSig = "public static void GetNumber(string name) { /* Comment */ }";

            MethodSyntax methodSyntax = new MethodSyntax();

            methodSyntax.Modifiers.Add("public");
            methodSyntax.Modifiers.Add("static");
            methodSyntax.ReturnType = new TypeSyntax("void");
            methodSyntax.Identifier = "GetNumber";
            methodSyntax.MethodParameters.Add(new ParameterSyntax("string", "name"));
            methodSyntax.CodeInsideMethod = "/* Comment */";

            var method = Apex.MethodDeclaration.Parse(methodSig);

            Assert.AreEqual(2, method.Modifiers.Count);
            Assert.AreEqual("public", method.Modifiers[0]);
            Assert.AreEqual("static", method.Modifiers[1]);
            Assert.AreEqual("void", method.ReturnType.Identifier);
            Assert.AreEqual("GetNumber", method.Identifier);

            Assert.AreEqual(1, method.MethodParameters.Count);
            Assert.AreEqual("string", method.MethodParameters[0].Type.Identifier);
            Assert.AreEqual("name", method.MethodParameters[0].Identifier);
            Assert.AreEqual("/* Comment */", method.CodeInsideMethod);
        }
        protected override SyntaxNode VisitMethodSyntax(MethodSyntax pNode)
        {
            if (_currentType != null)
            {
                //This means we are current in a generic struct and we should use the types defined on the generic struct
                //Poly any parameters
                List <TypedIdentifierSyntax> parameters = new List <TypedIdentifierSyntax>(pNode.Parameters.Count);
                foreach (var p in pNode.Parameters)
                {
                    var type = PolyType(p.TypeNode);
                    var iden = p.Value;

                    parameters.Add(SyntaxFactory.TypedIdentifier(type, iden));
                }

                //Poly return types
                List <TypeSyntax> returnValues = new List <TypeSyntax>(pNode.ReturnValues.Count);
                foreach (var r in pNode.ReturnValues)
                {
                    returnValues.Add(PolyType(r));
                }

                return(SyntaxFactory.Method(pNode.Scope, pNode.Name, returnValues, parameters, (BlockSyntax)Visit(pNode.Body)));
            }
            else
            {
                //Otherwise we are just in a normal generic method
                //We need to discover all the generic types then poly them
            }

            return(base.VisitMethodSyntax(pNode));
        }
        public List <SyntaxToken> FormatParameters(MethodSyntax syntax)
        {
            List <SyntaxToken>      tokens     = new List <SyntaxToken>();
            List <ParameterDetails> parameters = syntax.GetParameters();

            tokens.Add(new SyntaxToken("(", SyntaxTokens.Text));
            for (int i = 0; i < parameters.Count; i++)
            {
                if (i != 0)
                {
                    tokens.Add(new SyntaxToken($",\n\t", SyntaxTokens.Text));
                }
                else
                {
                    tokens.Add(new SyntaxToken("\n\t", SyntaxTokens.Text));
                }
                tokens.AddRange(FormatParameterModifiers(parameters[i]));
                tokens.AddRange(FormatTypeDetails(parameters[i].TypeDetails));
                tokens.Add(Constants.Space);
                tokens.Add(new SyntaxToken(parameters[i].Name, SyntaxTokens.Text));
            }
            if (parameters.Count > 0)
            {
                tokens.Add(new SyntaxToken("\n\t", SyntaxTokens.Text));
            }
            tokens.Add(new SyntaxToken(")", SyntaxTokens.Text));

            return(tokens);
        }
Exemple #7
0
 public override void Visit(MethodSyntax pNode)
 {
     if (!pNode.External && pNode.ReturnValues.Count > 0 && !ValidateReturnPaths(pNode))
     {
         Compiler.ReportError(CompilerErrorType.PathNoReturnValue, pNode);
     }
     base.Visit(pNode);
 }
Exemple #8
0
        public void ExtensionMethodsTestMethodSyntax()
        {
            List <Product> productsList = MethodSyntax.GetProductsByName("Grip").NullCategoryMS();

            foreach (Product product in productsList)
            {
                Assert.IsNull(product.ProductSubcategory);
            }
        }
        private bool AddMethodToCache(SmallType pType, MethodSyntax pMethod, out MethodDefinition pDefinition)
        {
            //Check for duplicate method definitions
            Compiler.FindResult found;
            if (pMethod.SyntaxType == SyntaxType.Method)
            {
                found = _unit.MethodExists(pType, pMethod);
            }
            else if (pMethod.SyntaxType == SyntaxType.CastDefinition)
            {
                found = _unit.CastExists(pType, pMethod.Type, out MethodDefinition pDef);
            }
            else
            {
                throw new InvalidOperationException("Unknown method type " + pMethod.SyntaxType.ToString());
            }

            if (found != Compiler.FindResult.NotFound)
            {
                if (pMethod.SyntaxType == SyntaxType.Method)
                {
                    CompilerErrors.MethodDuplicate(pMethod, pMethod.Span);
                }
                else if (pMethod.SyntaxType == SyntaxType.CastDefinition)
                {
                    CompilerErrors.CastDuplicate(pMethod.Parameters[0].Type, pMethod.Type, pMethod.Span);
                }
                pDefinition = default;
                return(false);
            }
            else
            {
                //Create the tuple type if we are returning more than one value from a method
                //This will cache it in our SmallTypeCache so it can be found later
                if (pMethod.ReturnValues.Count > 1)
                {
                    SmallTypeCache.GetOrCreateTuple(SyntaxHelper.SelectNodeTypes(pMethod.ReturnValues));
                }

                //Set method and return types
                foreach (var p in pMethod.Parameters)
                {
                    _unit.FromString(p.TypeNode, out SmallType t);
                    p.TypeNode.SetType(t);
                }
                foreach (var r in pMethod.ReturnValues)
                {
                    _unit.FromString(r, out SmallType t);
                    r.SetType(t);
                }

                //Add method
                pDefinition = _unit.AddMethod(pType, pMethod);
                return(true);
            }
        }
Exemple #10
0
 protected override void VisitMethodSyntax(MethodSyntax pNode)
 {
     for (int i = 0; i < pNode.ReturnValues.Count; i++)
     {
         if (pNode.ReturnValues[i].Type == SmallTypeCache.Undefined)
         {
             CompilerErrors.UndeclaredType(pNode.ReturnValues[i].Value, pNode.ReturnValues[i].Span);
         }
     }
     _methodReturns = SyntaxHelper.SelectNodeTypes(pNode.ReturnValues);
     base.VisitMethodSyntax(pNode);
 }
Exemple #11
0
 protected virtual void VisitMethodSyntax(MethodSyntax pNode)
 {
     foreach (var p in pNode.Parameters)
     {
         Visit(p);
     }
     foreach (var r in pNode.ReturnValues)
     {
         Visit(r);
     }
     Visit(pNode.Body);
 }
Exemple #12
0
        public Compiler.FindResult MethodExists(SmallType pType, MethodSyntax pNode)
        {
            var name = GetMethodName(pType, pNode.Name);

            if (_methods.ContainsKey(name))
            {
                SmallType[] types = Utils.SyntaxHelper.SelectNodeTypes(pNode.Parameters);
                return(FindMethod(out MethodDefinition m, false, pType, name, types));
            }

            return(Compiler.FindResult.NotFound);
        }
Exemple #13
0
        public void TestRetriveAllOrderByPriceAscendingMethodSyntax()
        {
            MethodSyntax          qa    = new MethodSyntax();
            IEnumerable <Product> lista = qa.RetriveAllOrderByPriceAscending();

            int[] produse = { 3, 1, 2 };
            int   i       = 0;

            foreach (Product product in lista)
            {
                Assert.AreEqual(produse[i], product.Id, "Nu sunt ordonate");
                i = i + 1;
            }
        }
Exemple #14
0
        public MethodDefinition AddMethod(SmallType pType, string pNamespace, MethodSyntax pNode)
        {
            var name = GetMethodName(pType, pNode.Name);

            if (!_methods.ContainsKey(name))
            {
                _methods.Add(name, new List <MethodDefinition>());
                _counter.Add(name, 0);
            }
            _counter[name]++;
            var md = GetDefinition(pNode, _counter[name], pNamespace, name);

            _methods[name].Add(md);
            return(md);
        }
Exemple #15
0
        private static MethodDefinition GetDefinition(MethodSyntax pMethod, int pCounter, string pNamespace, string pName)
        {
            List <SmallType> arguments = new List <SmallType>(pMethod.Parameters.Count);

            for (int i = 0; i < pMethod.Parameters.Count; i++)
            {
                var parmType = pMethod.Parameters[i].Type;
                arguments.Add(parmType);
            }

            SmallType ret         = pMethod.Type;
            string    mangledName = pNamespace + "__" + pName + "_" + pCounter;

            return(new MethodDefinition(pMethod.Scope, pMethod.Name, mangledName, pMethod.External, arguments, ret));
        }
 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);
 }
Exemple #17
0
        protected virtual SyntaxNode VisitMethodSyntax(MethodSyntax pNode)
        {
            List <TypedIdentifierSyntax> parameters = new List <TypedIdentifierSyntax>(pNode.Parameters.Count);

            foreach (var p in pNode.Parameters)
            {
                parameters.Add((TypedIdentifierSyntax)Visit(p));
            }

            List <TypeSyntax> returns = new List <TypeSyntax>(pNode.ReturnValues.Count);

            foreach (var r in pNode.ReturnValues)
            {
                returns.Add((TypeSyntax)Visit(r));
            }

            MethodSyntax m = SyntaxFactory.Method(pNode.Scope, pNode.Name, returns, parameters, (BlockSyntax)Visit(pNode.Body), pNode.External);

            m.Annotation = pNode.Annotation;
            return(m);
        }
Exemple #18
0
        public void MethodSyntaxTest()
        {
            List <Product> productsList = null;

            Assert.IsNull(productsList);
            productsList = MethodSyntax.GetProductsByName("Blade");
            Assert.IsNotNull(productsList);
            Assert.AreEqual("Blade", productsList[0].Name);
            productsList = MethodSyntax.GetProductsWithNRecentReviews(3);
            Assert.AreEqual(937, productsList[0].ProductID);
            Assert.AreEqual(798, productsList[1].ProductID);

            List <String> namesList = MethodSyntax.GetProductNamesByVendorName("Beaumont Bikes");

            Assert.AreEqual("Chainring Bolts", namesList[0]);
            Assert.AreEqual("Chainring Nut", namesList[1]);
            Assert.AreEqual("Chainring", namesList[2]);

            namesList = MethodSyntax.GetProductVendorByProductName("Chainring");
            Assert.AreEqual("Training Systems", namesList[0]);
            Assert.AreEqual("Beaumont Bikes", namesList[1]);
            Assert.AreEqual("Bike Satellite Inc.", namesList[2]);

            productsList = MethodSyntax.GetNRecentlyReviewedProducts(3);
            Assert.AreEqual(937, productsList[0].ProductID);
            Assert.AreEqual(798, productsList[1].ProductID);
            Assert.AreEqual(709, productsList[2].ProductID);

            productsList = MethodSyntax.GetNProductsFromCategory("Bikes", 2);
            Assert.AreEqual(775, productsList[0].ProductID);
            Assert.AreEqual(776, productsList[1].ProductID);

            int sum = MethodSyntax.GetTotalStandardCostByCategory(MethodSyntax.GetProductCategoryFromName("Bikes"));

            Assert.AreEqual(92092, sum);
        }
Exemple #19
0
        /// <summary>
        /// Formats the indexer based on the language specification as a
        /// collection of syntax tokens.
        /// </summary>
        /// <param name="syntax">The syntax class that describes the indexer.</param>
        /// <returns>The collection of tokens describing the indexer in the language</returns>
        public SyntaxTokenCollection Format(IndexorSyntax syntax)
        {
            SyntaxTokenCollection tokens = new SyntaxTokenCollection();

            tokens.AddRange(FormatVisibility(syntax));
            tokens.Add(Constants.Space);
            tokens.AddRange(FormatType(syntax));
            tokens.Add(Constants.Space);
            tokens.Add(FormatIdentifier(syntax));

            // Provide the properties to access the indexer, these are
            // obtained from the get method.
            MethodSyntax getMethod = new MethodSyntax(
                _syntax.GetMethod != null ? _syntax.GetMethod : _syntax.SetMethod
                );

            tokens.Add(new SyntaxToken("[", SyntaxTokens.Text));
            List <ParameterDetails> parameters = getMethod.GetParameters();

            // dont output the last parameter if we are not using the get method as it is the return value...
            for (int i = 0; i < parameters.Count; i++)
            {
                ParameterDetails current = parameters[i];

                tokens.AddRange(FormatTypeDetails(current.TypeDetails));
                tokens.Add(Constants.Space);
                tokens.Add(new SyntaxToken(current.Name, SyntaxTokens.Text));

                if (i < parameters.Count - 1)
                {
                    tokens.Add(new SyntaxToken(", ", SyntaxTokens.Text));
                }
            }
            tokens.Add(new SyntaxToken("]", SyntaxTokens.Text));

            tokens.Add(new SyntaxToken(" {", SyntaxTokens.Text));
            if (_syntax.GetMethod != null)
            {
                tokens.Add(new SyntaxToken("\n\t", SyntaxTokens.Text));
                if (syntax.GetVisibility() != syntax.GetGetterVisibility())
                {
                    tokens.AddRange(FormatGetVisibility(syntax));
                    tokens.Add(Constants.Space);
                }
                tokens.Add(Constants.KeywordGet);
                tokens.Add(new SyntaxToken(";", SyntaxTokens.Text));
            }
            if (this._syntax.SetMethod != null)
            {
                tokens.Add(new SyntaxToken("\n\t", SyntaxTokens.Text));
                if (syntax.GetVisibility() != syntax.GetSetterVisibility())
                {
                    tokens.AddRange(FormatSetVisibility(syntax));
                    tokens.Add(Constants.Space);
                }
                tokens.Add(Constants.KeywordSet);
                tokens.Add(new SyntaxToken(";", SyntaxTokens.Text));
            }
            tokens.Add(new SyntaxToken("\n\t}", SyntaxTokens.Text));
            return(tokens);
        }
Exemple #20
0
        public static void ValidateExternalAnnotation(Annotation pAnnotation, MethodSyntax pMethod)
        {
            //Check basic format
            if (string.IsNullOrEmpty(pAnnotation.Value))
            {
                CompilerErrors.NoExternalAnnotation(pMethod.Span);
                return;
            }

            var parts = pAnnotation.Value.Split(',');

            if (parts.Length != 3)
            {
                CompilerErrors.ExternalAnnotationFormat(pAnnotation.Span);
                return;
            }

            try
            {
                //Try to retrieve assembly
                Assembly assembly = TryResolveAssembly(parts[0]);
                if (assembly == null)
                {
                    throw new System.IO.FileNotFoundException($"Unable to locate assembly {parts[0]}");
                }

                //Try to retrieve type
                Type type = assembly.GetType(parts[1]);
                if (type == null)
                {
                    throw new System.IO.FileNotFoundException($"Unable to type {parts[1]} within {parts[0]}");
                }

                //Convert SmallTypes to System.Type
                Type[] types = new Type[pMethod.Parameters.Count];
                for (int i = 0; i < pMethod.Parameters.Count; i++)
                {
                    var t = pMethod.Parameters[i].Type;
                    if (t == cache.Double)
                    {
                        types[i] = typeof(double);
                    }
                    else if (t == cache.Float)
                    {
                        types[i] = typeof(float);
                    }
                    else if (t == cache.Long)
                    {
                        types[i] = typeof(long);
                    }
                    else if (t == cache.Int)
                    {
                        types[i] = typeof(int);
                    }
                    else if (t == cache.Short)
                    {
                        types[i] = typeof(short);
                    }
                    else if (t == cache.Boolean)
                    {
                        types[i] = typeof(bool);
                    }
                    else if (t == cache.String)
                    {
                        types[i] = typeof(string);
                    }
                    else if (t == cache.Char)
                    {
                        types[i] = typeof(char);
                    }
                    else if (t.IsEnum)
                    {
                        types[i] = typeof(Enum);
                    }
                    else
                    {
                        throw new InvalidCastException("Unknown type " + t.ToString());
                    }
                }

                if (!TryResolveMethod(type, parts[2], types, out MethodInfo method))
                {
                    CompilerErrors.UnknownExternalMethod(parts[2], pAnnotation.Span);
                }
                else
                {
                    //Method must be a static and double check argument types. Primitive types can be implicitly casted in GetMethod
                    if (!method.IsStatic)
                    {
                        CompilerErrors.StaticExternalMethod(parts[2], pAnnotation.Span);
                    }

                    var parmTypes = method.GetParameters();
                    for (int i = 0; i < parmTypes.Length; i++)
                    {
                        //We will allow use of SmallType Enums to System.Enum
                        //This works because we just emit the integer value
                        if (parmTypes[i].ParameterType != types[i] &&
                            parmTypes[i].ParameterType.IsEnum && types[i] != typeof(Enum))
                        {
                            CompilerErrors.TypeCastError(types[i].ToString(), parmTypes[i].ParameterType.ToString(), pAnnotation.Span);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                CompilerErrors.UnknownExternalError(e.Message, pAnnotation.Span);
            }
        }
 public CSharpMethodFormatter(MethodSyntax syntax)
 {
     _syntax    = syntax;
     _signiture = syntax.Method.Signiture;
 }
Exemple #22
0
        public void TestRetriveInactiveProductsMethodSyntax()
        {
            MethodSyntax qa = new MethodSyntax();

            Assert.AreNotEqual(2, qa.RetriveInactiveProducts(), "Sunt egale");
        }
Exemple #23
0
        public void TestRetriveAllBySartEndDateMethodSyntax()
        {
            MethodSyntax qa = new MethodSyntax();

            Assert.AreEqual(3, qa.RetriveAllByStartEndDate(new DateTime(2011, 1, 1), new DateTime(2030, 1, 1)), "Nu sunt egale");
        }
 public List <SyntaxToken> FormatVisibility(MethodSyntax syntax)
 {
     return(FormatVisibility(syntax.GetVisibility()));
 }
 public SyntaxToken FormatInheritance(MethodSyntax syntax)
 {
     return(FormatInheritance(syntax.GetInheritance()));
 }
 public List <SyntaxToken> FormatReturnType(MethodSyntax syntax)
 {
     return(FormatTypeDetails(syntax.GetReturnType()));
 }
        protected override void VisitMethodSyntax(MethodSyntax pNode)
        {
            if (pNode.External)
            {
                KeyAnnotations.ValidateExternalAnnotation(pNode.Annotation, pNode);
            }

            //Validate that one and only 1 method is annotated with "run"
            //This method must contain no parameters and return no values
            if (pNode.Annotation.Value == KeyAnnotations.RunMethod)
            {
                if (Store.GetValue <string>("RunMethod") != null)
                {
                    CompilerErrors.RunMethodDuplicate(Store.GetValue <string>("RunMethod"), pNode.Name, pNode.Span);
                    return;
                }

                Store.SetValue("RunMethod", pNode.Name);
                if (pNode.Parameters.Count != 0)
                {
                    CompilerErrors.RunMethodParameters(pNode.Span);
                }

                if (pNode.ReturnValues.Count != 0)
                {
                    CompilerErrors.RunMethodReturn(pNode.Span);
                }
            }

            using (var ic = Store.AddValue("InConstructor", pNode.Annotation.Value == KeyAnnotations.Constructor))
            {
                using (var rf = Store.AddValue("ReturnFound", false))
                {
                    using (var rvc = Store.AddValue("ReturnValueCount", pNode.ReturnValues.Count))
                    {
                        _usedFields = new HashSet <string>();
                        base.VisitMethodSyntax(pNode);

                        //Validate that all paths return a value
                        if (pNode.Body != null)
                        {
                            if (pNode.ReturnValues.Count != 0 && !rf.Value)
                            {
                                CompilerErrors.MethodReturnPaths(pNode, pNode.Span);
                            }
                            else if (pNode.ReturnValues.Count == 0 && rf.Value)
                            {
                                CompilerErrors.MethodNoReturn(pNode, pNode.Span);
                            }
                        }
                    }
                }

                if (ic.Value)
                {
                    SmallType s = Struct;
                    if (s != null)
                    {
                        foreach (var f in s.GetFields())
                        {
                            if (!_usedFields.Contains(f.Name))
                            {
                                CompilerErrors.FieldNotInitialized(f.Name, pNode.Span);
                            }
                        }
                    }
                }
            }
        }
Exemple #28
0
        public void TestRetriveActiveProductsMethodSyntax()
        {
            MethodSyntax qa = new MethodSyntax();

            Assert.AreEqual(2, qa.RetriveActiveProducts(), "Nu sunt egale");
        }
Exemple #29
0
        public void TestRetriveAllByNameMethodSyntax()
        {
            MethodSyntax qa = new MethodSyntax();

            Assert.AreEqual(1, qa.RetriveAllByName("masina"), "Nu sunt egale");
        }
        public override void Visit(MethodSyntax pNode)
        {
            //Create any generic type parameters to the function
            Dictionary <string, SmallType> typeArgs = new Dictionary <string, SmallType>();

            foreach (var t in pNode.TypeHints)
            {
                typeArgs.Add(t, SmallType.CreateGenericParameter(t));
            }

            //
            //Create types for method
            //

            //Infer parameter types now that structs have been defined
            foreach (var p in pNode.Parameters)
            {
                var st = SmallType.FromString(p.Namespace, p.Value);
                if (p.TypeParameters.Count > 0)
                {
                    SmallType[] types = new SmallType[p.TypeParameters.Count];
                    for (int i = 0; i < types.Length; i++)
                    {
                        //If the type parameter is one on the method definition, use that type
                        if (typeArgs.ContainsKey(p.TypeParameters[i]))
                        {
                            types[i] = typeArgs[p.TypeParameters[i]];
                        }
                        else
                        {
                            types[i] = SmallType.FromString("", p.TypeParameters[i]);
                        }
                    }

                    if (!p.Type.IsVariant)
                    {
                        st = st.MakeGenericType(types);
                    }
                    else
                    {
                        //vnt types are transformed to the actual type parameter
                        if (p.TypeParameters.Count > 1)
                        {
                            SmallType[] typeParameters = new SmallType[p.TypeParameters.Count];
                            for (int i = 0; i < typeParameters.Length; i++)
                            {
                                typeParameters[i] = SmallType.CreateGenericParameter(p.TypeParameters[i]);
                            }
                            st = SmallType.CreateTupleOf(typeParameters);
                        }
                        else
                        {
                            st = SmallType.CreateGenericParameter(p.TypeParameters[0]);
                        }
                    }
                }
                p.SetType(st);
            }

            foreach (var r in pNode.ReturnValues)
            {
                //If the type parameter is one on the method definition, use that type
                if (typeArgs.ContainsKey(r.Value))
                {
                    r.SetType(SmallType.CreateGenericParameter(r.Value));
                }
                else
                {
                    r.SetType(SmallType.FromString(r.Namespace, r.Value));
                }
            }

            //
            //Create method definition
            //

            //Create parameters
            MethodDefinition.Parameter[] parameters = new MethodDefinition.Parameter[pNode.Parameters.Count];
            for (int i = 0; i < pNode.Parameters.Count; i++)
            {
                parameters[i] = new MethodDefinition.Parameter(pNode.Parameters[i]);
            }

            //Create return types
            SmallType[] returnTypes = new SmallType[pNode.ReturnValues.Count];
            for (int i = 0; i < pNode.ReturnValues.Count; i++)
            {
                returnTypes[i] = pNode.ReturnValues[i].Type;
            }

            var d = MetadataCache.AddMethod(pNode.Name, parameters, returnTypes, typeArgs.Values.ToList());

            if (pNode.Annotations.Count > 0)
            {
                //Process any standard annotations
                //run
                //export
                //external info
                foreach (var a in pNode.Annotations)
                {
                    if (a.Value.Equals("run", StringComparison.OrdinalIgnoreCase))
                    {
                        if (_mainFound)
                        {
                            Compiler.ReportError(CompilerErrorType.DuplicateRun, pNode);
                        }
                        else
                        {
                            d.IsMain = true;
                        }

                        if (pNode.Parameters.Count > 0 || pNode.ReturnValues.Count > 0)
                        {
                            Compiler.ReportError(CompilerErrorType.InvalidRun, pNode);
                        }
                        _mainFound = true;
                    }
                    else if (a.Value.Equals("export", StringComparison.OrdinalIgnoreCase))
                    {
                        d.SetScope(Scope.Public);
                    }
                    else if (pNode.External)
                    {
                        var s = a.Value.Split(';');
                        if (s.Length != 3)
                        {
                            Compiler.ReportError(CompilerErrorType.InvalidExternalAnnotation, pNode);
                        }

                        d.SetExternInfo(s[0], s[1], s[2]);
                    }
                }

                if (d.ExternMethod != null && d.Scope == Scope.Public)
                {
                    Compiler.ReportError(CompilerErrorType.ExportExternal, pNode, pNode.Name);
                }
            }
            pNode.SetDefinition(d);
        }