From cc1247e46c0fc8d155d91697c280f212fcc32f74 Mon Sep 17 00:00:00 2001 From: Denis Krivak <dokrivak@avito.ru> Date: Mon, 2 Nov 2020 21:54:03 +0300 Subject: [PATCH] Add replacements for non-capital letters in sentences. --- checks.go | 25 +++++-- coverage.txt | 153 +++++++++++++++++++++++++++++++++++++++ godot_test.go | 83 +++++++++++++++------ testdata/check/README.md | 21 ++++-- testdata/check/main.go | 41 ++++++----- testdata/get/README.md | 13 ++-- 6 files changed, 278 insertions(+), 58 deletions(-) create mode 100644 coverage.txt diff --git a/checks.go b/checks.go index 043d423..e675da6 100644 --- a/checks.go +++ b/checks.go @@ -1,7 +1,6 @@ package godot import ( - "fmt" "go/token" "regexp" "strings" @@ -88,9 +87,12 @@ func checkCommentForPeriod(fset *token.FileSet, c comment) *Issue { // attached lines. Use `iss.Pos.Column` because it's a position in // the original line. original := []rune(c.lines[pos.line-1]) - iss.Replacement = fmt.Sprintf("%s.%s", - string(original[:iss.Pos.Column-1]), - string(original[iss.Pos.Column-1:])) + iss.Replacement = string(original[:iss.Pos.Column-1]) + "." + + string(original[iss.Pos.Column-1:]) + + // Save replacement to raw lines to be able to combine it with + // further replacements + c.lines[pos.line-1] = iss.Replacement return &iss } @@ -117,7 +119,7 @@ func checkCommentForCapital(fset *token.FileSet, c comment) []Issue { pos.column += 2 } - issues[i] = Issue{ + iss := Issue{ Pos: token.Position{ Filename: start.Filename, Offset: start.Offset, @@ -127,7 +129,18 @@ func checkCommentForCapital(fset *token.FileSet, c comment) []Issue { Message: noCapitalMessage, } - // TODO: Make a replacement + // Make a replacement. Use `pos.line` to get an original line from + // attached lines. Use `iss.Pos.Column` because it's a position in + // the original line. + rep := []rune(c.lines[pos.line-1]) + rep[iss.Pos.Column-1] = unicode.ToTitle(rep[iss.Pos.Column-1]) + iss.Replacement = string(rep) + + // Save replacement to raw lines to be able to combine it with + // further replacements + c.lines[pos.line-1] = iss.Replacement + + issues[i] = iss } return issues diff --git a/coverage.txt b/coverage.txt new file mode 100644 index 0000000..9b0b593 --- /dev/null +++ b/coverage.txt @@ -0,0 +1,153 @@ + +mode: atomic +github.com/tetafro/godot/checks.go:35.88,37.29 2 10 +github.com/tetafro/godot/checks.go:54.2,54.15 1 10 +github.com/tetafro/godot/checks.go:37.29,38.43 1 209 +github.com/tetafro/godot/checks.go:42.3,42.22 1 207 +github.com/tetafro/godot/checks.go:48.3,48.23 1 207 +github.com/tetafro/godot/checks.go:38.43,39.12 1 2 +github.com/tetafro/godot/checks.go:42.22,43.57 1 207 +github.com/tetafro/godot/checks.go:43.57,45.5 1 93 +github.com/tetafro/godot/checks.go:48.23,49.60 1 207 +github.com/tetafro/godot/checks.go:49.60,51.5 1 21 +github.com/tetafro/godot/checks.go:59.67,66.8 4 207 +github.com/tetafro/godot/checks.go:71.2,72.44 2 93 +github.com/tetafro/godot/checks.go:76.2,97.13 5 93 +github.com/tetafro/godot/checks.go:66.8,68.3 1 114 +github.com/tetafro/godot/checks.go:72.44,74.3 1 87 +github.com/tetafro/godot/checks.go:103.69,110.18 4 207 +github.com/tetafro/godot/checks.go:114.2,115.25 2 21 +github.com/tetafro/godot/checks.go:146.2,146.15 1 21 +github.com/tetafro/godot/checks.go:110.18,112.3 1 186 +github.com/tetafro/godot/checks.go:115.25,118.45 2 21 +github.com/tetafro/godot/checks.go:122.3,143.18 6 21 +github.com/tetafro/godot/checks.go:118.45,120.4 1 15 +github.com/tetafro/godot/checks.go:152.58,157.39 4 226 +github.com/tetafro/godot/checks.go:167.2,167.12 1 226 +github.com/tetafro/godot/checks.go:171.2,171.32 1 185 +github.com/tetafro/godot/checks.go:175.2,176.19 2 98 +github.com/tetafro/godot/checks.go:157.39,159.17 2 288 +github.com/tetafro/godot/checks.go:162.3,164.8 3 185 +github.com/tetafro/godot/checks.go:159.17,160.12 1 103 +github.com/tetafro/godot/checks.go:167.12,169.3 1 41 +github.com/tetafro/godot/checks.go:171.32,173.3 1 87 +github.com/tetafro/godot/checks.go:183.67,191.15 4 213 +github.com/tetafro/godot/checks.go:194.2,194.28 1 213 +github.com/tetafro/godot/checks.go:224.2,224.11 1 213 +github.com/tetafro/godot/checks.go:191.15,193.3 1 100 +github.com/tetafro/godot/checks.go:194.28,198.16 3 8377 +github.com/tetafro/godot/checks.go:206.3,206.39 1 8265 +github.com/tetafro/godot/checks.go:210.3,210.35 1 8167 +github.com/tetafro/godot/checks.go:213.3,213.15 1 8158 +github.com/tetafro/godot/checks.go:219.3,219.51 1 7136 +github.com/tetafro/godot/checks.go:222.3,222.16 1 7136 +github.com/tetafro/godot/checks.go:198.16,201.24 3 112 +github.com/tetafro/godot/checks.go:204.4,204.12 1 112 +github.com/tetafro/godot/checks.go:201.24,203.5 1 14 +github.com/tetafro/godot/checks.go:206.39,208.12 2 98 +github.com/tetafro/godot/checks.go:210.35,211.12 1 9 +github.com/tetafro/godot/checks.go:213.15,214.24 1 1022 +github.com/tetafro/godot/checks.go:217.4,217.12 1 1022 +github.com/tetafro/godot/checks.go:214.24,216.5 1 31 +github.com/tetafro/godot/checks.go:219.51,221.4 1 31 +github.com/tetafro/godot/checks.go:229.42,233.41 1 75 +github.com/tetafro/godot/checks.go:236.2,236.14 1 55 +github.com/tetafro/godot/checks.go:233.41,235.3 1 20 +github.com/tetafro/godot/checks.go:241.41,243.45 1 650 +github.com/tetafro/godot/checks.go:247.2,254.36 3 631 +github.com/tetafro/godot/checks.go:259.2,263.40 2 551 +github.com/tetafro/godot/checks.go:267.2,267.14 1 506 +github.com/tetafro/godot/checks.go:243.45,245.3 1 19 +github.com/tetafro/godot/checks.go:254.36,256.3 1 80 +github.com/tetafro/godot/checks.go:263.40,265.3 1 45 +github.com/tetafro/godot/checks.go:270.50,271.34 1 189 +github.com/tetafro/godot/checks.go:276.2,276.14 1 100 +github.com/tetafro/godot/checks.go:271.34,272.35 1 926 +github.com/tetafro/godot/checks.go:272.35,274.4 1 89 +github.com/tetafro/godot/getters.go:13.87,14.29 1 12 +github.com/tetafro/godot/getters.go:19.2,20.54 2 12 +github.com/tetafro/godot/getters.go:23.2,27.64 3 12 +github.com/tetafro/godot/getters.go:31.2,33.15 3 12 +github.com/tetafro/godot/getters.go:51.2,53.22 2 12 +github.com/tetafro/godot/getters.go:14.29,16.3 1 0 +github.com/tetafro/godot/getters.go:20.54,22.3 1 0 +github.com/tetafro/godot/getters.go:27.64,29.3 1 0 +github.com/tetafro/godot/getters.go:34.16,36.47 1 4 +github.com/tetafro/godot/getters.go:37.21,43.4 1 4 +github.com/tetafro/godot/getters.go:44.10,47.66 1 4 +github.com/tetafro/godot/getters.go:58.86,60.34 2 8 +github.com/tetafro/godot/getters.go:89.2,89.17 1 8 +github.com/tetafro/godot/getters.go:60.34,62.10 2 88 +github.com/tetafro/godot/getters.go:66.3,66.20 1 38 +github.com/tetafro/godot/getters.go:69.3,69.35 1 16 +github.com/tetafro/godot/getters.go:62.10,63.12 1 50 +github.com/tetafro/godot/getters.go:66.20,67.12 1 22 +github.com/tetafro/godot/getters.go:69.35,71.48 1 468 +github.com/tetafro/godot/getters.go:78.4,78.42 1 16 +github.com/tetafro/godot/getters.go:81.4,86.6 3 16 +github.com/tetafro/godot/getters.go:71.48,72.13 1 452 +github.com/tetafro/godot/getters.go:78.42,79.13 1 0 +github.com/tetafro/godot/getters.go:93.89,95.34 2 4 +github.com/tetafro/godot/getters.go:106.2,106.17 1 4 +github.com/tetafro/godot/getters.go:95.34,96.41 1 117 +github.com/tetafro/godot/getters.go:99.3,104.5 3 73 +github.com/tetafro/godot/getters.go:96.41,97.12 1 44 +github.com/tetafro/godot/getters.go:110.92,112.34 2 12 +github.com/tetafro/godot/getters.go:132.2,132.17 1 12 +github.com/tetafro/godot/getters.go:112.34,114.27 2 132 +github.com/tetafro/godot/getters.go:121.3,121.16 1 132 +github.com/tetafro/godot/getters.go:125.3,130.5 3 114 +github.com/tetafro/godot/getters.go:115.21,116.14 1 57 +github.com/tetafro/godot/getters.go:117.22,118.14 1 75 +github.com/tetafro/godot/getters.go:121.16,122.12 1 18 +github.com/tetafro/godot/getters.go:136.84,138.34 2 4 +github.com/tetafro/godot/getters.go:146.2,146.17 1 4 +github.com/tetafro/godot/getters.go:138.34,145.3 3 117 +github.com/tetafro/godot/getters.go:153.52,156.40 1 424 +github.com/tetafro/godot/getters.go:160.2,160.33 1 405 +github.com/tetafro/godot/getters.go:179.2,179.17 1 405 +github.com/tetafro/godot/getters.go:182.2,182.21 1 404 +github.com/tetafro/godot/getters.go:156.40,158.3 1 19 +github.com/tetafro/godot/getters.go:160.33,163.38 3 557 +github.com/tetafro/godot/getters.go:168.3,168.50 1 557 +github.com/tetafro/godot/getters.go:163.38,167.4 3 51 +github.com/tetafro/godot/getters.go:168.50,169.27 1 635 +github.com/tetafro/godot/getters.go:173.4,173.16 1 503 +github.com/tetafro/godot/getters.go:176.4,176.20 1 503 +github.com/tetafro/godot/getters.go:169.27,171.13 2 132 +github.com/tetafro/godot/getters.go:173.16,175.5 1 376 +github.com/tetafro/godot/getters.go:179.17,181.3 1 1 +github.com/tetafro/godot/getters.go:186.40,187.25 1 12 +github.com/tetafro/godot/getters.go:187.25,188.30 1 114 +github.com/tetafro/godot/getters.go:188.30,189.34 1 1565 +github.com/tetafro/godot/getters.go:189.34,191.10 2 114 +github.com/tetafro/godot/godot.go:43.83,45.16 2 9 +github.com/tetafro/godot/godot.go:49.2,52.20 3 9 +github.com/tetafro/godot/godot.go:45.16,47.3 1 0 +github.com/tetafro/godot/godot.go:56.95,59.16 2 8 +github.com/tetafro/godot/godot.go:62.2,62.23 1 7 +github.com/tetafro/godot/godot.go:66.2,67.16 2 6 +github.com/tetafro/godot/godot.go:72.2,73.29 2 6 +github.com/tetafro/godot/godot.go:78.2,79.60 2 6 +github.com/tetafro/godot/godot.go:86.2,88.19 2 6 +github.com/tetafro/godot/godot.go:59.16,61.3 1 1 +github.com/tetafro/godot/godot.go:62.23,64.3 1 1 +github.com/tetafro/godot/godot.go:67.16,69.3 1 0 +github.com/tetafro/godot/godot.go:73.29,75.3 1 76 +github.com/tetafro/godot/godot.go:79.60,81.28 2 774 +github.com/tetafro/godot/godot.go:84.3,84.49 1 774 +github.com/tetafro/godot/godot.go:81.28,83.4 1 76 +github.com/tetafro/godot/godot.go:92.89,94.16 2 4 +github.com/tetafro/godot/godot.go:97.2,100.16 3 3 +github.com/tetafro/godot/godot.go:104.2,104.60 1 3 +github.com/tetafro/godot/godot.go:107.2,107.12 1 3 +github.com/tetafro/godot/godot.go:94.16,96.3 1 1 +github.com/tetafro/godot/godot.go:100.16,102.3 1 0 +github.com/tetafro/godot/godot.go:104.60,106.3 1 0 +github.com/tetafro/godot/godot.go:111.30,112.38 1 9 +github.com/tetafro/godot/godot.go:112.38,113.49 1 225 +github.com/tetafro/godot/godot.go:116.3,116.41 1 225 +github.com/tetafro/godot/godot.go:119.3,119.47 1 0 +github.com/tetafro/godot/godot.go:113.49,115.4 1 0 +github.com/tetafro/godot/godot.go:116.41,118.4 1 225 +mode: atomic diff --git a/godot_test.go b/godot_test.go index cfee0d0..75c1348 100644 --- a/godot_test.go +++ b/godot_test.go @@ -24,19 +24,28 @@ func TestRun(t *testing.T) { contains []string }{ { - name: "scope: decl", - scope: DeclScope, - contains: []string{"[DECL]"}, + name: "scope: decl", + scope: DeclScope, + contains: []string{ + "[PERIOD_DECL]", "[CAPITAL_DECL]", + }, }, { - name: "scope: top", - scope: TopLevelScope, - contains: []string{"[DECL]", "[TOP]"}, + name: "scope: top", + scope: TopLevelScope, + contains: []string{ + "[PERIOD_DECL]", "[CAPITAL_DECL]", + "[PERIOD_TOP]", "[CAPITAL_TOP]", + }, }, { - name: "scope: all", - scope: AllScope, - contains: []string{"[DECL]", "[TOP]", "[ALL]"}, + name: "scope: all", + scope: AllScope, + contains: []string{ + "[PERIOD_DECL]", "[CAPITAL_DECL]", + "[PERIOD_TOP]", "[CAPITAL_TOP]", + "[PERIOD_ALL]", "[CAPITAL_ALL]", + }, }, } @@ -49,9 +58,8 @@ func TestRun(t *testing.T) { continue } for _, s := range tt.contains { - if strings.Contains(c.Text(), s) { - expected++ - break + if cnt := strings.Count(c.Text(), s); cnt > 0 { + expected += cnt } } } @@ -99,7 +107,8 @@ func TestFix(t *testing.T) { }) t.Run("scope: decl", func(t *testing.T) { - expected := strings.ReplaceAll(string(content), "[DECL]", "[DECL].") + expected := strings.ReplaceAll(string(content), "[PERIOD_DECL]", "[PERIOD_DECL].") + expected = strings.ReplaceAll(expected, "non-capital-decl", "Non-capital-decl") fixed, err := Fix(testFile, file, fset, Settings{Scope: DeclScope, Period: true, Capital: true}) if err != nil { @@ -110,8 +119,10 @@ func TestFix(t *testing.T) { }) t.Run("scope: top", func(t *testing.T) { - expected := strings.ReplaceAll(string(content), "[DECL]", "[DECL].") - expected = strings.ReplaceAll(expected, "[TOP]", "[TOP].") + expected := strings.ReplaceAll(string(content), "[PERIOD_DECL]", "[PERIOD_DECL].") + expected = strings.ReplaceAll(expected, "[PERIOD_TOP]", "[PERIOD_TOP].") + expected = strings.ReplaceAll(expected, "non-capital-decl", "Non-capital-decl") + expected = strings.ReplaceAll(expected, "non-capital-top", "Non-capital-top") fixed, err := Fix(testFile, file, fset, Settings{Scope: TopLevelScope, Period: true, Capital: true}) if err != nil { @@ -122,9 +133,12 @@ func TestFix(t *testing.T) { }) t.Run("scope: all", func(t *testing.T) { - expected := strings.ReplaceAll(string(content), "[DECL]", "[DECL].") - expected = strings.ReplaceAll(expected, "[TOP]", "[TOP].") - expected = strings.ReplaceAll(expected, "[ALL]", "[ALL].") + expected := strings.ReplaceAll(string(content), "[PERIOD_DECL]", "[PERIOD_DECL].") + expected = strings.ReplaceAll(expected, "[PERIOD_TOP]", "[PERIOD_TOP].") + expected = strings.ReplaceAll(expected, "[PERIOD_ALL]", "[PERIOD_ALL].") + expected = strings.ReplaceAll(expected, "non-capital-decl", "Non-capital-decl") + expected = strings.ReplaceAll(expected, "non-capital-top", "Non-capital-top") + expected = strings.ReplaceAll(expected, "non-capital-all", "Non-capital-all") fixed, err := Fix(testFile, file, fset, Settings{Scope: AllScope, Period: true, Capital: true}) if err != nil { @@ -164,7 +178,8 @@ func TestReplace(t *testing.T) { defer func() { ioutil.WriteFile(testFile, content, mode) // nolint: errcheck,gosec }() - expected := strings.ReplaceAll(string(content), "[DECL]", "[DECL].") + expected := strings.ReplaceAll(string(content), "[PERIOD_DECL]", "[PERIOD_DECL].") + expected = strings.ReplaceAll(expected, "non-capital-decl", "Non-capital-decl") err := Replace(testFile, file, fset, Settings{Scope: DeclScope, Period: true, Capital: true}) if err != nil { @@ -182,9 +197,33 @@ func TestReplace(t *testing.T) { defer func() { ioutil.WriteFile(testFile, content, mode) // nolint: errcheck,gosec }() - expected := strings.ReplaceAll(string(content), "[DECL]", "[DECL].") - expected = strings.ReplaceAll(expected, "[TOP]", "[TOP].") - expected = strings.ReplaceAll(expected, "[ALL]", "[ALL].") + expected := strings.ReplaceAll(string(content), "[PERIOD_DECL]", "[PERIOD_DECL].") + expected = strings.ReplaceAll(expected, "[PERIOD_TOP]", "[PERIOD_TOP].") + expected = strings.ReplaceAll(expected, "non-capital-decl", "Non-capital-decl") + expected = strings.ReplaceAll(expected, "non-capital-top", "Non-capital-top") + + err := Replace(testFile, file, fset, Settings{Scope: TopLevelScope, Period: true, Capital: true}) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + fixed, err := ioutil.ReadFile(testFile) // nolint: gosec + if err != nil { + t.Fatalf("Failed to read fixed file %s: %v", testFile, err) + } + + assertEqualContent(t, expected, string(fixed)) + }) + + t.Run("scope: all", func(t *testing.T) { + defer func() { + ioutil.WriteFile(testFile, content, mode) // nolint: errcheck,gosec + }() + expected := strings.ReplaceAll(string(content), "[PERIOD_DECL]", "[PERIOD_DECL].") + expected = strings.ReplaceAll(expected, "[PERIOD_TOP]", "[PERIOD_TOP].") + expected = strings.ReplaceAll(expected, "[PERIOD_ALL]", "[PERIOD_ALL].") + expected = strings.ReplaceAll(expected, "non-capital-decl", "Non-capital-decl") + expected = strings.ReplaceAll(expected, "non-capital-top", "Non-capital-top") + expected = strings.ReplaceAll(expected, "non-capital-all", "Non-capital-all") err := Replace(testFile, file, fset, Settings{Scope: AllScope, Period: true, Capital: true}) if err != nil { diff --git a/testdata/check/README.md b/testdata/check/README.md index e1887c2..b3dc2af 100644 --- a/testdata/check/README.md +++ b/testdata/check/README.md @@ -2,10 +2,17 @@ Main integration test for linter. -- If line contains `[DECL]` string, it should be caught as error by the -linter with the setting `Scope: DeclScope`. -- If line contains `[TOP]` string, it should be caught as error by the -linter with the setting `Scope: TopLevelScope`. -- If line contains `[ALL]` string, it should be caught as error by the -linter with the setting `Scope: AllScope`. -- If line contains `[PASS]` string, it shouldn't be caught. +Tags: +- `[PERIOD_DECL]` - line should be caught as an error by the linter with the +settings `Scope: DeclScope, Period: true`. +- `[PERIOD_TOP]` - line should be caught as an error by the linter with the +settings `Scope: TopLevelScope, Period: true`. +- `[PERIOD_ALL]` - line should be caught as an error by the linter with the +settings `Scope: AllScope, Period: true`. +- `[CAPITAL_DECL]` - line should be caught as an error by the linter with the +settings `Scope: DeclScope, Capital: true`. +- `[CAPITAL_TOP]` - line should be caught as an error by the linter with the +settings `Scope: TopLevelScope, Capital: true`. +- `[CAPITAL_ALL]` - line should be caught as an error by the linter with the +settings `Scope: AllScope, Capital: true`. +- `[PASS]` - line shouldn't be caught. diff --git a/testdata/check/main.go b/testdata/check/main.go index d0d3b55..1ef3f28 100644 --- a/testdata/check/main.go +++ b/testdata/check/main.go @@ -1,4 +1,4 @@ -// Package comment without a period [TOP] +// Package comment without a period [PERIOD_TOP] package example /* @@ -21,7 +21,8 @@ import ( // #tag hashtag comment without period [PASS] /* -Multiline comment without a period [TOP] +non-capital-top [CAPITAL_TOP]. +Multiline comment without a period [PERIOD_TOP] */ @@ -29,27 +30,27 @@ Multiline comment without a period [TOP] Multiline comment with a period [PASS]. */ -/* One-line comment without a period [TOP] */ +/* One-line comment without a period [PERIOD_TOP] */ /* One-line comment with a period [PASS]. */ -// Single-line comment without a period [TOP] +// Single-line comment without a period [PERIOD_TOP] // Single-line comment with a period [PASS]. -// Block comment [DECL] +// Block comment [PERIOD_DECL] const ( - // Inside comment [DECL] + // Inside comment [PERIOD_DECL] constant1 = "constant1" // Inside comment [PASS]. constant2 = "constant2" ) -// Declaration comment without a period [DECL] +// Declaration comment without a period [PERIOD_DECL] type SimpleObject struct { - // Exported field comment [ALL] + // Exported field comment [PERIOD_ALL] Type string - // Unexported field comment [ALL] + // Unexported field comment [PERIOD_ALL] secret int } @@ -57,9 +58,9 @@ type SimpleObject struct { // co := ComplexObject{} // fmt.Println(co) // [PASS] type ComplexObject struct { - // Exported field comment [ALL] + // Exported field comment [PERIOD_ALL] Type string - // Unexported field comment [ALL] + // Unexported field comment [PERIOD_ALL] secret int } @@ -74,16 +75,16 @@ type Message struct { // second line // third line with a period [PASS]. func Sum(a, b int) int { - // Inner comment [ALL] + // Inner comment [PERIOD_ALL] a++ b++ - return a + b // Inline comment [ALL] + return a + b // Inline comment [PERIOD_ALL] } // Declaration multiline comment // second line -// third line without a period [DECL] +// third line without a period [PERIOD_DECL] func Mult(a, b int) int { return a * b } @@ -93,7 +94,7 @@ func CgoExportedFunction(a, b int) int { return a + b } -// Кириллица [DECL] +// Кириллица [PERIOD_DECL] func NonLatin() string { return "привет, мир" } @@ -110,12 +111,18 @@ func noComment() { } func inside() { - // Not a top level declaration [ALL] + // Not a top level declaration [PERIOD_ALL] type thing struct { field string } - t := thing{} // Inline comment [ALL] + t := thing{} // Inline comment [PERIOD_ALL] println(t) } +// nonCapital is a function. non-capital-decl first letter [CAPITAL_DECL]. +func nonCapital() int { + // non-capital-all [CAPITAL_ALL]. + return 10 // non-capital-all [CAPITAL_ALL]. +} + // Comment with a URL - http://example.com/[PASS] diff --git a/testdata/get/README.md b/testdata/get/README.md index 15931f3..fe2815c 100644 --- a/testdata/get/README.md +++ b/testdata/get/README.md @@ -2,9 +2,10 @@ Integration test for `getComments` method. -- If line contains `[DECL]` string, it should be extracted by `getComments` -with `scope` argument one of: `DeclScope`, `TopLevelScope`, `AllScope`. -- If line contains `[TOP]` string, it should be extracted by `getComments` -with `scope` argument one of: `TopLevelScope`, `AllScope`. -- If line contains `[ALL]` string, it should be extracted by `getComments` -with `scope` argument `AllScope`. +Tags: +- `[DECL]` - line should be extracted by `getComments` with `scope` argument +one of: `DeclScope`, `TopLevelScope`, `AllScope`. +- `[TOP]` - line should be extracted by `getComments` with `scope` argument +one of: `TopLevelScope`, `AllScope`. +- `[ALL]` - line should be extracted by `getComments` with `scope` argument +`AllScope`.