Exemple #1
0
        // Builds a "class" expression: really could be a class, struct, or module.
        public static void BuildClass(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            Class c = new Class(parentExpression, currentNode.FindToken().Convert());
            parentExpression.ChildExpressions.Add(c);

            int i = 0;

            // Interpret the declaration modifiers (abstract, public, internal, etc).
            InterpretClassModifiers( root, c, currentNode.ChildNodes[i]);

            i++;

            // Determine if it's a class, module, or struct.
            switch(currentNode.ChildNodes[i].Term.ToString())
            {
                case "module":
                    c.IsModule = true;
                    c.IsFinal = true;
                    c.IsPartial = true;
                    break;
                case "struct":
                    c.IsStruct = true;
                    c.IsModule = false;
                    break;
                default:
                    c.IsStruct = false;
                    c.IsModule = false;
                    break;
            }

            i++;

            // Class name
            c.UnqualifiedName = currentNode.ChildNodes[i].FindTokenAndGetText();

            i++;

            // Get the generic type list.
            if (currentNode.ChildNodes[i].ChildNodes.Count > 0)
            {
                var generics = currentNode.ChildNodes[i].ChildNodes[0].ChildNodes[1];
                foreach (string s in IronyParser.InterpretList(generics))
                    c.GenericTypeNames.Add(s);
            }

            i++;

            // Get the base type list.
            if (currentNode.ChildNodes[i].ChildNodes.Count > 0)
            {
                var baseTypes = currentNode.ChildNodes[i].ChildNodes[0].ChildNodes[0];
                foreach (string s in IronyParser.InterpretList(baseTypes))
                    c.BaseTypeNames.Add(s);
            }

            i+=1;

            // Build the child expressions of the class.
            parser.ConsumeParseTree(root, c, currentNode.ChildNodes[i]);
        }
Exemple #2
0
        public void TestClassFullName()
        {
            Namespace n = new Namespace(null, null);
            n.Name = "foo";

            Class c = new Class(null, null);
            c.UnqualifiedName = "bar";
            Console.WriteLine(c.GetQualifiedName());
            Assert.AreEqual("foo", n.Name, "namespace name1");
            Assert.AreEqual("foo", n.GetFullName(), "namespace full name1");
            Assert.AreEqual("bar", c.UnqualifiedName, "class name1");
            Assert.AreEqual("bar", c.GetQualifiedName(), "class full name1");

            c.ParentExpression = n;
            Assert.AreEqual("foo", n.Name, "namespace name2");
            Assert.AreEqual("foo", n.GetFullName(), "namespace full name2");
            Assert.AreEqual("bar", c.UnqualifiedName, "class name2");
            Assert.AreEqual("foo.bar", c.GetQualifiedName(), "class full name2");

            c.ParentExpression = new Expression(null, null);
            Assert.AreEqual("foo", n.Name, "namespace name3");
            Assert.AreEqual("foo", n.GetFullName(), "namespace full name3");
            Assert.AreEqual("bar", c.UnqualifiedName, "class name3");
            Assert.AreEqual("bar", c.GetQualifiedName(), "class full name3");
        }
Exemple #3
0
        public static void Validate(Validator validator, Root root, Class c)
        {
            bool validated = true;

            // As a module, it can't have base types
            if(c.IsModule)
            {
                if(c.BaseTypeNames.Count > 0)
                    root.CompilerErrors.Add(new ModuleInheritanceCompilerError("", c.Token.Line, c.Token.Position));

                foreach (var e in c.ChildExpressions)
                    if (e is Constructor)
                        root.CompilerErrors.Add(new ModuleConstructorCompilerError("", c.Token.Line, c.Token.Position));

                if (c.IsAbstract)
                    root.CompilerErrors.Add(new ModuleModifierCompilerError("", c.Token.Line, c.Token.Position));
            }

            c.Validated = validated;
        }
Exemple #4
0
 /* All classes produced during a test should be
  * valiated with this method. Scenarios to test:
  *
  * Class with body
  * Name
  * Accessibility
  * Generic parameters
  * Class inheritance
  * Interface inheritance
  * Final (sealed)
  * Module (static class)
  * Correct parent expression (root, namespace, class, or module)
  * If a compiler error is supposed to be thrown, validate it is the correct error.
  *
  * */
 public static void ValidateClass(Class c, 
     Expression parentExpression, 
     string name, 
     string fullName, 
     Accessibility access, 
     bool module, 
     bool final,
     bool partial,
     bool isAbstract,
     bool isStruct)
 {
     // Validate the class
     Assert.AreEqual(name, c.UnqualifiedName, "class Name");
     Assert.AreEqual(module, c.IsModule, "IsModule");
     Assert.AreEqual(fullName, c.GetQualifiedName(), "FullName");
     Assert.AreEqual(c.Accessibility, access, "Accessibility");
     Assert.AreEqual(parentExpression, c.ParentExpression, "ParentExpresion");
     Assert.AreEqual(final, c.IsFinal, "IsFinal");
     Assert.AreEqual(partial, c.IsPartial, "IsPartial");
     Assert.AreEqual(isAbstract, c.IsAbstract, "IsAbstract");
     Assert.AreEqual(isStruct, c.IsStruct);
 }
Exemple #5
0
        // Interpret class declaration modifiers: make sure to check for duplicates or conflicting ones.
        static void InterpretClassModifiers(Root root, Class c, ParseTreeNode node)
        {
            bool foundPublic = false;
            bool foundInternal = false;
            bool foundFinal = false;
            bool foundPartial = false;
            bool foundAbstract = false;

            foreach (var modifierNode in node.ChildNodes)
            {
                string text = modifierNode.FindTokenAndGetText();

                if (text == "public")
                {
                    if (foundPublic || foundInternal)
                    {
                        root.CompilerErrors.Add(new MultipleAccessModifiersCompilerError("",
                            modifierNode.FindToken().Location.Line,
                            modifierNode.FindToken().Location.Position));
                    }
                    else
                    {
                        c.Accessibility = Accessibility.Public;
                        foundPublic = true;
                    }
                }

                if (text == "internal")
                {
                    if (foundInternal || foundPublic)
                    {
                        root.CompilerErrors.Add(new MultipleAccessModifiersCompilerError("",
                            modifierNode.FindToken().Location.Line,
                            modifierNode.FindToken().Location.Position));
                    }
                    else
                    {
                        c.Accessibility = Accessibility.Internal;
                        foundInternal = true;
                    }
                }

                if (text == "final")
                {
                    if (foundFinal)
                    {
                        root.CompilerErrors.Add(new DuplicateModifiersCompilerError("",
                            modifierNode.FindToken().Location.Line,
                            modifierNode.FindToken().Location.Position));
                    }
                    else
                    {
                        if (c.IsModule)
                            root.CompilerErrors.Add(new ModuleModifierCompilerError("",
                                modifierNode.FindToken().Location.Line,
                                modifierNode.FindToken().Location.Position));
                        c.IsFinal = true;
                        foundFinal = true;
                    }
                }

                if (text == "partial")
                {
                    if (foundPartial)
                    {
                        root.CompilerErrors.Add(new DuplicateModifiersCompilerError("",
                            modifierNode.FindToken().Location.Line,
                            modifierNode.FindToken().Location.Position));
                    }
                    else
                    {
                        if (c.IsModule)
                            root.CompilerErrors.Add(new ModuleModifierCompilerError("",
                                modifierNode.FindToken().Location.Line,
                                modifierNode.FindToken().Location.Position));
                        c.IsPartial = true;
                        foundPartial = true;
                    }
                }

                if (text == "abstract")
                {
                    if (foundAbstract)
                    {
                        root.CompilerErrors.Add(new DuplicateModifiersCompilerError("",
                            modifierNode.FindToken().Location.Line,
                            modifierNode.FindToken().Location.Position));
                    }
                    else
                    {
                        if (c.IsModule)
                            root.CompilerErrors.Add(new ModuleModifierCompilerError("",
                                modifierNode.FindToken().Location.Line,
                                modifierNode.FindToken().Location.Position));
                        c.IsAbstract = true;
                        foundAbstract = true;
                    }
                }
            }
        }
Exemple #6
0
        /* Builds the CodeDOM statement for a class, and attaches it to a
         * CodeDOM namespace statement. */
        public static void Emit(CodeNamespace codeNamespace, Class c)
        {
            // CodeTypeDeclaration is the CodeDOM representation of a
            // class, struct, or enum.
            var codeTypeDeclaration = new CodeTypeDeclaration();
            codeNamespace.Types.Add(codeTypeDeclaration);

            // Assign the unqualified name (without namespace).
            codeTypeDeclaration.Name = c.UnqualifiedName;

            if(c.IsStruct)
                codeTypeDeclaration.IsStruct = true;
            else
            // Flag the type as a class.
                codeTypeDeclaration.IsClass = true;

            // Create the enum that sets attributes of the class.
            var typeAttr = TypeAttributes.Class;

            // If the class is "final", it is "sealed" in C# terms.
            if (c.IsFinal)
                typeAttr |= TypeAttributes.Sealed;

            if (c.IsAbstract)
                typeAttr |= TypeAttributes.Abstract;

            // Assign the partial state of the class.
            codeTypeDeclaration.IsPartial = c.IsPartial;

            // Add the list of generic type names of the class.
            foreach (string s in c.GenericTypeNames)
                codeTypeDeclaration.TypeParameters.Add(new CodeTypeParameter(s));

            // Add the list of base type names of the class.
            foreach(string s in c.BaseTypeNames)
                codeTypeDeclaration.BaseTypes.Add(s);

            // Set the accessibility of the class.
            switch(c.Accessibility)
            {
                case Accessibility.Internal:
                    typeAttr |= TypeAttributes.NestedAssembly;
                    break;
                case Accessibility.Public:
                    typeAttr |= TypeAttributes.Public;
                    break;
            }
            codeTypeDeclaration.TypeAttributes = typeAttr;

            /* Iterate through and emit the children */
            foreach (var e in c.ChildExpressions)
            {
                if (e is ClassVariable)
                    ClassVariableEmitter.Emit(codeTypeDeclaration, e as ClassVariable);
                if (e is MethodDeclaration)
                    MethodEmitter.Emit(codeTypeDeclaration, (MethodDeclaration)e);
                if (e is Constructor)
                    ConstructorEmitter.Emit(codeTypeDeclaration, (e as Constructor));
                if (e is Property)
                    PropertyEmitter.Emit(codeTypeDeclaration, (e as Property));
                if (e is Event)
                    EventEmitter.Emit(codeTypeDeclaration, (e as Event));
            }
        }