public void detect_cicle_with_three_types()
        {
            var typeA = new AliasTypeDeclarationNode
                {
                    ExistingType = new TypeReferenceNode
                        {
                            TypeName = "b"
                        },
                    Name = new TypeIdentifierNode
                        {
                            Name = "a"
                        }
                };
            var typeB = new AliasTypeDeclarationNode
                {
                    ExistingType = new TypeReferenceNode
                        {
                            TypeName = "c"
                        },
                    Name = new TypeIdentifierNode
                        {
                            Name = "b"
                        }
                };
            var typeC = new AliasTypeDeclarationNode
                {
                    ExistingType = new TypeReferenceNode
                        {
                            TypeName = "a"
                        },
                    Name = new TypeIdentifierNode
                        {
                            Name = "c"
                        }
                };
            var types = new[] {typeA, typeB, typeC};

            var target = new CircularTypeReferencesError(types, SourceLocation.Invalid);

            Assert.IsTrue(target.IsActive);
        }
        protected internal override void CheckSemantics(AstHelper astHelper)
        {
            AstHelper helper = astHelper.CreateChild(function: true, variables: true, types: true);

            // add all type builders to the scope in case of recursive type calls
            foreach (IAddToScope typeDeclarationNode in TypeDeclarations.OfType<IAddToScope>())
                typeDeclarationNode.AddToScope(helper);

            var error = new CircularTypeReferencesError(TypeDeclarations, Start);
            astHelper.Errors.Check(error);
            // define other types
            foreach (TypeDeclarationNode typeDeclarationNode in error.OrderedTypes)
                typeDeclarationNode.CheckSemantics(helper);

            // add all functions to the scope in case of recursive calls
            foreach (FunctionDefinitionExpression functionDefinitionExpression in FunctionDefinitions)
                functionDefinitionExpression.AddToScope(helper);

            foreach (VariableDeclarationBase variableDeclarationExpression in VariableDeclarations)
                variableDeclarationExpression.CheckSemantics(helper);

            foreach (FunctionDefinitionExpression functionDefinitionExpression in FunctionDefinitions)
                functionDefinitionExpression.CheckSemantics(helper);

            Body.CheckSemantics(helper);

            IEnumerable<ParameterExpression> variables = from variable in VariableDeclarations select variable.Pointer;
            IEnumerable<ParameterExpression> functions = from function in FunctionDefinitions select function.Pointer;
            // calculate the closure that will be used when we're generating the expression
            _closure = variables.Union(functions);
        }
        public void use_type_defined_below()
        {
            var typeA = new AliasTypeDeclarationNode
                {
                    ExistingType = new TypeReferenceNode
                        {
                            TypeName = "b"
                        },
                    Name = new TypeIdentifierNode
                        {
                            Name = "a"
                        }
                };
            var typeB = new AliasTypeDeclarationNode
                {
                    ExistingType = new TypeReferenceNode
                        {
                            TypeName = "int"
                        },
                    Name = new TypeIdentifierNode
                        {
                            Name = "b"
                        }
                };
            var types = new[] {typeA, typeB};

            var target = new CircularTypeReferencesError(types, SourceLocation.Invalid);

            CollectionAssert.AreEqual(new[] {typeB, typeA}, target.OrderedTypes);
            Assert.IsFalse(target.IsActive);
        }
        public void returns_types_not_involved_in_cicle()
        {
            var typeA = new AliasTypeDeclarationNode
                {
                    ExistingType = new TypeReferenceNode
                        {
                            TypeName = "b"
                        },
                    Name = new TypeIdentifierNode
                        {
                            Name = "a"
                        }
                };
            var typeB = new AliasTypeDeclarationNode
                {
                    ExistingType = new TypeReferenceNode
                        {
                            TypeName = "a"
                        },
                    Name = new TypeIdentifierNode
                        {
                            Name = "b"
                        }
                };
            var typeC = new AliasTypeDeclarationNode
                {
                    ExistingType = new TypeReferenceNode
                        {
                            TypeName = "int"
                        },
                    Name = new TypeIdentifierNode
                        {
                            Name = "c"
                        }
                };
            var types = new[] {typeA, typeB, typeC};

            var target = new CircularTypeReferencesError(types, SourceLocation.Invalid);

            CollectionAssert.AreEqual(new[] {typeC}, target.OrderedTypes);
            Assert.IsTrue(target.IsActive);
        }