phpgrep

package
v0.5.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 23, 2022 License: MIT, MIT Imports: 11 Imported by: 0

README

phpgrep

Go Report Card GoDoc Build Status

TODO: clarify that this is a customized for integration fork of the phpgrep.

Syntax-aware grep for PHP code.

This repository is used for the library and command-line tool development. A good source for additional utilities and ready-to-run recipes is phpgrep-contrib repository.

Overview

phpgrep is both a library and a command-line tool.

Library can be used to perform syntax-aware PHP code matching inside Go programs while binary utility can be used from your favorite text editor or terminal emulator.

It's very close to structural search and replace in PhpStorm, but better suited for standalone usage.

In many ways, inspired by github.com/mvdan/gogrep/.

See also: "phpgrep: syntax aware code search".

Quick start

To install phpgrep binary under your $(go env GOPATH)/bin:

go get -v github.com/quasilyte/phpgrep/cmd/phpgrep

If $GOPATH/bin is under your system $PATH, phpgrep command should be available after that.
This should print the help message:

$ phpgrep -help
Usage: phpgrep [flags...] target pattern [filters...]
Where:
  flags are command-line flags that are listed in -help (see below)
  target is a file or directory name where search is performed
  pattern is a string that describes what is being matched
  filters are optional arguments bound to the pattern

Examples:
  # Find f calls with a single variable argument.
  phpgrep file.php 'f(${"var"})'
  # Like previous example, but searches inside entire
  # directory recursively and variable names are restricted
  # to $id, $uid and $gid.
  # Also uses -v flag that makes phpgrep output more info.
  phpgrep -v ~/code/php 'f(${"x:var"})' 'x=id,uid,gid'

Exit status:
  0 if something is matched
  1 if nothing is matched
  2 if error occured

# ... rest of output

Create a test file hello.php:

<?php
function f(...$xs) {}
f(10);
f(20);
f(30);
f($x);
f();

Run phpgrep over that file:

# phpgrep hello.php 'f(${"x:int"})' 'x!=20'
hello.php:3: f(10)
hello.php:5: f(30)

We found all f calls with a single argument x that is int literal not equal to 20.

Next thing to learn is ${"*"} matcher.

Suppose you need to match all foo function calls that have null argument.
foo is variadic, so it's unknown where that argument can be located.

This pattern will match null arguments at any position: foo(${"*"}, null, ${"*"}).

Read pattern language docs to learn more about how to write search patterns.

Recipes

This section contains ready-to-use phpgrep patterns.

srcdir is a target source directory (can also be a single filename).

Useful recipes
# Find arrays with at least 1 duplicated key.
$ phpgrep srcdir '[${"*"}, $k => $_, ${"*"}, $k => $_, ${"*"}]'

# Find where ?: can be applied.
$ phpgrep srcdir '$x ? $x : $y' # Use `$x ?: $y` instead

# Find potential operator precedence issues.
$ phpgrep srcdir '$x & $mask == $y' # Should be ($x & $mask) == $y
$ phpgrep srcdir '$x & $mask != $y' # Should be ($x & $mask) != $y

# Find calls where func args are misplaced.
$ phpgrep srcdir 'stripos(${"str"}, $_)'
$ phpgrep srcdir 'explode($_, ${"str"}, ${"*"})

# Find new calls without parentheses.
$ phpgrep srcdir 'new $t'

# Find all if statements with a body without {}.
$ phpgrep srcdir 'if ($cond) $x' 'x!~^\{'
# Or without regexp.
$ phpgrep srcdir 'if ($code) ${"expr"}'

# Find all error-supress operator usages.
$ phpgrep srcdir '@$_'
Miscellaneous recipes
# Find all function calls that have at least one var-argument that has _id suffix.
$ phpgrep srcdir '$f(${"*"}, ${"x:var"}, ${"*"})' 'x~.*_id$'

Documentation

Overview

Package phpgrep is a library for searching PHP code using syntax trees.

Inspired by mvdan/gogrep.

TODO(quasilyte): add the actual overview.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CapturedNode added in v0.3.0

type CapturedNode struct {
	Name string
	Node ir.Node
}

type Compiler

type Compiler struct {
	// CaseSensitive option specifies whether compiled patterns
	// should match identifiers in a strictly case-sensitive manner.
	//
	// In PHP, f() and F() refer to the same function `f`, but if
	// case sensitivity is set to true, compiled matcher will reject
	// any spelling mismatches.
	CaseSensitive bool

	// FuzzyMatching enables some forms of normalization to the
	// pattern so `[$x]` matches `array($x)` too.
	FuzzyMatching bool
}

Compiler creates matcher objects out of the string patterns.

func (*Compiler) Compile

func (c *Compiler) Compile(pattern []byte) (*Matcher, error)

Compile compiler a given pattern into a matcher.

type MatchData

type MatchData struct {
	Node    ir.Node
	Capture []CapturedNode
}

func (MatchData) CapturedByName added in v0.3.0

func (data MatchData) CapturedByName(name string) (ir.Node, bool)

type Matcher

type Matcher struct {
	// contains filtered or unexported fields
}

Matcher is a compiled pattern that can be used for PHP code search.

func (*Matcher) Clone

func (m *Matcher) Clone() *Matcher

Clone returns a deep copy of m.

func (*Matcher) Match

func (m *Matcher) Match(n ir.Node) (MatchData, bool)

Match attempts to match n without recursing into it.

Returned match data should only be examined if the second return value is true.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL