diff --git a/docs/checkers_doc.md b/docs/checkers_doc.md index 166416b1..bb31729b 100644 --- a/docs/checkers_doc.md +++ b/docs/checkers_doc.md @@ -4,7 +4,7 @@ | Total checks | Checks enabled by default | Disabled checks by default | Autofixable checks | | ------------ | ------------------------- | -------------------------- | ------------------ | -| 104 | 86 | 18 | 14 | +| 105 | 87 | 18 | 14 | ## Table of contents - Enabled by default @@ -75,6 +75,7 @@ - [`stdInterface` checker](#stdinterface-checker) - [`strangeCast` checker](#strangecast-checker) - [`strictCmp` checker](#strictcmp-checker) + - [`stringInterpolationDeprecated` checker](#stringinterpolationdeprecated-checker) - [`stripTags` checker](#striptags-checker) - [`switchEmpty` checker](#switchempty-checker) - [`switchSimplify` checker](#switchsimplify-checker) @@ -1183,7 +1184,7 @@ interface Iface { #### Description -Report not nullable param can be null. +Report not nullable param with explicit null default value. #### Non-compliant code: ```php @@ -1471,6 +1472,24 @@ in_array("what", $s, true)


+### `stringInterpolationDeprecated` checker + +#### Description + +Report deprecated string interpolation style + +#### Non-compliant code: +```php +${variable} +``` + +#### Compliant code: +```php +{$variable} +``` +


+ + ### `stripTags` checker #### Description diff --git a/src/linter/block_linter.go b/src/linter/block_linter.go index 3f6cbd4f..11e11b2e 100644 --- a/src/linter/block_linter.go +++ b/src/linter/block_linter.go @@ -24,6 +24,10 @@ type blockLinter struct { func (b *blockLinter) enterNode(n ir.Node) { switch n := n.(type) { + + case *ir.Encapsed: + b.checkStringInterpolationDeprecation(n) + case *ir.Assign: b.checkAssign(n) @@ -207,6 +211,18 @@ func (b *blockLinter) enterNode(n ir.Node) { } } +func (b *blockLinter) checkStringInterpolationDeprecation(str *ir.Encapsed) { + for _, item := range str.Parts { + variable, ok := item.(*ir.SimpleVar) + if ok { + if variable.IdentifierTkn.Value[0] != '$' { + b.report(str, LevelWarning, "stringInterpolationDeprecated", "use {$variable} instead ${variable}") + break + } + } + } +} + func (b *blockLinter) checkUnaryPlus(n *ir.UnaryPlusExpr) { val := constfold.Eval(b.classParseState(), n.Expr) if val.IsValid() { diff --git a/src/linter/report.go b/src/linter/report.go index b36363b9..97ad85b7 100644 --- a/src/linter/report.go +++ b/src/linter/report.go @@ -618,6 +618,15 @@ g();`, }`, }, + { + Name: "stringInterpolationDeprecated", + Default: true, + Quickfix: false, + Comment: `Report deprecated string interpolation style`, + Before: `${variable}`, + After: `{$variable}`, + }, + { Name: "misspellName", Default: true, diff --git a/src/tests/checkers/string_interpolation_test.go b/src/tests/checkers/string_interpolation_test.go new file mode 100644 index 00000000..3f895203 --- /dev/null +++ b/src/tests/checkers/string_interpolation_test.go @@ -0,0 +1,50 @@ +package checkers + +import ( + "testing" + + "github.com/VKCOM/noverify/src/linttest" +) + +func TestInterpolationDeprecated1(t *testing.T) { + test := linttest.NewSuite(t) + test.AddFile(`