The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Devel::PerlySense::Document - A Perl file/document

SYNOPSIS

DESCRIPTION

The document contains a PPI parsed document, etc. along with a metadata object.

Caching

Caching is done on a per file + mod timestamp basis. Things that are cached are: PPI documents, Document::Api and Document::Meta objects.

Currently Cache::Cache is used. This isn't great (duh), since there is no good way to expire obsolete files.

PROPERTIES

oPerlySense

Devel::PerlySense object.

Default: set during new()

file

The absolute file name of the parsed file, or "" if none was parsed.

Default: ""

oDocument

The PPI::Document object from the parse(), or undef if none was parsed.

Default: undef

oMeta

The Devel::PerlySense::Document::Meta object from the parse(), or undef if none was parsed.

Default: undef

rhPackageApiLikely

Hash ref with (keys: package names; Document::Api objects).

Default: {}

API METHODS

new(oPerlySense => $oPerlySense)

Create new PearlySense::Document object. Associate it with $oPerlySense.

fileFindModule(nameModule => $nameModule)

Find the file containing the $nameModule given the file property of the document.

Return the absolute file name, or undef if none could be found. Die on errors.

parse(file => $file)

Parse the $file and store the metadata.

Return 1 on success, else die.

Cached on the usual.

parse0(file => $file)

Parse the $file and store the metadata.

Return 1 on success, else die.

aNamePackage()

Return list of package names in this document.

aNameBase()

Return list of names of modules that are base classes, according to either "use base" or an assignment to @ISA.

Dir on errors.

hasBaseClass($nameClass)

Return true if $nameClass is an immediate base class to this one, else false.

aNameModuleUse()

Find modules that are used in this document.

Don't find pragmas. Don't find very common infrastructure modules. Only report modules used in this actual document.

Return list of unique module names.

Dir on errors.

packageAt(row => $row)

Return the package name that is active on line $row (1..), or die on errors.

isEmptyAt(row => $row, col => $col)

Determine whether the position at $row, $col is empty (ther is no known content, no:

  modules
  methods
  variables?

).

Return 1 if empty, else 0.

Die on errors.

moduleAt(row => $row, col => $col)

Find the module mentioned on line $row (1..) at $col (1..). Don't recognize modules that isn't ucfirst(). There may be false positives, if it looks like a module. (examples?)

Return string like "My::Module" or "Module", or undef if none was found.

Die on errors.

methodCallAt(row => $row, col => $col)

Return the method call Perl code is on line $row (1..) at $col (1..), or die on errors.

In scalar context, return string like "$self->fooBar". Don't include the parameter list or parens, only the "$object->method".

In list context, return two item list with (object, method).

The object may be undef/"" if it's an expression rather than a simple variable.

Return undef or () if none was found. Die on errors.

selfMethodCallAt(row => $row, row => $col)

Return the name of the $self->method at $row, $col in this document.

If no method call is found, maybe warn and return undef.

Die on errors.

moduleMethodCallAt(row => $row, row => $col)

Find the My::Module->method call at $row, $col in this document.

In list context, return two item list with (module, method). In scalar context, return "My::Module->method".

Return undef or () if none was found. Die on errors.

aObjectMethodCallAt(row => $row, row => $col)

Return three item array with (object name, method name, $oLocation of the surrounding sub) of the $self->method at $row, $col in this document. The object may be '$self'.

If no method call is found, maybe warn and return ().

Die on errors.

rhRegexExample(row => $row, col => $col)

Look in $file at location $row/$col and find the regex located there, and possibly the example comment preceeding it.

Return hash ref with (keys: regex, example; values: source string). The source string is an empty string if nothing found.

If there is an example string in a comment, return the example without the comment #

Die if $file doesn't exist, or on other errors.

oLocationSub(name => $name, [package => "main"])

Return a Devel::PerlySense::Document::Location object with the location of the sub declaration called $name in $package, or undef if it wasn't found.

Die on errors.

oLocationSubAt(row => $row, col => $col)

Return a Devel::PerlySense::Document::Location object with the location of the sub definition at $row/$col, or undef if it row/col isn't inside a sub definition.

Note: Currently, col is ignored, and the sub is presumed to occupy the entire row.

Die on errors.

oLocationSubDefinition(name => $name, [row => $row], [package => $package])

Return a Devel::PerlySense::Document::Location object with the location of the sub "definition" for $name, or undef if it wasn't found. The definition can be the sub declaration, or a POD entry.

If $row is passed, use it to determine which package is active at $row. If $package is passed, use that instead. Default to package "main" if neither is passed.

If no definition can be found in this document, and the module has one or more base classes, look in the @ISA (depth-first, just like Perl (see perldoc perltoot)).

Warn on some failures to find the location. Die on errors.

oLocationPod(name => $name, lookFor => $lookFor, [ignoreBaseModules => 0])

Return a Devel::PerlySense::Document::Location object with the "best" location of the pod =head? or =item where $name is present, or undef if it wasn't found.

$lookFor can be "method", i.e. what the search was looking for.

If $lookFor is "method" and the POD isn't found, try in the base classes, unless $ignoreBaseModules is true.

If the method POD is found in a base class, make sure that notice is in the rhProperty->{pod} (once).

Set the rhProperty keys of the Location:

  found - $lookFor
  docType - "hint"
  name - the $name
  pod - the POD describing $name (includes podSection)
  podSection - the POD section the name is located in

Die on errors.

aMethodCallOf(nameObject => $nameObject, oLocationWithin => $oLocationWithin)

Find all the method calls of $nameObject in the $oLocationWithin.

Shortcut: assume the $oLocationWithin is the entire interesting scope. Ignore morons who re-define their vars in inner scopes with a different type. If this turns out to be a problem, fix the problem then. Or smack them over the head with a trout.

Return sorted array with the method names called.

Die on errors.

determineLikelyApi(nameModule => $nameModule)

Look in the document for sub declarations, $self->method calls, and $self->{hash_key} in order to determine what is the likely API of the packages of this document. Focus on the $nameModule and its base classes.

Set the rhPackageApiLikely property with new Devel::PerlySense::Document::Api objects for each package.

Return 1 on success. Die on errors.

Cached on the usual + $nameModule.

determineLikelyApi0(nameModule => $nameModule)

Implementation for determineLikelyApi()

mergePackageApiWithBase(nameModule => $nameModule, rhPackageApi => $rhPackageApi, nameModuleBase => $nameModuleBase, rhPackageApiBase => $rhPackageApiBase)

Merge the $rhPackageApiBase of the base class with the existing $rhPackageApi. Modify $rhPackageApi.

Only merge the API of the $nameModule.

Document::Api objects are cloned, not reused, but individual Document::Location objects may be shared between documents and apis.

Return 1 on success, or 0 if the package wasn't found. Die on errors.

scoreInterfaceMatch(nameModule => $nameModule, raMethodRequired => $raMethodRequired, raMethodNice => $raMethodNice)

Rate the interface match between the document and the wanted interface of the method names in $raMethodRequired + $raMethodNice.

If not all method names in $raMethodRequired are supported, the score is 0, and this document should not be considered to support the requirements.

The score is calculated like this:

 % of ($raMethod*) that is supported, except
 all required must be there.

 +

 % of the api that consists of $raMethod*. This will favour smaller
 interfaces in base classes.

Return score on success. Die on errors.

stringSignatureSurveyFromFile()

Calculate a Signature Survey string for the source in the document.

Return the string. Die on errors.

stringSignatureSurveyFromSource($stringSource)

Calculate a Signature Survey string for the $stringSource, based on the idea in http://c2.com/doc/SignatureSurvey/ .

The idea is not to get an exact representation of the source but a good feel for what it contains.

Return the survey string. Die on errors.

IMPLEMENTATION METHODS

oLocationOfNode($oNode, [$extraRow = 0, $extraCol = 0])

Return Devel::PerlySense::Document::Location object for $oNode.

If $extraRow or $extraCol are passed, add that to the location.

aDocumentFind($what)

Convenience wrapper around $self->$oDocument->find($what) to account for the unusable api.

Return list of matching nodes, or an empty list if none was found.

aNodeFind($oNode, $what)

Convenience wrapper around $oNode->find($what) to account for the unusable api.

Return list of matching nodes, or an empty list if none was found.

oLocationEnclosingSub($oNode)

Return a Document::Location object that is the enclosing sub of $oNode, i.e. $oNode is located within the sub block. The Location object has the following rhProperty keys:

  nameSub
  source
  oLocationEnd with: row and col

Return Location object with the sub, or undef if none was found. Die on errors.

CACHE METHODS

cacheSet($key, $file, $rValue)

If a cache is active, store the $value in the cache under the total key of ($file, $file's timestamp, $key).

$value should be a scalar or reference which can be freezed.

$file must be an existing file.

Return 1 if the $value was stored, else 0. Die on errors.

cacheGet($key, $file)

If a cache is active, get the value in the cache under the total key of ($file, $file's timestamp, $key).

$file must be an existing file.

Return the value, or undef if the value could not be fetched. Die on errors.

AUTHOR

Johan Lindström, <johanl[ÄT]DarSerMan.com>

BUGS

Please report any bugs or feature requests to bug-devel-perlysense@rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Devel-PerlySense. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

ACKNOWLEDGEMENTS

COPYRIGHT & LICENSE

Copyright 2005 Johan Lindström, All Rights Reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

1 POD Error

The following errors were encountered while parsing the POD:

Around line 1163:

Non-ASCII character seen before =encoding in 'Lindström,'. Assuming CP1252