コード例 #1
0
        private void GenerateClassMethods(ITypeBuilder type, IReadOnlyList <MethodSyntaxNode> methods, CodeGenerationStore store,
                                          Dictionary <IMethodBuilder, MethodSyntaxNode> methodsDictionary, ref IMethodInfo?entryPoint)
        {
            var definedMethods = new List <IMethodInfo>();

            store.Methods.Add(type, definedMethods);

            foreach (var method in methods)
            {
                var methodAttributes = MethodAttributes.Public;
                if (method.IsStatic)
                {
                    methodAttributes |= MethodAttributes.Static;
                }

                var parameters = method.Parameters.Select(x =>
                {
                    var tpe = store.TypeDefLookup(x.Type);
                    if (x.IsRef)
                    {
                        throw new RefTypeException("Ref types are not supported");
                    }

                    typeChecker !.AssertTypeIsNotVoid(tpe);
                    return(tpe);
                }).ToArray();

                var arrType = typeof(int[]);

                var returnType = store.TypeDefLookup(method.ReturnType);

                var definedMethod = type.DefineMethod(method.Name, methodAttributes, returnType, parameters, method.IsEntryPoint);

                if (method.IsEntryPoint)
                {
                    if (entryPoint != null)
                    {
                        throw new EntryPointException("Can only have 1 entry point");
                    }
                    entryPoint = definedMethod;
                }

                definedMethods.Add(definedMethod);

                store.MethodParameters.Add(definedMethod, parameters);
                methodsDictionary.Add(definedMethod, method);

                int offset = 0;
                //if (!method.IsStatic)
                //{
                //    offset = 1;
                //}

                for (int i = 0; i < method.Parameters.Count; i++)
                {
                    definedMethod.DefineParameter(i + 1 + offset, ParameterAttributes.None, method.Parameters[i].Name);
                }
            }
        }
コード例 #2
0
ファイル: NewCodeGenerator.cs プロジェクト: ThadHouse/COMP430
        // Generate all of our delegates. Delegates are easy, since the code generated for them is fixed, and all implemented
        // by the runtime.
        private void GenerateDelegates(GeneratedData toGenerate, CodeGenerationStore store)
        {
            foreach (var delegateToGenerate in toGenerate.Delegates)
            {
                var type       = delegateToGenerate.Key;
                var syntaxNode = delegateToGenerate.Value;

                store.Fields.Add(type, Array.Empty <IFieldInfo>());

                // Generate our constructor
                var constructor = type.DefineConstructor(MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, delegateConstructorTypes !);
                constructor.SetImplementationFlags(MethodImplAttributes.Runtime);

                store.Constructors.Add(type, new IConstructorInfo[] { constructor });

                store.ConstructorParameters.Add(constructor, delegateConstructorTypes !);

                var parameterTypes = new IType[syntaxNode.Parameters.Count];

                for (int i = 0; i < parameterTypes.Length; i++)
                {
                    var paramType = store.TypeDefLookup(syntaxNode.Parameters[i].Type);
                    if (syntaxNode.Parameters[i].IsRef)
                    {
                        throw new RefTypeException("Ref types are not supported");
                    }
                    typeChecker !.AssertTypeIsNotVoid(paramType);
                    parameterTypes[i] = paramType;
                }

                var returnType = store.TypeDefLookup(syntaxNode.ReturnType);

                // Generate the invoke method
                var method = type.DefineMethod("Invoke", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.NewSlot, returnType, parameterTypes, false);
                method.SetImplementationFlags(MethodImplAttributes.Runtime);

                for (int i = 0; i < parameterTypes.Length; i++)
                {
                    method.DefineParameter(i + 1, ParameterAttributes.None, syntaxNode.Parameters[i].Name);
                }

                store.Methods.Add(type, new IMethodInfo[] { method });

                store.MethodParameters.Add(method, parameterTypes);

                store.Delegates.Add((method.ReturnType, parameterTypes, type, constructor));
            }
        }
コード例 #3
0
        private IReadOnlyList <StatementSyntaxNode> GenerateClassFields(ITypeBuilder type, IReadOnlyList <FieldSyntaxNode> fields, CodeGenerationStore store,
                                                                        ISyntaxNode syntaxNode)
        {
            var definedFields   = new List <IFieldInfo>();
            var initExpressions = new List <StatementSyntaxNode>();

            store.Fields.Add(type, definedFields);
            foreach (var field in fields)
            {
                var fieldType = store.TypeDefLookup(field.Type);

                typeChecker !.AssertTypeIsNotVoid(fieldType);

                var definedField = type.DefineField(field.Name, fieldType, FieldAttributes.Public);
                definedFields.Add(definedField);
                if (field.Expression != null)
                {
                    initExpressions.Add(new ExpressionEqualsExpressionSyntaxNode(field, new VariableSyntaxNode(field, field.Name), field.Expression));
                }
            }

            initExpressions.Add(new BaseClassConstructorSyntax(syntaxNode));

            return(initExpressions);
        }
コード例 #4
0
        private IReadOnlyList <ConstructorSyntaxNode> GenerateClassConstructors(ITypeBuilder type, IReadOnlyList <ConstructorSyntaxNode> constructors, CodeGenerationStore store,
                                                                                IReadOnlyList <StatementSyntaxNode> fieldInitializers,
                                                                                Dictionary <IConstructorBuilder, ConstructorSyntaxNode> constructorsDictionary, ISyntaxNode parent)
        {
            var initialConstructors = new List <ConstructorSyntaxNode>(constructors);
            var mutatedConstructors = new List <ConstructorSyntaxNode>();

            var definedConstructors = new List <IConstructorInfo>();

            store.Constructors.Add(type, definedConstructors);

            if (constructors.Count == 0)
            {
                var statementList = new List <StatementSyntaxNode>();
                initialConstructors.Add(new ConstructorSyntaxNode(parent, Array.Empty <ParameterDefinitionSyntaxNode>(), statementList));
            }

            foreach (var constructor in initialConstructors)
            {
                var newStatements = new List <StatementSyntaxNode>(fieldInitializers);
                foreach (var toAdd in constructor.Statements)
                {
                    newStatements.Add(toAdd);
                }

                var mutatedConstructor = constructor.MutateStatements(newStatements);
                mutatedConstructors.Add(mutatedConstructor);

                var methodAttributes = MethodAttributes.Public;

                var parameters = mutatedConstructor.Parameters.Select(x =>
                {
                    var tpe = store.TypeDefLookup(x.Type);
                    if (x.IsRef)
                    {
                        throw new RefTypeException("Ref types are not supported");
                    }
                    typeChecker !.AssertTypeIsNotVoid(tpe);
                    return(tpe);
                }).ToArray();

                var definedConstructor = type.DefineConstructor(methodAttributes, parameters);

                definedConstructors.Add(definedConstructor);

                store.ConstructorParameters.Add(definedConstructor, parameters);
                constructorsDictionary.Add(definedConstructor, mutatedConstructor);

                int offset = 0;

                for (int i = 0; i < mutatedConstructor.Parameters.Count; i++)
                {
                    definedConstructor.DefineParameter(i + 1 + offset, ParameterAttributes.None, mutatedConstructor.Parameters[i].Name);
                }
            }
            return(mutatedConstructors);
        }