public void PropertyExtraction_VisibilityModifier(string phpCode, AstConstants.VisibilityModifiers modifiers)
        {
            var extract = ParseAndExtract(phpCode);

            foreach (var property in extract.Classes.SelectMany(c => c.Properties))
            {
                Assert.AreEqual(modifiers, property.VisibilityModifiers, "Property: " + property);
            }
        }
 public void EnteringNode(object sender, XmlTraverseEventArgs e)
 {
     var node = e.Node;
     switch (node.LocalName)
     {
         // Nodes
         case AstConstants.Nodes.Stmt_Interface:
             currentInterface = new Interface(node)
             {
                 StartLine = AstNode.GetStartLine(node),
                 EndLine = AstNode.GetEndLine(node)
             };
             break;
         case AstConstants.Nodes.Stmt_Class:
             currentClass = new Class(node)
             {
                 StartLine = AstNode.GetStartLine(node),
                 EndLine = AstNode.GetEndLine(node)
             };
             break;
         case AstConstants.Nodes.Stmt_ClassMethod:
             ClassMethodEnter(node);
             break;
         case AstConstants.Nodes.Stmt_Property:
             inPropertyDeclarations = true;
             break;
         case AstConstants.Nodes.Stmt_PropertyProperty:
             currentProperty = new Property(node)
             {
                 StartLine = AstNode.GetStartLine(node),
                 EndLine = AstNode.GetEndLine(node),
                 VisibilityModifiers = propertyModifiers,
             };
             break;
         case AstConstants.Nodes.Stmt_Function:
             currentFunctions.Push(new Function(node)
             {
                 StartLine = AstNode.GetStartLine(node),
                 EndLine = AstNode.GetEndLine(node)
             });
             functionClosureOrder.Push(FunctionClosure.Function);
             break;
         case AstConstants.Nodes.Expr_Closure:
             currentClosures.Push(new ExtractorClosureInfo()
             {
                 Closure = new Closure(node)
                           {
                               StartLine = AstNode.GetStartLine(node),
                               EndLine = AstNode.GetEndLine(node)
                           }
             });
             functionClosureOrder.Push(FunctionClosure.Closure);
             break;
         case AstConstants.Nodes.Param:
             currentParameter = new Parameter(node);
             break;
         case AstConstants.Nodes.Expr_ClosureUse:
             currentClosureUse = new ClosureUse(node);
             break;
         // Subnodes
         case AstConstants.Subnodes.Name:
             Name(node);
             break;
         case AstConstants.Subnodes.Params:
             inParamDeclarations = true;
             break;
         case AstConstants.Subnodes.ByRef:
             Subnode_ByRef_Enter(node);
             break;
         case AstConstants.Subnodes.Variadic:
             if (inParamDeclarations && !parameteVariadicIsSet)
             {
                 currentParameter.IsVariadic = Convert.ToBoolean(node.FirstChild.LocalName);
                 parameteVariadicIsSet = true;
             }
             break;
         case AstConstants.Subnodes.Default:
             if (inParamDeclarations && !parameterDefaultIsSet)
             {
                 currentParameter.IsOptional = node.FirstChild.Prefix != AstConstants.Scalar;
                 parameterDefaultIsSet = true;
             }
             break;
         case AstConstants.Subnodes.Uses:
             if (currentClosures.Any() && currentClosures.Peek().ClosureUses == null && !currentClosures.Peek().ClosureUsagesIsSet)
             {
                 currentClosures.Peek().ClosureUses = new Queue<ClosureUse>();
             }
             break;
         case AstConstants.Subnodes.Var:
             if (currentClosureUse != null)
             {
                 currentClosureUse.Name = node.InnerText;
             }
             break;
         case AstConstants.Subnodes.Type:
             if (inPropertyDeclarations && currentProperty == null)
             {
                 propertyModifiers = (AstConstants.VisibilityModifiers) Enum.Parse(typeof (AstConstants.VisibilityModifiers), node.InnerText);
             }
             break;
     }
 }
 public void LeavingNode(object sender, XmlTraverseEventArgs e)
 {
     var node = e.Node;
     switch (node.LocalName)
     {
         // Nodes
         case AstConstants.Nodes.Stmt_Interface:
             _interfaces.Add(currentInterface);
             currentInterface = null;
             break;
         case AstConstants.Nodes.Stmt_Class:
             _classes.Add(currentClass);
             currentClass = null;
             break;
         case AstConstants.Nodes.Stmt_ClassMethod:
             ClassMethodExit();
             break;
         case AstConstants.Nodes.Stmt_Property:
             inPropertyDeclarations = false;
             propertyModifiers = 0;
             break;
         case AstConstants.Nodes.Stmt_PropertyProperty:
             currentClass.Properties.Add(currentProperty);
             currentProperty = null;
             break;
         case AstConstants.Nodes.Stmt_Function:
             _functions.Add(currentFunctions.Pop());
             functionClosureOrder.Pop();
             break;
         case AstConstants.Nodes.Expr_ClosureUse:
             currentClosures.Peek().ClosureUses.Enqueue(currentClosureUse);
             currentClosureUse = null;
             break;
         case AstConstants.Nodes.Expr_Closure:
             _closures.Add(currentClosures.Pop().Closure);
             functionClosureOrder.Pop();
             break;
         case AstConstants.Nodes.Param:
             parameters.Enqueue(currentParameter);
             currentParameter = null;
             parameteVariadicIsSet = false;
             parameterByRefIsSet = false;
             parameterDefaultIsSet = false;
             break;
         // Subnodes
         case AstConstants.Subnodes.Params:
             ParamsExit();
             break;
         case AstConstants.Subnodes.Uses:
             if (currentClosures.Any())
             {
                 ExtractorClosureInfo closureInfo = currentClosures.Peek();
                 if (!closureInfo.ClosureUsagesIsSet && closureInfo.ClosureUses != null)
                 {
                     closureInfo.Closure.UseParameters = closureInfo.ClosureUses.ToArray();
                     closureInfo.ClosureUsagesIsSet = true;
                 }
             }
             break;
     }
 }
        public void EnteringNode(object sender, XmlTraverseEventArgs e)
        {
            var node = e.Node;

            switch (node.LocalName)
            {
            // Nodes
            case AstConstants.Nodes.Stmt_Interface:
                currentInterface = new Interface(node)
                {
                    StartLine = AstNode.GetStartLine(node),
                    EndLine   = AstNode.GetEndLine(node)
                };
                break;

            case AstConstants.Nodes.Stmt_Class:
                currentClass = new Class(node)
                {
                    StartLine = AstNode.GetStartLine(node),
                    EndLine   = AstNode.GetEndLine(node)
                };
                break;

            case AstConstants.Nodes.Stmt_ClassMethod:
                ClassMethodEnter(node);
                break;

            case AstConstants.Nodes.Stmt_Property:
                inPropertyDeclarations = true;
                break;

            case AstConstants.Nodes.Stmt_PropertyProperty:
                currentProperty = new Property(node)
                {
                    StartLine           = AstNode.GetStartLine(node),
                    EndLine             = AstNode.GetEndLine(node),
                    VisibilityModifiers = propertyModifiers,
                };
                break;

            case AstConstants.Nodes.Stmt_Function:
                currentFunctions.Push(new Function(node)
                {
                    StartLine = AstNode.GetStartLine(node),
                    EndLine   = AstNode.GetEndLine(node)
                });
                functionClosureOrder.Push(FunctionClosure.Function);
                break;

            case AstConstants.Nodes.Expr_Closure:
                currentClosures.Push(new ExtractorClosureInfo()
                {
                    Closure = new Closure(node)
                    {
                        StartLine = AstNode.GetStartLine(node),
                        EndLine   = AstNode.GetEndLine(node)
                    }
                });
                functionClosureOrder.Push(FunctionClosure.Closure);
                break;

            case AstConstants.Nodes.Param:
                currentParameter = new Parameter(node);
                break;

            case AstConstants.Nodes.Expr_ClosureUse:
                currentClosureUse = new ClosureUse(node);
                break;

            // Subnodes
            case AstConstants.Subnodes.Name:
                Name(node);
                break;

            case AstConstants.Subnodes.Params:
                inParamDeclarations = true;
                break;

            case AstConstants.Subnodes.ByRef:
                Subnode_ByRef_Enter(node);
                break;

            case AstConstants.Subnodes.Variadic:
                if (inParamDeclarations && !parameteVariadicIsSet)
                {
                    currentParameter.IsVariadic = Convert.ToBoolean(node.FirstChild.LocalName);
                    parameteVariadicIsSet       = true;
                }
                break;

            case AstConstants.Subnodes.Default:
                if (inParamDeclarations && !parameterDefaultIsSet)
                {
                    currentParameter.IsOptional = node.FirstChild.Prefix != AstConstants.Scalar;
                    parameterDefaultIsSet       = true;
                }
                break;

            case AstConstants.Subnodes.Uses:
                if (currentClosures.Any() && currentClosures.Peek().ClosureUses == null && !currentClosures.Peek().ClosureUsagesIsSet)
                {
                    currentClosures.Peek().ClosureUses = new Queue <ClosureUse>();
                }
                break;

            case AstConstants.Subnodes.Var:
                if (currentClosureUse != null)
                {
                    currentClosureUse.Name = node.InnerText;
                }
                break;

            case AstConstants.Subnodes.Type:
                if (inPropertyDeclarations && currentProperty == null)
                {
                    var visibilityModifiers = (AstConstants.VisibilityModifiers)Enum.Parse(typeof(AstConstants.VisibilityModifiers), node.InnerText);
                    // No modifier in source code = 0, if no modifier is present the default visibility is public
                    propertyModifiers = visibilityModifiers == 0 ? AstConstants.VisibilityModifiers.Public : visibilityModifiers;
                }
                break;
            }
        }
        public void LeavingNode(object sender, XmlTraverseEventArgs e)
        {
            var node = e.Node;

            switch (node.LocalName)
            {
            // Nodes
            case AstConstants.Nodes.Stmt_Interface:
                _interfaces.Add(currentInterface);
                currentInterface = null;
                break;

            case AstConstants.Nodes.Stmt_Class:
                _classes.Add(currentClass);
                currentClass = null;
                break;

            case AstConstants.Nodes.Stmt_ClassMethod:
                ClassMethodExit();
                break;

            case AstConstants.Nodes.Stmt_Property:
                inPropertyDeclarations = false;
                propertyModifiers      = 0;
                break;

            case AstConstants.Nodes.Stmt_PropertyProperty:
                currentClass.Properties.Add(currentProperty);
                currentProperty = null;
                break;

            case AstConstants.Nodes.Stmt_Function:
                _functions.Add(currentFunctions.Pop());
                functionClosureOrder.Pop();
                break;

            case AstConstants.Nodes.Expr_ClosureUse:
                currentClosures.Peek().ClosureUses.Enqueue(currentClosureUse);
                currentClosureUse = null;
                break;

            case AstConstants.Nodes.Expr_Closure:
                _closures.Add(currentClosures.Pop().Closure);
                functionClosureOrder.Pop();
                break;

            case AstConstants.Nodes.Param:
                parameters.Enqueue(currentParameter);
                currentParameter      = null;
                parameteVariadicIsSet = false;
                parameterByRefIsSet   = false;
                parameterDefaultIsSet = false;
                break;

            // Subnodes
            case AstConstants.Subnodes.Params:
                ParamsExit();
                break;

            case AstConstants.Subnodes.Uses:
                if (currentClosures.Any())
                {
                    ExtractorClosureInfo closureInfo = currentClosures.Peek();
                    if (!closureInfo.ClosureUsagesIsSet && closureInfo.ClosureUses != null)
                    {
                        closureInfo.Closure.UseParameters = closureInfo.ClosureUses.ToArray();
                        closureInfo.ClosureUsagesIsSet    = true;
                    }
                }
                break;
            }
        }