Page MenuHomePhabricator

Allow getXHPASTTreeForPath to return the tree for an arbitrary path
ClosedPublic

Authored by joshuaspence on Apr 4 2015, 3:58 AM.
Tags
None
Referenced Files
Unknown Object (File)
Sat, Apr 20, 5:09 PM
Unknown Object (File)
Fri, Apr 19, 5:25 AM
Unknown Object (File)
Thu, Apr 11, 9:07 AM
Unknown Object (File)
Fri, Mar 29, 10:49 PM
Unknown Object (File)
Feb 18 2024, 10:51 PM
Unknown Object (File)
Feb 8 2024, 3:15 PM
Unknown Object (File)
Jan 11 2024, 9:35 PM
Unknown Object (File)
Jan 10 2024, 9:36 AM
Subscribers

Details

Summary

This allows ArcanistBaseXHPASTLinter::getXHPASTTreeForPath to return the parse tree for a file that wasn't explicitly linted. In my particular use case, I am writing a linter rule to determine if it is necessary to import a PHP file with require_once (i.e. the file consists only of class/interface definitions which are autoloadable).

Test Plan

Tested externally using a custom linter.

Diff Detail

Repository
rARC Arcanist
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

joshuaspence retitled this revision from to Fix a minor issue with getXHPASTTreeForPath.
joshuaspence updated this object.
joshuaspence edited the test plan for this revision. (Show Details)
joshuaspence added a reviewer: epriestley.
joshuaspence retitled this revision from Fix a minor issue with getXHPASTTreeForPath to Allow getXHPASTTreeForPath to return the tree for an arbitrary path.Apr 4 2015, 4:54 AM
joshuaspence updated this object.
joshuaspence edited the test plan for this revision. (Show Details)
joshuaspence edited edge metadata.
epriestley edited edge metadata.

I don't love this because it's slower than parallelizing, the cost is hidden and implicit (similar looking code may have dramatically different costs), and it makes fixing the memory behavior in a solid way (e.g., T5097) much more difficult.

I'd accept an explicit method to add a tree (if such a method does not already exist).

In an ideal world, I'd guess the structure you probably want is something like:

  • a cache on disk of <hash(content) -> is purely autoloadable>, which is tiny/fast/not meaningfully memory constrained;
  • a getAllCacheEntriesForTheseFiles($list_of_paths) which builds missing cache entries in parallel, then throws away the trees, so it runs in roughly constant memory;
  • a linter which looks like:
    • get all includes in a file;
    • batch lookup in the cache;
    • ok good.

This is trickier if you also want to evaluate includes for includes (e.g., if an included file is autoloadable except for includes, but those are also autoloadable, mark the file as autoloadable), but in theory you don't really need to do that since you can just keep running the linter and removing unnecessary includes over and over again to end up in the same place.

This revision now requires changes to proceed.Apr 6 2015, 1:18 PM
joshuaspence edited edge metadata.

OK, how about this... if you call getXHPASTTreeForPath for a path that we don't have an ExecFuture for then we return null. Then, in my calling code I can do this:

$tree = $this->getXHPASTTreeForPath($path);

if (!$tree) {
  $this->buildSharedFutures(array($path));
  $tree = $this->getXHPASTTreeForPath($path);
}

Which can be simplified to:

$this->buildSharedFutures(array($path));
$tree = $this->getXHPASTTreeForPath($path);

Which means that I don't actually require this diff (although return null seems nice anyway)

epriestley edited edge metadata.
epriestley added inline comments.
src/lint/linter/ArcanistBaseXHPASTLinter.php
171–172

We should probably do the second check before this line. Otherwise, calling this method prevents a future from being built later, I think.

This revision is now accepted and ready to land.May 19 2015, 3:11 PM

And possibly this should be some kind of, like, throw new YouDidntAskForThatPathToBeBuilt thing.

joshuaspence edited edge metadata.

Move conditional as requested

This revision was automatically updated to reflect the committed changes.