Source for file Classes.inc
Documentation is available at
Classes.inc
<?php
/**
* Intermediate class parsing structure.
*
* phpDocumentor :: automatic documentation generator
*
* PHP versions 4 and 5
*
* Copyright (c) 2001-2007 Gregory Beaver
*
* LICENSE:
*
* This library is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser General
* Public License as published by the Free Software Foundation;
* either version 2.1 of the License, or (at your option) any
* later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
@category
ToolsAndUtilities
*
@package
phpDocumentor
*
@author
Greg Beaver <
[email protected]
>
*
@copyright
2001-2007 Gregory Beaver
*
@license
http://www.opensource.org/licenses/lgpl-license.php LGPL
*
@version
CVS: $Id: Classes.inc 243933 2007-10-10 01:18:25Z ashnazg $
*
@filesource
*
@link
http://www.phpdoc.org
*
@link
http://pear.php.net/PhpDocumentor
*
@see
parserDocBlock, parserInclude, parserPage, parserClass
*
@see
parserDefine, parserFunction, parserMethod, parserVar
*
@since
1.0rc1
*
@todo
CS cleanup - change package to PhpDocumentor
*/
/**
* Intermediate class parsing structure.
*
* The
{@link phpDocumentor_IntermediateParser}
class uses this class and its
* cousin,
{@link ProceduralPages}
to organize all parsed source code elements.
* Data is fed to each immediately after it is parsed, and at conversion time,
* everything is organized.
*
* The Classes class is responsible for all inheritance, including resolving
* name conflicts between classes, determining which classes extend other
* classes, and is responsible for all inheritance of documentation.
*
{@internal
* This structure parses classes, vars and methods by file, and then iterates
* over the class tree to set up inheritance. The {@link Inherit()}
* method is the meat of the class, and processes the class trees from root to
* branch, ensuring that parsing order is unimportant.}}
}
*
*
@category
ToolsAndUtilities
*
@package
phpDocumentor
*
@author
Greg Beaver <
[email protected]
>
*
@copyright
2001-2007 Gregory Beaver
*
@license
http://www.opensource.org/licenses/lgpl-license.php LGPL
*
@version
Release: @VER@
*
@link
http://www.phpdoc.org
*
@link
http://pear.php.net/PhpDocumentor
*
@since
1.0rc1
*
@todo
CS cleanup - change package to PhpDocumentor
*/
class
Classes
{
/**#@+
* @access private
*/
/**
* file being parsed, used in every add function to match up elements with
* the file that contains them
*
* This variable is used during parsing to associate class elements added
* to the data structures that contain them with the file they reside in
*
@see
addClass(), addMethod(), addVar(), nextFile()
*
@var
string
*/
var
$curfile
;
/**
* class being parsed, used to match up methods and vars with their parent
* class
*
* This variable is used during parsing to associate class elements added
* to the data structures that contain them with the file they reside in
*
@see
addMethod(), addVar()
*
@var
string
*/
var
$curclass
;
/**
* Used when a definite match is made between a parent class and a child
* class
*
* This variable is used in post-parsing.
*
* Format:<pre>
* array(
* parent => array(
* parentfile => array(
* child => childfile
* )
* )
* )</pre>
*
@var
array
*/
var
$definitechild
;
/**
* array of parsed classes organized by the name of the file that contains
* the class.
*
* Format:<pre>
* array(
* filename => array(
* classname =>
{@link parserClass}
* )
* )</pre>
*
@var
array
*/
var
$classesbyfile
= array
(
)
;
/**
* array of file names organized by classes that are in the file.
*
* This structure is designed to handle name conflicts. Two files can
* contain classes with the same name, and this array will record both
* filenames to help control linking and inheritance errors
*
* Format:<pre>
* array(
* classname => array(
* name of file containing classname,
* name of file 2 containing classname,
* ...
* )
* )</pre>
*
@var
array
*/
var
$classesbynamefile
= array
(
)
;
/**
* array of parsed methods organized by the file that contains them.
*
* Format:<pre>
* array(
* filename => array(
* classname => array(
*
{@link parserMethod}
1,
*
{@link parserMethod}
2,
* ...
* )
* )
* )</pre>
*
@var
array
*/
var
$methodsbyfile
= array
(
)
;
/**
* array of parsed vars organized by the file that contains them.
*
* Format:<pre>
* array(
* filename => array(
* classname => array(
*
{@link parserVar}
1,
*
{@link parserVar}
2,
* ...
* )
* )
* )</pre>
*
@var
array
*/
var
$varsbyfile
= array
(
)
;
/**
* array of parsed class constants organized by the file that contains them.
*
* Format:<pre>
* array(
* filename => array(
* classname => array(
*
{@link parserConst}
1,
*
{@link parserConst}
2,
* ...
* )
* )
* )</pre>
*
@var
array
*/
var
$constsbyfile
= array
(
)
;
/**
* keeps track of extend declarations by file, used to find inheritance
*
* Format:<pre>
* array(
* filename => array(
* classname => parentclassname
* )
* )</pre>
*
@var
array
*/
var
$extendsbyfile
= array
(
)
;
/**
* Keeps track of child classes by file.
* Since phpDocumentor can document collections of files that contain name
* conflicts (PHP would give a fatal error), it
* is impossible to assume a class that declares "extends foo" necessarily
* extends the class foo in file X. It could be an
* extended class of class foo in file Y. Because of this, phpDocumentor
* relies on packaging to resolve the name conflict
* This array keeps track of the packages of a child class
*
* Format:<pre>
* array(
* parentclassname => array(
* filename => array(
* childclassname => array(
* packagename,
* packagename
* )
* )
* )
* )</pre>
*
@var
array
*/
var
$classchildrenbyfile
= array
(
)
;
/**
* Keeps track of class packages found in a file.
* This is used in
{@link getParentClass()}
to determine the number of
* packages in a file, in order to resolve inheritance issues
* Format:<pre>
* array(
* filename => array(
* packagename1,
* packagename2,
* ...
* )
* )</pre>
*
@var
array
*/
var
$classpackagebyfile
= array
(
)
;
/**
* a tree of class inheritance by name.
*
* Format:<pre>
* array(
* childname => parentname,
* childname1 => parentname1,
* rootname => 0,
* ...
* )</pre>
*
@var
array
*
@see
Converter::generateSortedClassTreeFromClass()
*/
var
$classparents
= array
(
)
;
/**
* Keeps track of package and subpackage for each class name, organized
* by package
*
* Format:<pre>
* array(
* classname => array(
* path => array(
* package,
* subpackage
* ),
* path2 => array(
* package,
* subpackage
* ),
* ...
* )
* )</pre>
*
@var
array
*/
var
$classpathpackages
= array
(
)
;
/**
* used to delete duplicates in the same package to avoid documentation errors
*
* Specifically used in
{@link Converter::checkKillClass()}
*/
var
$killclass
= array
(
)
;
/**
* array of methods by package and class
*
* format:<pre>
* array(packagename =>
* array(classname =>
* array(methodname1 =>
{@link parserMethod}
class,
* methodname2 =>
{@link parserMethod}
class,...)
* )
* )
* )</pre>
*
@var
array
*
@see
Converter
*/
var
$methods
= array
(
)
;
/**
* array of class variables by package and class
*
* format:<pre>
* array(packagename =>
* array(classname =>
* array(variablename1 =>
{@link parserVar}
class,
* variablename2 =>
{@link parserVar}
class,...
* )
* )
* )</pre>
*
@var
array
*
@see
Converter
*/
var
$vars
= array
(
)
;
/**
* array of class variables by package and class
*
* format:<pre>
* array(packagename =>
* array(classname =>
* array(constname1 =>
{@link parserConst}
class,
* constname2 =>
{@link parserConst}
class,...
* )
* )
* )</pre>
*
@var
array
*
@see
Converter
*/
var
$consts
= array
(
)
;
/**
* Reverse class_packages_by_file, used to prevent duplicates
*
@var
array
Format: array(packagename => 1)
*/
var
$revcpbf
= array
(
)
;
/**
* All classes with no parents (no extends clause) are tracked in this array
* by the file that contains them.
*
* Format:<pre>
* array(
* classname => array(
* name of file1 that contains root classname,
* name of file2 that contains root classname,
* ...
* )
* )</pre>
*
@var
array
*/
var
$roots
= array
(
)
;
/**
* All classes with a parent that was not parsed are included in this array
*
* Format:<pre>
* array(
* classname => array(
* name of file1 that contains root classname,
* name of file2 that contains root classname,
* ...
* )
* )</pre>
*
@var
array
*/
var
$specialRoots
= array
(
)
;
/**
* array of all files that contain classes with the same name
*
@var
array
Format: (classname => array(path1, path2,...))
*/
var
$potentialclassconflicts
= array
(
)
;
/**
* array of all inter-package name conflicts of classes
*
* This array allows documentation of PHP namespace conflicts that would
* occur should a user try to include these files in the same file
*
@var
array
Format: (classname => array(path1, path2,...))
*/
var
$classconflicts
= array
(
)
;
/**#@-*/
/**
* While parsing, add a class to the list of parsed classes
*
* sets up the
{@link $classesbyfile, $classesbynamefile, $extendsbyfile}
,
*
{@link $classchildrenbyfile, $roots}
arrays, and sets
{@link $curclass}
*
*
@param
parserClass
&$element
element is a
{@link parserClass}
*
*
@return
void
*
@uses
addPackageToFile() marks the current class's package as being
* present in a file
*/
function
addClass
(
&
$element
)
{
$this
->
curclass
=
$element
->
getName
(
)
;
$element
->
curfile =
$this
->
curfile
;
if
(
isset
(
$this
->
classesbyfile
[
$this
->
curfile
]
[
$this
->
curclass
]
))
{
addWarning
(
PDERROR_ELEMENT_IGNORED
,
'class'
,
$this
->
curclass
,
$this
->
curfile
)
;
$this
->
curclass
= false
;
return
;
}
$this
->
classesbyfile
[
$this
->
curfile
]
[
$this
->
curclass
]
=
$element
;
$this
->
classesbynamefile
[
$this
->
curclass
]
[
]
=
$this
->
curfile
;
$this
->
extendsbyfile
[
$this
->
curfile
]
[
$this
->
curclass
]
=
$element
->
getExtends
(
)
;
$this
->
classchildrenbyfile
[
$element
->
getExtends
(
)
]
[
$this
->
curfile
]
[
$this
->
curclass
]
[
]
=
$element
->
docblock
->
package
;
if
(
$element
->
docblock
->
getExplicitPackage
(
))
$this
->
addPackageToFile
(
$element
->
docblock
->
package
)
;
if
(
!
$element
->
getExtends
(
))
{
$this
->
roots
[
$this
->
curclass
]
[
]
=
$this
->
curfile
;
}
}
/**
* While parsing, add a method to the list of parsed methods
*
* sets up the
{@link $methodsbyfile}
array using
{@link $curfile}
and
*
{@link $curclass}
*
*
@param
parserMethod
&$element
element is a
{@link parserMethod}
*
*
@return
void
*/
function
addMethod
(
&
$element
)
{
if
(
!
$this
->
curclass
)
return
;
$this
->
methodsbyfile
[
$this
->
curfile
]
[
$this
->
curclass
]
[
]
=
$element
;
}
/**
* While parsing, add a variable to the list of parsed variables
*
* sets up the
{@link $varsbyfile}
array using
{@link $curfile}
* and
{@link $curclass}
*
*
@param
parserVar
&$element
element is a
{@link parserVar}
*
*
@return
void
*/
function
addVar
(
&
$element
)
{
if
(
!
$this
->
curclass
)
return
;
$this
->
varsbyfile
[
$this
->
curfile
]
[
$this
->
curclass
]
[
]
=
$element
;
}
/**
* While parsing, add a variable to the list of parsed variables
*
* sets up the
{@link $constsbyfile}
array using
{@link $curfile}
* and
{@link $curclass}
*
*
@param
parserConst
&$element
element is a
{@link parserConst}
*
*
@return
void
*/
function
addConst
(
&
$element
)
{
if
(
!
$this
->
curclass
)
return
;
$this
->
constsbyfile
[
$this
->
curfile
]
[
$this
->
curclass
]
[
]
=
$element
;
}
/**
* Prepare to parse a new file
*
* sets
{@link $curfile}
to $file and
{@link $curclass}
* to false (no class being parsed)
*
*
@param
string
$file
file currently being parsed
*
*
@return
void
*/
function
nextFile
(
$file
)
{
$this
->
curfile
=
$file
;
$this
->
curclass
= false
;
}
/**
* Mark a package as being used in a class
*
*
{@source }
*
*
@param
string
$package
package name
*
*
@return
void
*/
function
addPackageToFile
(
$package
)
{
if
(
!
isset
(
$this
->
revcpbf
[
$this
->
curfile
]
[
$package
]
))
$this
->
classpackagebyfile
[
$this
->
curfile
]
[
]
=
$package
;
$this
->
revcpbf
[
$this
->
curfile
]
[
$package
]
= 1
;
}
/**
* Find the parent class of $class, and set up structures to note this fact
*
* Modifies the
{@link parserClass}
element in
{@link $classesbyfile}
to use
* the parent's package, and inherit methods/vars
*
*
@param
string
$class
child class to find parent class
*
@param
string
$file
file child class is located in
*
*
@return
void
*
@uses
$definitechild if a match is made between a parent class and parameter
* $class in file $file, then definitechild is set here
*
@uses
getParentClass() to find the parent class
*/
function
setClassParent
(
$class
,
$file
)
{
if
(
is_array
(
$par
=
$this
->
getParentClass
(
$class
,
$file
)))
{
// (for debugging)
// phpDocumentor_out("$file class $class extends "
// . $par[1] ." file ". $par[0] . "\n");
$this
->
classesbyfile
[
$file
]
[
$class
]
->
setParent
(
$par
[
1
]
,
$par
[
0
]
,
$this
)
;
$this
->
definitechild
[
$par
[
1
]]
[
$par
[
0
]]
[
$class
]
=
$file
;
}
else
{
$this
->
classesbyfile
[
$file
]
[
$class
]
->
setParentNoClass
(
$par
)
;
}
}
/**
* Main processing engine for setting up class inheritance.
*
* This function uses
{@link $roots}
to traverse the inheritance tree via
*
{@link processChild()}
and returns the data structures
* phpDocumentor_IntermediateParser needs to convert parsed data
* to output using
{@link phpDocumentor_IntermediateParser::Convert()}
*
*
@param
phpDocumentor_IntermediateParser
&$render
the renderer object
*
*
@return
void
*
@uses
processChild() set up inheritance
*
@todo
CS Cleanup - rename to "inherit" for CamelCaps naming standard
*/
function
Inherit
(
&
$render
)
{
phpDocumentor_out
(
"\nProcessing Class Inheritance\n\n"
)
;
flush
(
)
;
phpDocumentor_out
(
"\nProcessing Root Trees\n\n"
)
;
flush
(
)
;
foreach
(
$this
->
roots
as
$class
=>
$files
)
{
for
(
$i
=0
;
$i
<
count
(
$files
)
;
$i
++
)
{
$this
->
processChild
(
$render
,
$class
,
$files
[
$i
]
)
;
}
}
if
(
0
)
foreach
(
$this
->
classesbyfile
as
$i
=>
$j
)
{
foreach
(
$j
as
$k
=>
$m
)
{
var_dump
(
$i
,
$k
)
;
if
(
$i
==
'iConverter'
)
{
var_dump
(
$j
)
;
}
}
}
phpDocumentor_out
(
"\nProcessing leftover classes "
.
"(classes that extend root classes not found in the same package)\n"
)
;
flush
(
)
;
foreach
(
$this
->
classesbyfile
as
$i
=>
$j
)
{
foreach
(
$j
as
$k
=>
$m
)
{
$this
->
processChild
(
$render
,
$k
,
$i
,
true
)
;
}
}
phpDocumentor_out
(
"done processing leftover classes\n"
)
;
flush
(
)
;
$this
->
setupClassConflicts
(
)
;
}
/**
* Transfers actual conflicts from
{@link $potentialClassconflicts}
to
*
{@link $classconflicts}
*
*
@return
void
*
@access
private
*
@uses
$potentialclassconflicts transfers values to
{@link $classconflicts}
*/
function
setupClassConflicts
(
)
{
foreach
(
$this
->
potentialclassconflicts
as
$class
=>
$paths
)
{
if
(
count
(
$paths
)
- 1
)
{
//conflict
$package
= array
(
)
;
foreach
(
$paths
as
$path
)
{
// create a list of conflicting classes in each package
if
(
isset
(
$this
->
classpathpackages
[
$class
]
[
$path
]
))
$package
[
$this
->
classpathpackages
[
$class
]
[
$path
]
[
0
]]
[
]
=
$path
;
}
foreach
(
$package
as
$pathpackages
)
{
/*
* if at least 2 functions exist in the same package,
* delete all but the first one and add warnings
*/
if
(
count
(
$pathpackages
)
- 1
)
{
for
(
$i
=1
;
$i
<
count
(
$pathpackages
)
;
$i
++
)
{
if
(
isset
(
$this
->
classesbyfile
[
$pathpackages
[
$i
]]
))
{
addWarning
(
PDERROR_ELEMENT_IGNORED
,
'class'
,
$class
,
$pathpackages
[
$i
]
)
;
$this
->
killClass
(
$class
,
$pathpackages
[
$i
]
)
;
$oth
=
array_flip
(
$paths
)
;
unset
(
$paths
[
$oth
[
$pathpackages
[
$i
]]]
)
;
}
}
}
}
$this
->
classconflicts
[
$class
]
=
$paths
;
}
}
}
/**
* If a package contains two classes with the same name, this function finds
* that conflict
*
* Returns the
{@link $classconflicts}
entry for class $class, minus its own path
*
*
@param
mixed
$class
the class name to search for
*
*
@return
mixed
returns false if no conflicts,
* or an array of paths containing conflicts
*/
function
getConflicts
(
$class
)
{
if
(
!
isset
(
$this
->
classconflicts
[
$class
]
))
return
false
;
$a
= array
(
)
;
foreach
(
$this
->
classconflicts
[
$class
]
as
$conflict
)
{
$a
[
$this
->
classesbyfile
[
$conflict
]
[
$class
]
->
docblock
->
package
]
=
$this
->
classesbyfile
[
$conflict
]
[
$class
]
;
}
return
$a
;
}
/**
* sets up
{@link $killclass}
for use by Converter::checkKillClass()
*
*
@param
mixed
$class
the class
*
@param
mixed
$path
the path
*
*
@return
void
*
@access
private
*/
function
killClass
(
$class
,
$path
)
{
$this
->
killclass
[
$class
]
[
$path
]
= true
;
}
/**
* This function recursively climbs up the class tree, setting inherited
* information like package and adds the elements to
*
{@link phpDocumentor_IntermediateParser}
.
*
* Using structures defined in
{@link Classes}
,
* the function first sets package information,
* and then seeks out child classes.
* It uses 3 tests to determine whether a class is a child class.
* <ol>
* <li>child class is in the same file as the parent class
* and extends parent class
* </li>
* <li>child class is in a different file and specifies
* the parent's @package in its docblock
* </li>
* <li>child class is in a different file and is in a
* different @package, with one possible parent class
* </li>
* </ol>
*
*
@param
phpDocumentor_IntermediateParser
&$render
the renderer object
*
@param
string
$class
class to process
*
@param
string
$file
name of file $class
* is located in
*
@param
boolean
$furb
flag used privately
* to control informational
* output while parsing
* (used when processing
* leftover classes in
*
{@link Inherit()}
*
*
@return
void
*
@global
string
default package, usually "default"
*/
function
processChild
(
&
$render
,
$class
,
$file
,
$furb
= false
)
{
global
$phpDocumentor_DefaultPackageName
;
if
(
isset
(
$this
->
classesbyfile
[
$file
]
[
$class
]
->
processed
))
return
;
$this
->
potentialclassconflicts
[
$class
]
[
]
=
$file
;
if
(
$furb
)
phpDocumentor_out
(
"
Processing
$class
in file
$file
\n
"
)
;
flush
(
)
;
$this
->
classesbyfile
[
$file
]
[
$class
]
->
processed = true
;
$db
=
$this
->
classesbyfile
[
$file
]
[
$class
]
;
$render
->
addUses
(
$db
,
$file
)
;
if
(
!
$render
->
parsePrivate
)
{
/*
* if this class has an @access private,
* and parse private is disabled, remove it
*/
if
(
$db
->
docblock
->
hasaccess
)
{
$aaa
=
$db
->
docblock
->
getKeyword
(
'access'
)
;
if
(
is_object
(
$aaa
)
&&
$aaa
->
getString
(
)
==
'private'
)
{
if
(
isset
(
$this
->
varsbyfile
[
$file
]
)
&& isset
(
$this
->
varsbyfile
[
$file
]
[
$class
]
))
{
unset
(
$this
->
varsbyfile
[
$file
]
[
$class
]
)
;
}
if
(
isset
(
$this
->
methodsbyfile
[
$file
]
)
&& isset
(
$this
->
methodsbyfile
[
$file
]
[
$class
]
))
{
unset
(
$this
->
methodsbyfile
[
$file
]
[
$class
]
)
;
}
if
(
isset
(
$this
->
constsbyfile
[
$file
]
)
&& isset
(
$this
->
constsbyfile
[
$file
]
[
$class
]
))
{
unset
(
$this
->
constsbyfile
[
$file
]
[
$class
]
)
;
}
$this
->
classesbyfile
[
$file
]
[
$class
]
->
ignore = true
;
// if this is a root class, remove it from the roots array
if
(
isset
(
$this
->
roots
[
$class
]
))
{
foreach
(
$this
->
roots
[
$class
]
as
$i
=>
$files
)
{
// find the file key and unset
if
(
$files
==
$file
)
unset
(
$this
->
roots
[
$class
]
[
$i
]
)
;
}
}
/*
* if this is a child, remove it from the list
* of child classes of its parent
*/
if
(
$db
->
getExtends
(
))
unset
(
$this
->
classchildrenbyfile
[
$db
->
getExtends
(
)
]
[
$file
]
)
;
return
;
}
}
}
if
(
$render
->
packageoutput
)
{
if
(
!
in_array
(
$db
->
docblock
->
package
,
$render
->
packageoutput
))
{
if
(
isset
(
$this
->
varsbyfile
[
$file
]
)
&& isset
(
$this
->
varsbyfile
[
$file
]
[
$class
]
))
{
unset
(
$this
->
varsbyfile
[
$file
]
[
$class
]
)
;
}
if
(
isset
(
$this
->
methodsbyfile
[
$file
]
)
&& isset
(
$this
->
methodsbyfile
[
$file
]
[
$class
]
))
{
unset
(
$this
->
methodsbyfile
[
$file
]
[
$class
]
)
;
}
if
(
isset
(
$this
->
constsbyfile
[
$file
]
)
&& isset
(
$this
->
constsbyfile
[
$file
]
[
$class
]
))
{
unset
(
$this
->
constsbyfile
[
$file
]
[
$class
]
)
;
}
$this
->
classesbyfile
[
$file
]
[
$class
]
->
ignore = true
;
if
(
isset
(
$this
->
roots
[
$class
]
))
{
foreach
(
$this
->
roots
[
$class
]
as
$i
=>
$files
)
{
if
(
$files
==
$file
)
unset
(
$this
->
roots
[
$class
]
[
$i
]
)
;
}
}
if
(
$db
->
getExtends
(
))
unset
(
$this
->
classchildrenbyfile
[
$db
->
getExtends
(
)
]
[
$file
]
)
;
return
;
}
}
$this
->
setClassParent
(
$class
,
$file
)
;
$db
=
$this
->
classesbyfile
[
$file
]
[
$class
]
;
if
(
$furb
&&
!
is_array
(
$db
->
parent
))
{
// debug("furb adding $class $file to roots");
$this
->
specialRoots
[
$db
->
parent
]
[
]
= array
(
$class
,
$file
)
;
}
// fix for 591396
if
(
!
$db
->
docblock
->
getExplicitPackage
(
))
{
$a
=
$render
->
proceduralpages
->
pagepackages
[
$file
]
;
if
(
$a
[
0
]
!=
$phpDocumentor_DefaultPackageName
)
{
// inherit page package
$this
->
classesbyfile
[
$file
]
[
$class
]
->
docblock
->
package =
$a
[
0
]
;
}
}
if
(
$this
->
classesbyfile
[
$file
]
[
$class
]
->
docblock
->
package
==
$render
->
proceduralpages
->
pagepackages
[
$file
]
[
0
]
)
{
if
(
$this
->
classesbyfile
[
$file
]
[
$class
]
->
docblock
->
subpackage ==
''
)
{
$this
->
classesbyfile
[
$file
]
[
$class
]
->
docblock
->
subpackage
=
$render
->
proceduralpages
->
pagepackages
[
$file
]
[
1
]
;
}
}
$db
=
$this
->
classesbyfile
[
$file
]
[
$class
]
;
$render
->
addPackageParent
(
$db
)
;
$render
->
addPageIfNecessary
(
$file
,
$db
)
;
if
(
$access
=
$db
->
docblock
->
getKeyword
(
'access'
))
{
if
(
!
is_string
(
$access
)
&&
is_object
(
$access
))
$access
=
$access
->
getString
(
)
;
if
(
!
is_string
(
$access
))
$access
=
'public'
;
if
((
$access
==
'private'
)
&&
(
!
$render
->
parsePrivate
))
{
if
(
isset
(
$this
->
varsbyfile
[
$file
]
)
&& isset
(
$this
->
varsbyfile
[
$file
]
[
$class
]
))
{
foreach
(
$this
->
varsbyfile
[
$file
]
[
$class
]
as
$i
=>
$vr
)
{
$vr
->
docblock
->
addKeyword
(
'access'
,
'private'
)
;
$this
->
varsbyfile
[
$file
]
[
$class
]
[
$i
]
=
$vr
;
}
}
if
(
isset
(
$this
->
methodsbyfile
[
$file
]
)
&& isset
(
$this
->
methodsbyfile
[
$file
]
[
$class
]
))
{
foreach
(
$this
->
methodsbyfile
[
$file
]
[
$class
]
as
$i
=>
$vr
)
{
$vr
->
docblock
->
addKeyword
(
'access'
,
'private'
)
;
$this
->
methodsbyfile
[
$file
]
[
$class
]
[
$i
]
=
$vr
;
}
}
if
(
isset
(
$this
->
constsbyfile
[
$file
]
)
&& isset
(
$this
->
constsbyfile
[
$file
]
[
$class
]
))
{
foreach
(
$this
->
constsbyfile
[
$file
]
[
$class
]
as
$i
=>
$vr
)
{
$vr
->
docblock
->
addKeyword
(
'access'
,
'private'
)
;
$this
->
constsbyfile
[
$file
]
[
$class
]
[
$i
]
=
$vr
;
}
}
}
}
$this
->
classpathpackages
[
$class
]
[
$file
]
= array
(
$db
->
docblock
->
package
,
$db
->
docblock
->
subpackage
)
;
if
(
$db
->
docblock
->
getExplicitPackage
(
))
{
$render
->
proceduralpages
->
addClassPackageToFile
(
$file
,
$db
->
docblock
->
package
,
$db
->
docblock
->
subpackage
)
;
}
$render
->
addElementToPage
(
$db
,
$file
)
;
if
(
isset
(
$this
->
varsbyfile
[
$file
]
)
&& isset
(
$this
->
varsbyfile
[
$file
]
[
$class
]
))
{
foreach
(
$this
->
varsbyfile
[
$file
]
[
$class
]
as
$i
=>
$vr
)
{
$vr
->
docblock
->
package =
$db
->
docblock
->
package
;
$vr
->
docblock
->
subpackage =
$db
->
docblock
->
subpackage
;
$render
->
addElementToPage
(
$vr
,
$file
)
;
$render
->
addUses
(
$vr
,
$file
)
;
$this
->
varsbyfile
[
$file
]
[
$class
]
[
$i
]
=
$vr
;
$this
->
vars
[
$db
->
docblock
->
package
]
[
$class
]
[
$vr
->
getName
(
)
]
=
$vr
;
}
}
if
(
isset
(
$this
->
methodsbyfile
[
$file
]
)
&& isset
(
$this
->
methodsbyfile
[
$file
]
[
$class
]
))
{
foreach
(
$this
->
methodsbyfile
[
$file
]
[
$class
]
as
$i
=>
$vr
)
{
$vr
->
docblock
->
package =
$db
->
docblock
->
package
;
$vr
->
docblock
->
subpackage =
$db
->
docblock
->
subpackage
;
$render
->
addElementToPage
(
$vr
,
$file
)
;
$render
->
addUses
(
$vr
,
$file
)
;
$this
->
methodsbyfile
[
$file
]
[
$class
]
[
$i
]
=
$vr
;
$this
->
methods
[
$db
->
docblock
->
package
]
[
$class
]
[
$vr
->
getName
(
)
]
=
$vr
;
}
}
if
(
isset
(
$this
->
constsbyfile
[
$file
]
)
&& isset
(
$this
->
constsbyfile
[
$file
]
[
$class
]
))
{
foreach
(
$this
->
constsbyfile
[
$file
]
[
$class
]
as
$i
=>
$vr
)
{
$vr
->
docblock
->
package =
$db
->
docblock
->
package
;
$vr
->
docblock
->
subpackage =
$db
->
docblock
->
subpackage
;
$render
->
addElementToPage
(
$vr
,
$file
)
;
$render
->
addUses
(
$vr
,
$file
)
;
$this
->
constsbyfile
[
$file
]
[
$class
]
[
$i
]
=
$vr
;
$this
->
methods
[
$db
->
docblock
->
package
]
[
$class
]
[
$vr
->
getName
(
)
]
=
$vr
;
}
}
$this
->
classpackages
[
$class
]
[
]
= array
(
$db
->
docblock
->
package
,
$db
->
docblock
->
subpackage
)
;
if
(
is_array
(
$db
->
parent
))
$this
->
classparents
[
$db
->
docblock
->
package
]
[
$class
]
=
$db
->
parent
[
1
]
;
else
$this
->
classparents
[
$db
->
docblock
->
package
]
[
$class
]
=
$db
->
getExtends
(
)
;
if
(
is_array
(
$db
->
parent
))
{
$z
=
$this
->
getClass
(
$db
->
parent
[
1
]
,
$db
->
parent
[
0
]
)
;
$this
->
classchildren
[
$z
->
docblock
->
package
]
[
$db
->
parent
[
1
]]
[
]
=
$db
;
}
if
(
isset
(
$this
->
classchildrenbyfile
[
$class
]
))
{
foreach
(
$this
->
classchildrenbyfile
[
$class
]
as
$childfile
=>
$other
)
{
// test 1, inherits in same file (must be same package)
if
(
$childfile
==
$file
)
{
foreach
(
$other
as
$child
=>
$packages
)
{
// debug("parent $class same file $child");
$this
->
processChild
(
$render
,
$child
,
$childfile
)
;
$x
=
$this
->
getClass
(
$child
,
$childfile
)
;
if
(
$x
->
docblock
->
package
!=
$GLOBALS
[
'phpDocumentor_DefaultPackageName'
]
)
{
// child package need root for class trees
if
(
$x
->
docblock
->
package !=
$db
->
docblock
->
package
)
{
// debug("adding $child in $childfile 1");
$this
->
roots
[
$child
]
[
]
=
$childfile
;
}
}
}
}
else
{
// test 2, different file, same package
foreach
(
$other
as
$child
=>
$packages
)
{
for
(
$j
=0
;
$j
<
count
(
$packages
)
;
$j
++
)
{
if
(
$this
->
classesbyfile
[
$file
]
[
$class
]
->
docblock
->
package ==
$packages
[
$j
]
)
{
$this
->
processChild
(
$render
,
$child
,
$childfile
)
;
// debug("$childfile diff file $child, parent $class,
// same package ".$packages[$j]);
}
else
{
/*
* test 3, different file, different package,
* only 1 parent is possible
*/
if
(
isset
(
$this
->
classesbynamefile
[
$child
]
))
{
// 1 possible parent
if
(
count
(
$this
->
classesbynamefile
[
$class
]
)
== 1
)
{
// debug("$childfile diff file $child,
// diff package,
// 1 possible parent root $class");
$this
->
processChild
(
$render
,
$child
,
$childfile
)
;
$x
=
$this
->
getClass
(
$child
,
$childfile
)
;
if
(
$x
->
docblock
->
package
!=
$GLOBALS
[
'phpDocumentor_DefaultPackageName'
]
)
{
// child package need root
//for class trees
if
(
$x
->
docblock
->
package
!=
$db
->
docblock
->
package
)
{
// debug("adding roots
// $child in $childfile 2");
$this
->
roots
[
$child
]
[
]
=
$childfile
;
}
}
}
}
}
}
}
}
}
}
}
/**
* Get the parserClass representation of a class from its name and file
*
*
@param
string
$class
classname
*
@param
string
$file
file classname is located in
*
*
@return
parserClass
*/
function
&
getClass
(
$class
,
$file
)
{
// debug("getClass called with class $class file $file");
return
$this
->
classesbyfile
[
$file
]
[
$class
]
;
}
/**
* Used by
{@link parserData::getClasses()}
* to retrieve classes defined in file $path
*
* retrieves the array entry from
{@link $classesbyfile}
for $path
*
*
@param
string
$path
full path to filename
*
*
@return
mixed
returns false if no classes defined in the file,
* otherwise returns an array of
{@link parserClass}
es
*/
function
getClassesInPath
(
$path
)
{
if
(
!
isset
(
$this
->
classesbyfile
[
$path
]
))
return
false
;
return
$this
->
classesbyfile
[
$path
]
;
}
/**
* called by
{@link parserClass::hasMethods()}
. Should not be directly called
*
*
@param
string
$file
file classname is located in
*
@param
string
$class
classname
*
*
@return
bool
*
@access
private
*/
function
hasMethods
(
$file
,
$class
)
{
return
isset
(
$this
->
methodsbyfile
[
$file
]
[
$class
]
)
;
}
/**
* called by
{@link parserClass::hasConsts()}
.
* Should not be directly called
*
*
@param
string
$file
file classname is located in
*
@param
string
$class
classname
*
*
@return
bool
*
@access
private
*/
function
hasConsts
(
$file
,
$class
)
{
return
isset
(
$this
->
constsbyfile
[
$file
]
[
$class
]
)
;
}
/**
* called by
{@link parserClass::hasVars()}
. Should not be directly called
*
*
@param
string
$file
file classname is located in
*
@param
string
$class
classname
*
*
@return
bool
*
@access
private
*/
function
hasVars
(
$file
,
$class
)
{
return
isset
(
$this
->
varsbyfile
[
$file
]
[
$class
]
)
;
}
/**
* called by
{@link parserClass::hasMethod()}
. Should not be directly called
*
*
@param
string
$class
classname
*
@param
string
$file
file classname is located in
*
@param
string
$name
method name
*
*
@return
bool
*
@access
private
*/
function
hasMethod
(
$class
,
$file
,
$name
)
{
if
(
!
$this
->
hasMethods
(
$file
,
$class
))
return
false
;
for
(
$i
=0
;
$i
<
count
(
$this
->
methodsbyfile
[
$file
]
[
$class
]
)
;
$i
++
)
{
if
(
$this
->
methodsbyfile
[
$file
]
[
$class
]
[
$i
]
->
getName
(
)
==
$name
)
return
true
;
}
return
false
;
}
/**
* called by
{@link parserClass::hasVar()}
. Should not be directly called
*
*
@param
string
$class
classname
*
@param
string
$file
file classname is located in
*
@param
string
$name
var name
*
*
@return
bool
*
@access
private
*/
function
hasVar
(
$class
,
$file
,
$name
)
{
if
(
!
$this
->
hasVars
(
$file
,
$class
))
return
false
;
for
(
$i
=0
;
$i
<
count
(
$this
->
varsbyfile
[
$file
]
[
$class
]
)
;
$i
++
)
{
if
(
$this
->
varsbyfile
[
$file
]
[
$class
]
[
$i
]
->
getName
(
)
==
$name
)
return
true
;
}
return
false
;
}
/**
* called by
{@link parserClass::hasConst()}
. Should not be directly called
*
*
@param
string
$class
classname
*
@param
string
$file
file classname is located in
*
@param
string
$name
constant name
*
*
@return
bool
*
@access
private
*/
function
hasConst
(
$class
,
$file
,
$name
)
{
if
(
!
$this
->
hasConsts
(
$file
,
$class
))
return
false
;
for
(
$i
=0
;
$i
<
count
(
$this
->
constsbyfile
[
$file
]
[
$class
]
)
;
$i
++
)
{
if
(
$this
->
constsbyfile
[
$file
]
[
$class
]
[
$i
]
->
getName
(
)
==
$name
)
return
true
;
}
return
false
;
}
/**
* called by
{@link parserClass::getMethods()}
. Should not be directly called
*
*
@param
string
$class
classname
*
@param
string
$file
file classname is located in
*
*
@return
mixed
*
@access
private
*/
function
&
getMethods
(
$class
,
$file
)
{
if
(
!
isset
(
$this
->
methodsbyfile
[
$file
]
[
$class
]
))
{
$flag
= false
;
return
$flag
;
}
return
$this
->
methodsbyfile
[
$file
]
[
$class
]
;
}
/**
* called by
{@link parserClass::getVars()}
. Should not be directly called
*
*
@param
string
$class
classname
*
@param
string
$file
file classname is located in
*
*
@return
mixed
*
@access
private
*/
function
&
getVars
(
$class
,
$file
)
{
if
(
!
isset
(
$this
->
varsbyfile
[
$file
]
[
$class
]
))
{
$flag
= false
;
return
$flag
;
}
return
$this
->
varsbyfile
[
$file
]
[
$class
]
;
}
/**
* called by
{@link parserClass::getConsts()}
. Should not be directly called
*
*
@param
string
$class
classname
*
@param
string
$file
file classname is located in
*
*
@return
mixed
*
@access
private
*/
function
&
getConsts
(
$class
,
$file
)
{
if
(
!
isset
(
$this
->
constsbyfile
[
$file
]
[
$class
]
))
{
$flag
= false
;
return
$flag
;
}
return
$this
->
constsbyfile
[
$file
]
[
$class
]
;
}
/**
* called by
{@link parserClass::getMethod()}
. Should not be directly called
*
*
@param
string
$class
classname
*
@param
string
$file
file classname is located in
*
@param
string
$name
method name
*
*
@return
mixed
*
@access
private
*/
function
getMethod
(
$class
,
$file
,
$name
)
{
if
(
!
$this
->
hasMethod
(
$class
,
$file
,
$name
))
return
false
;
for
(
$i
=0
;
$i
<
count
(
$this
->
methodsbyfile
[
$file
]
[
$class
]
)
;
$i
++
)
{
if
(
$this
->
methodsbyfile
[
$file
]
[
$class
]
[
$i
]
->
getName
(
)
==
$name
)
return
$this
->
methodsbyfile
[
$file
]
[
$class
]
[
$i
]
;
}
}
/**
* called by
{@link parserClass::getVar()}
. Should not be directly called
*
*
@param
string
$class
classname
*
@param
string
$file
file classname is located in
*
@param
string
$name
var name
*
*
@return
mixed
*
@access
private
*/
function
getVar
(
$class
,
$file
,
$name
)
{
if
(
!
$this
->
hasVar
(
$class
,
$file
,
$name
))
return
false
;
for
(
$i
=0
;
$i
<
count
(
$this
->
varsbyfile
[
$file
]
[
$class
]
)
;
$i
++
)
{
if
(
$this
->
varsbyfile
[
$file
]
[
$class
]
[
$i
]
->
getName
(
)
==
$name
)
return
$this
->
varsbyfile
[
$file
]
[
$class
]
[
$i
]
;
}
}
/**
* called by
{@link parserClass::getConst()}
. Should not be directly called
*
*
@param
string
$class
classname
*
@param
string
$file
file classname is located in
*
@param
string
$name
const name
*
*
@return
mixed
*
@access
private
*/
function
getConst
(
$class
,
$file
,
$name
)
{
if
(
!
$this
->
hasConst
(
$class
,
$file
,
$name
))
return
false
;
for
(
$i
=0
;
$i
<
count
(
$this
->
constsbyfile
[
$file
]
[
$class
]
)
;
$i
++
)
{
if
(
$this
->
constsbyfile
[
$file
]
[
$class
]
[
$i
]
->
getName
(
)
==
$name
)
return
$this
->
constsbyfile
[
$file
]
[
$class
]
[
$i
]
;
}
}
/**
* Search for a class in a package
*
*
@param
string
$class
classname
*
@param
string
$package
package classname is in
*
*
@return
mixed
returns false if no class in $package,
* otherwise returns a
{@link parserClass}
*/
function
&
getClassByPackage
(
$class
,
$package
)
{
if
(
!
isset
(
$this
->
classesbynamefile
[
$class
]
))
{
// removed, too many warnings, not very useful
// addWarning(PDERROR_CLASS_NOT_IN_PACKAGE,$class,$package);
$flag
= false
;
return
$flag
;
}
for
(
$i
=0
;
$i
<
count
(
$this
->
classesbynamefile
[
$class
]
)
;
$i
++
)
{
$cls
=
$this
->
classesbyfile
[
$this
->
classesbynamefile
[
$class
]
[
$i
]]
[
$class
]
;
$pkg
=
$cls
->
getPackage
(
)
;
if
(
$pkg
==
$package
)
return
$cls
;
}
// addWarning(PDERROR_CLASS_NOT_IN_PACKAGE,$class,$package);
$flag
= false
;
return
$flag
;
}
/**
* Find the parent class of a class in file $file
* uses 3 tests to find the parent classname:
* <ol>
* <li>only one class with the parent classname</li>
* <li>more than one class, but only one in the same file as the child</li>
* <li>only one parent class in the same package as the child</li>
* </ol>
*
*
@param
string
$class
classname
*
@param
string
$file
file classname is located in
*
*
@return
mixed
false if no parent class,
* a string if no parent class found by that name,
* and an array(file parentclass is in, parentclassname)
*/
function
getParentClass
(
$class
,
$file
)
{
if
(
!
isset
(
$this
->
classesbyfile
[
$file
]
[
$class
]
))
{
return
false
;
}
$element
=
$this
->
classesbyfile
[
$file
]
[
$class
]
;
if
(
!
(
$ex
=
$element
->
getExtends
(
)))
return
false
;
// first check to see if there is one and only one
// class with the parent class's name
if
(
isset
(
$this
->
classesbynamefile
[
$ex
]
))
{
if
(
count
(
$this
->
classesbynamefile
[
$ex
]
)
== 1
)
{
if
(
$this
->
classesbyfile
[
$this
->
classesbynamefile
[
$ex
]
[
0
]]
[
$ex
]
->
ignore
)
{
return
$ex
;
}
return
array
(
$this
->
classesbynamefile
[
$ex
]
[
0
]
,
$ex
)
;
}
else
{
// next check to see if there is a parent class in the same file
if
(
isset
(
$this
->
classesbyfile
[
$file
]
[
$ex
]
))
{
if
(
$this
->
classesbyfile
[
$file
]
[
$ex
]
->
ignore
)
{
return
$ex
;
}
return
array
(
$file
,
$ex
)
;
}
// next check to see if there is only one package
// used in the file, try to resolve it that way
if
(
isset
(
$this
->
classpackagebyfile
[
$file
]
))
{
if
(
count
(
$this
->
classpackagebyfile
[
$file
]
)
== 1
)
{
for
(
$i
=0
;
$i
<
count
(
$this
->
classesbynamefile
[
$ex
]
)
;
$i
++
)
{
if
(
$this
->
classesbyfile
[
$this
->
classesbynamefile
[
$ex
]
[
$i
]]
[
$ex
]
->
getPackage
(
)
==
$this
->
classpackagebyfile
[
$file
]
[
0
]
)
{
if
(
$this
->
classesbyfile
[
$this
->
classesbynamefile
[
$ex
]
[
$i
]]
[
$ex
]
->
ignore
)
return
$ex
;
return
array
(
$this
->
classesbynamefile
[
$ex
]
[
$i
]
,
$ex
)
;
}
}
}
}
// name conflict
addWarning
(
PDERROR_INHERITANCE_CONFLICT
,
$class
,
$file
,
$ex
)
;
return
$ex
;
}
}
else
{
if
(
class_exists
(
'ReflectionClass'
)
&&
class_exists
(
$ex
))
{
$r
= new ReflectionClass
(
$ex
)
;
if
(
$r
->
isInternal
(
))
{
return
$ex
;
// no warning
}
}
addWarning
(
PDERROR_PARENT_NOT_FOUND
,
$class
,
$ex
)
;
return
$ex
;
}
}
/**
* Get a list of all root classes indexed by package. Used to generate
* class trees by
{@link Converter}
*
*
@param
boolean
$all
[since phpDocumentor 1.3.0RC6] determines whether to
* return class trees that extend non-parsed classes
*
*
@return
array
array(package => array(rootclassname, rootclassname,...),...)
*/
function
getRoots
(
$all
= false
)
{
$roots
= array
(
)
;
$temproots
=
$this
->
roots
;
if
(
!
$all
)
{
foreach
(
$this
->
specialRoots
as
$package
=>
$root
)
{
foreach
(
$root
as
$parent
=>
$info
)
{
$temproots
[
$info
[
0
]]
[
]
=
$info
[
1
]
;
}
}
}
foreach
(
$temproots
as
$class
=>
$files
)
{
if
(
count
(
$files
))
{
foreach
(
$files
as
$i
=>
$boofou
)
{
$x
=
$this
->
getClass
(
$class
,
$files
[
$i
]
)
;
$roots
[
$x
->
getPackage
(
)
]
[
]
=
$class
;
}
}
}
foreach
(
$roots
as
$package
=>
$root
)
{
usort
(
$roots
[
$package
]
,
"strnatcasecmp"
)
;
}
if
(
$all
)
{
$specialRoots
= array
(
)
;
foreach
(
$this
->
specialRoots
as
$parent
=>
$classinfo
)
{
if
(
count
(
$classinfo
))
{
foreach
(
$classinfo
as
$i
=>
$info
)
{
$x
=
$this
->
getClass
(
$info
[
0
]
,
$info
[
1
]
)
;
$specialRoots
[
$x
->
getPackage
(
)
]
[
$parent
]
[
]
=
$info
[
0
]
;
}
}
}
foreach
(
$specialRoots
as
$package
=>
$root
)
{
uksort
(
$specialRoots
[
$package
]
,
"strnatcasecmp"
)
;
foreach
(
$specialRoots
[
$package
]
as
$parent
=>
$classes
)
{
usort
(
$specialRoots
[
$package
]
[
$parent
]
,
'strnatcasecmp'
)
;
}
}
return
array
(
'special'
=>
$specialRoots
,
'normal'
=>
$roots
)
;
}
return
$roots
;
}
/**
* Get all classes confirmed in parsing
* to be descended class $parclass in file $file
*
*
@param
string
$parclass
name of parent class
*
@param
string
$file
file parent class is found in
*
*
@return
mixed
either false if no children, or array of format
* array(childname => childfile,childname2 => childfile2,...)
*
@see
parserClass::getChildClassList()
*
@uses
$definitechild
*/
function
getDefiniteChildren
(
$parclass
,
$file
)
{
if
(
isset
(
$this
->
definitechild
[
$parclass
]
[
$file
]
))
return
$this
->
definitechild
[
$parclass
]
[
$file
]
;
return
false
;
}
}
?>
Documentation generated on Mon, 05 Dec 2011 21:25:03 -0600 by
phpDocumentor 1.4.4