Skip to content
Snippets Groups Projects
Commit 1d26bdff authored by Semyon Krestyaninov's avatar Semyon Krestyaninov :dog2:
Browse files

add comments

parent ce2b124c
No related branches found
No related tags found
No related merge requests found
...@@ -10,8 +10,13 @@ import ( ...@@ -10,8 +10,13 @@ import (
) )
type PruneidentWalker struct { type PruneidentWalker struct {
// idents содержит идентификаторы для удаления в виде map для оптимизации
idents map[string]struct{} idents map[string]struct{}
// pruned отслеживает местоположения обрезанных узлов для их идентификации
pruned map[file.Location]struct{} pruned map[file.Location]struct{}
// scopes хранит стек областей видимости объявленных переменных
scopes []scope scopes []scope
} }
...@@ -25,18 +30,23 @@ func NewPruneidentWalker(idents []string) *PruneidentWalker { ...@@ -25,18 +30,23 @@ func NewPruneidentWalker(idents []string) *PruneidentWalker {
return w return w
} }
// scope представляет область видимости для одной переменной
type scope struct { type scope struct {
variable string variable string
} }
func (w *PruneidentWalker) Walk(node *ast.Node) { func (w *PruneidentWalker) Walk(node *ast.Node) {
// очищаем состояние для случая повторного использования
w.scopes = []scope{} w.scopes = []scope{}
w.pruned = make(map[file.Location]struct{}) w.pruned = make(map[file.Location]struct{})
w.walk(node) w.walk(node)
} }
//nolint:cyclop,funlen,gocyclo // Вынесение логики в функции ещё больше усложнит восприятие кода // walk рекурсивно обходит узлы, управляя областями видимости для переменных.
// Реализация аналогична ast.Walk с добавлением обработки областей видимости.
//
//nolint:cyclop,funlen,gocyclo
func (w *PruneidentWalker) walk(node *ast.Node) { func (w *PruneidentWalker) walk(node *ast.Node) {
if node == nil || *node == nil { if node == nil || *node == nil {
return return
...@@ -111,7 +121,10 @@ func (w *PruneidentWalker) walk(node *ast.Node) { ...@@ -111,7 +121,10 @@ func (w *PruneidentWalker) walk(node *ast.Node) {
w.visit(node) w.visit(node)
} }
//nolint:cyclop,funlen,gocyclo,gocognit // Вынесение логики в функции ещё больше усложнит восприятие кода // visit проверяет и модифицирует узлы, удаляя указанные идентификаторы
// и оптимизируя логические выражения после удаления.
//
//nolint:cyclop,funlen,gocyclo,gocognit
func (w *PruneidentWalker) visit(node *ast.Node) { func (w *PruneidentWalker) visit(node *ast.Node) {
switch n := (*node).(type) { switch n := (*node).(type) {
case *ast.IdentifierNode: case *ast.IdentifierNode:
...@@ -137,6 +150,8 @@ func (w *PruneidentWalker) visit(node *ast.Node) { ...@@ -137,6 +150,8 @@ func (w *PruneidentWalker) visit(node *ast.Node) {
leftPruned := w.prunedNode(n.Left) leftPruned := w.prunedNode(n.Left)
rightPruned := w.prunedNode(n.Right) rightPruned := w.prunedNode(n.Right)
// Для булевых операторов сохраняем оставшуюся ветку,
// для остальных - удаляем весь узел при любом удаленном операнде
if operator.IsBoolean(n.Operator) { if operator.IsBoolean(n.Operator) {
switch { switch {
case leftPruned && rightPruned: case leftPruned && rightPruned:
...@@ -210,11 +225,14 @@ func (w *PruneidentWalker) visit(node *ast.Node) { ...@@ -210,11 +225,14 @@ func (w *PruneidentWalker) visit(node *ast.Node) {
} }
} }
// mustPruned возвращает true, если идентификатор должен быть удален
// и не находится в текущей области видимости.
func (w *PruneidentWalker) mustPruned(ident string) bool { func (w *PruneidentWalker) mustPruned(ident string) bool {
_, exists := w.idents[ident] _, exists := w.idents[ident]
return exists && !w.scoped(ident) return exists && !w.scoped(ident)
} }
// pruneNode заменяет указанный узел на ast.NilNode и сохраняет его позицию.
func (w *PruneidentWalker) pruneNode(node *ast.Node) { func (w *PruneidentWalker) pruneNode(node *ast.Node) {
if node == nil || *node == nil { if node == nil || *node == nil {
return return
...@@ -225,6 +243,7 @@ func (w *PruneidentWalker) pruneNode(node *ast.Node) { ...@@ -225,6 +243,7 @@ func (w *PruneidentWalker) pruneNode(node *ast.Node) {
w.pruned[prune.Location()] = struct{}{} w.pruned[prune.Location()] = struct{}{}
} }
// prunedNode проверяет, был ли узел помечен как удаленный.
func (w *PruneidentWalker) prunedNode(node ast.Node) bool { func (w *PruneidentWalker) prunedNode(node ast.Node) bool {
if node == nil { if node == nil {
return false return false
...@@ -236,14 +255,17 @@ func (w *PruneidentWalker) prunedNode(node ast.Node) bool { ...@@ -236,14 +255,17 @@ func (w *PruneidentWalker) prunedNode(node ast.Node) bool {
return false return false
} }
// beginScope добавляет новую область видимости для переменной.
func (w *PruneidentWalker) beginScope(variable string) { func (w *PruneidentWalker) beginScope(variable string) {
w.scopes = append(w.scopes, scope{variable: variable}) w.scopes = append(w.scopes, scope{variable: variable})
} }
// endScope удаляет последнюю добавленную область видимости.
func (w *PruneidentWalker) endScope() { func (w *PruneidentWalker) endScope() {
w.scopes = w.scopes[:len(w.scopes)-1] w.scopes = w.scopes[:len(w.scopes)-1]
} }
// scoped проверяет, существует ли переменная в текущей области видимости.
func (w *PruneidentWalker) scoped(variable string) bool { func (w *PruneidentWalker) scoped(variable string) bool {
for i := len(w.scopes) - 1; i >= 0; i-- { for i := len(w.scopes) - 1; i >= 0; i-- {
if w.scopes[i].variable == variable { if w.scopes[i].variable == variable {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment