Пример #1
0
        public override AstNode Visit(NewExpression node)
        {
            // Visit the type expression.
            Expression typeExpression = node.GetTypeExpression();
            typeExpression.SetHints(Expression.TypeHint);
            typeExpression.Accept(this);

            // Visit the arguments.
            VisitList(node.GetArguments());

            // Get the type.
            IChelaType objectType = typeExpression.GetNodeType();
            objectType = ExtractActualType(typeExpression, objectType);
            node.SetObjectType(objectType);

            // Cannot create abstract objects.
            if(objectType.IsAbstract())
                Error(node, "cannot create abstract objects.");

            // Cannot create reference objects.
            if(objectType.IsReference())
                Error(node, "cannot create references, only object/structures.");

            // Create the different objects.
            Structure building = null;
            if(objectType.IsPrimitive() || objectType.IsPointer())
            {
                Error(node, "cannot create primitives with new");
            }
            else if(objectType.IsStructure())
            {
                building = (Structure)objectType;
            }
            else if(objectType.IsClass())
            {
                building = (Structure)objectType;
            }
            else if(objectType.IsInterface())
            {
                Error(node, "cannot instance interfaces.");
            }
            else
                Error(node, "cannot create object of type {0} with new.", objectType);

            // Use the implicit instance.
            if(building != null)
            {
                if(building.IsGeneric() && building.IsGenericImplicit())
                    building = building.GetSelfInstance();

                // Set the node type.
                if(building.IsPassedByReference())
                    node.SetNodeType(ReferenceType.Create(building));
                else
                    node.SetNodeType(building);
            }

            // Get the constructor group.
            FunctionGroup constructorGroup = building.GetConstructor();
            if(constructorGroup == null)
                Error(node, "default constructors unimplemented.");

            // Pick the constructor.
            Method constructor = (Method)PickFunction(node, constructorGroup, false, null, node.GetArguments(), false);
            node.SetConstructor(constructor);

            return node;
        }