Example #1
0
        public Type EmitStruct(SmallType pDefinition)
        {
            Type t  = null;
            var  ta = TypeAttributes.Class | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.SequentialLayout;

            if (pDefinition.Exported)
            {
                ta |= TypeAttributes.Public;
            }

            var tb = _builder.DefineType(pDefinition.Name, ta, typeof(ValueType));

            GenericTypeParameterBuilder[] typeParms = null;
            if (pDefinition.IsGenericDefinition)
            {
                typeParms = tb.DefineGenericParameters(pDefinition.GenericTypeParameters.Select((pSt) => pSt.Name).ToArray()); //eww
            }

            if (pDefinition.Exported)
            {
                var c  = typeof(TypePrefixAttribute).GetConstructor(new Type[] { typeof(string) });
                var cb = new CustomAttributeBuilder(c, new object[] { pDefinition.Name });
                tb.SetCustomAttribute(cb);
            }

            foreach (var f in pDefinition.GetFields())
            {
                var found = false;
                if (typeParms != null)
                {
                    foreach (var tp in typeParms)
                    {
                        foreach (var a in f.Type.GenericTypeParameters)
                        {
                            if (tp.Name == a.Name)
                            {
                                Type tt = tp;
                                if (f.Type.IsArray)
                                {
                                    tt = tt.MakeArrayType();
                                }
                                f.Info = tb.DefineField(f.Name, tt, FieldAttributes.Public);
                                found  = true;
                                break;
                            }
                        }
                    }
                }

                if (!found)
                {
                    f.Info = tb.DefineField(f.Name, f.Type.ToSystemType(), FieldAttributes.Public);
                }
            }

            if (pDefinition.HasInitializer)
            {
                var mb = tb.DefineMethod("Initialize", MethodAttributes.HideBySig | MethodAttributes.Public, null, null);
                pDefinition.Initializer.SetBuilder(mb);
            }

            //t = tb.CreateType();

            pDefinition.SetSystemType(tb);
            return(t);
        }
        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);
                            }
                        }
                    }
                }
            }
        }