Beispiel #1
0
        public override AstNode Visit(DelegateDefinition node)
        {
            // Use the base class for delegates.
            Structure building = node.GetStructure();
            building.SetBase(currentModule.GetDelegateClass());

            try
            {
                building.FixInheritance();
            }
            catch(ModuleException error)
            {
                Error(node, error.Message);
            }

            return node;
        }
        public override AstNode Visit(DelegateDefinition node)
        {
            // Check the security.
            bool isUnsafe = (node.GetFlags() & MemberFlags.SecurityMask) == MemberFlags.Unsafe;
            if(isUnsafe)
                PushUnsafe();

            // Get the delegate building.
            Structure building = node.GetStructure();

            // Use the generic prototype.
            // Use the generic scope.
            PseudoScope genScope = node.GetGenericScope();
            if(genScope != null)
                PushScope(genScope);

            // Visit the argument list.
            VisitList(node.GetArguments());

            // Visit the return type.
            Expression returnTypeExpr = node.GetReturnType();
            returnTypeExpr.Accept(this);

            IChelaType returnType = returnTypeExpr.GetNodeType();
            returnType = ExtractActualType(returnTypeExpr, returnType);

            // Use references for class/interface.
            if(returnType.IsPassedByReference())
                returnType = ReferenceType.Create(returnType);

            // Create the invoke function type.
            List<IChelaType> arguments = new List<IChelaType> ();

            // Add the argument types.
            AstNode argNode = node.GetArguments();
            while(argNode != null)
            {
                arguments.Add(argNode.GetNodeType());
                argNode = argNode.GetNext();
            }

            // Create the function type.
            FunctionType functionType = FunctionType.Create(returnType, arguments);

            // Check the type security.
            if(functionType.IsUnsafe())
                UnsafeError(node, "safe delegate with unsafe type.");

            // Create the invoke type.
            List<IChelaType> invokeArguments = new List<IChelaType> ();
            invokeArguments.Add(ReferenceType.Create(building));
            for(int i = 0; i < arguments.Count; ++i)
                invokeArguments.Add(arguments[i]);
            FunctionType invokeType = FunctionType.Create(returnType, invokeArguments);

            // Create the constructor type.
            List<IChelaType> ctorArguments = new List<IChelaType> ();
            ctorArguments.Add(ReferenceType.Create(building));
            ctorArguments.Add(ReferenceType.Create(currentModule.TypeMap(ChelaType.GetObjectType())));
            ctorArguments.Add(ReferenceType.Create(functionType));
            FunctionType ctorType = FunctionType.Create(ChelaType.GetVoidType(), ctorArguments);

            // Create the constructor method.
            Method ctorMethod = new Method("<ctor>", MemberFlags.Public | MemberFlags.Runtime | MemberFlags.Constructor, building);
            ctorMethod.SetFunctionType(ctorType);
            building.AddFunction("<ctor>", ctorMethod);

            // Create the invoke function.
            Method invokeMethod = new Method("Invoke", MemberFlags.Public | MemberFlags.Runtime, building);
            invokeMethod.SetFunctionType(invokeType);
            building.AddFunction("Invoke", invokeMethod);

            // Restore the scope.
            if(genScope != null)
                PopScope();

            // Restore the security level.
            if(isUnsafe)
                PushUnsafe();

            return node;
        }