Example #1
0
        public override AstNode Visit(InterfaceDefinition node)
        {
            // Parse the generic signature.
            GenericSignature genericSign = node.GetGenericSignature();
            GenericPrototype genProto = GenericPrototype.Empty;
            PseudoScope protoScope = null;
            if(genericSign != null)
            {
                // Visit the generic signature.
                genericSign.Accept(this);

                // Connect the generic prototype.
                genProto = genericSign.GetPrototype();

                // Create the placeholders scope.
                protoScope = new PseudoScope(currentScope, genProto);
                node.SetGenericScope(protoScope);
            }

            // Prevent redefinition.
            ScopeMember old = currentContainer.FindType(node.GetName(), genProto);
            if(old != null)
                Error(node, "trying to redefine a class.");

            // Create the structure
            Interface iface = new Interface(node.GetName(), node.GetFlags(), currentContainer);
            iface.SetGenericPrototype(genProto);
            node.SetStructure(iface);
            iface.Position = node.GetPosition();

            // Register type maps.
            string fullName = iface.GetFullName();
            IChelaType alias;
            if(typeMaps.TryGetValue(fullName, out alias))
                currentModule.RegisterTypeMap(alias, ReferenceType.Create(iface));

            // Register some important interfaces.
            if(fullName == "Chela.Lang.NumberConstraint")
                currentModule.RegisterNumberConstraint(iface);
            else if(fullName == "Chela.Lang.IntegerConstraint")
                currentModule.RegisterIntegerConstraint(iface);
            else if(fullName == "Chela.Lang.FloatingPointConstraint")
                currentModule.RegisterFloatingPointConstraint(iface);
            else if(fullName == "Chela.Collections.IEnumerable")
                currentModule.RegisterEnumerableIface(iface);
            else if(fullName == "Chela.Collections.IEnumerator")
                currentModule.RegisterEnumeratorIface(iface);
            else if(fullName.StartsWith("Chela.Collections.Generic.IEnumerable<"))
                currentModule.RegisterEnumerableGIface(iface);
            else if(fullName.StartsWith("Chela.Collections.Generic.IEnumerator<"))
                currentModule.RegisterEnumeratorGIface(iface);

            // Use the prototype scope.
            if(protoScope != null)
                PushScope(protoScope);

            // Add into the current scope.
            if(currentContainer.IsNamespace())
            {
                Namespace space = (Namespace)currentContainer;
                space.AddType(iface);
            }
            else if(currentContainer.IsStructure() || currentContainer.IsInterface() || currentContainer.IsClass())
            {
                Structure parent = (Structure)currentContainer;
                parent.AddType(iface);
            }
            else
            {
                Error(node, "unexpected place for a class.");
            }

            // Push the interface unsafe.
            if(iface.IsUnsafe())
                PushUnsafe();

            // Update the scope.
            PushScope(iface);

            // Visit the building children.
            VisitList(node.GetChildren());

            // Restore the scope.
            PopScope();

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

            // Pop the interface unsafe.
            if(iface.IsUnsafe())
                PopUnsafe();

            return node;
        }