Skip to content
This repository has been archived by the owner on Apr 23, 2024. It is now read-only.

Commit

Permalink
internal/walkers,symbols: collecting colors has been moved from the i…
Browse files Browse the repository at this point in the history
…ndexing stage to the call graph creation stage (#18)
  • Loading branch information
i582 authored Jul 1, 2021
1 parent dc19643 commit 3c76e98
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 82 deletions.
2 changes: 1 addition & 1 deletion internal/symbols/class.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type Class struct {
Name string
Type ClassType
Pos meta.ElementPosition
Colors palette.ColorContainer
Colors *palette.ColorContainer

WithExplicitConstructor bool
}
Expand Down
2 changes: 1 addition & 1 deletion internal/symbols/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type Function struct {
Name string
Type FunctionType
Pos meta.ElementPosition
Colors palette.ColorContainer
Colors *palette.ColorContainer

Called *Functions
CalledBy *Functions
Expand Down
96 changes: 81 additions & 15 deletions internal/walkers/root_checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ func (r *RootChecker) BeforeEnterFile() {
r.fileFunction = &symbols.Function{
Name: namegen.FileFunction(r.ctx.Filename()),
Type: symbols.MainFunc,
Colors: &palette.ColorContainer{},
Called: symbols.NewFunctions(),
CalledBy: symbols.NewFunctions(),
}
Expand Down Expand Up @@ -90,18 +91,88 @@ func (r *RootChecker) AfterEnterNode(n ir.Node) {
r.handleImportExpr(n)

case *ir.ClassStmt:
r.checkColorsInDoc(n.ClassName, n.Doc)
r.handleClass(n.ClassName, n.Stmts, n.Doc)
case *ir.InterfaceStmt:
r.checkColorsInDoc(n.InterfaceName, n.Doc)
r.handleClass(n.InterfaceName, n.Stmts, n.Doc)
case *ir.TraitStmt:
r.checkColorsInDoc(n.TraitName, n.Doc)
case *ir.ClassMethodStmt:
r.checkColorsInDoc(n.MethodName, n.Doc)
r.handleClass(n.TraitName, n.Stmts, n.Doc)
case *ir.FunctionStmt:
r.checkColorsInDoc(n.FunctionName, n.Doc)
r.handleFunction(n.FunctionName, n.Doc)
}
}

func (r *RootChecker) handleFunction(name *ir.Identifier, doc phpdoc.Comment) {
classFQN := namegen.FunctionFQN(r.state, name.Value)
class, ok := r.globalCtx.Functions.Get(classFQN)
if !ok {
return
}

colors, errs := r.colorsFromDoc(doc)
for _, err := range errs {
r.ctx.Report(name, linter.LevelError, "errorColor", err)
}

class.Colors.Colors = colors.Colors
}

func (r *RootChecker) handleClassMethods(name string, stmts []ir.Node, classColors palette.ColorContainer) {
for _, stmt := range stmts {
methodNode, ok := stmt.(*ir.ClassMethodStmt)
if !ok {
continue
}

methodFQN := namegen.Method(name, methodNode.MethodName.Value)

method, ok := r.globalCtx.Functions.Get(methodFQN)
if !ok {
continue
}

methodColors, errs := r.colorsFromDoc(methodNode.Doc)
for _, err := range errs {
r.ctx.Report(methodNode.MethodName, linter.LevelError, "errorColor", err)
}

if !classColors.Empty() {
// We need to mix the colors in the following order,
// first the class colors and then the method colors.
//
// If the class has no colors, then there is no point in copying.
var newColors palette.ColorContainer

for _, classColor := range classColors.Colors {
newColors.Add(classColor)
}
for _, methodColor := range methodColors.Colors {
newColors.Add(methodColor)
}

methodColors = newColors
}

method.Colors.Colors = methodColors.Colors
}
}

func (r *RootChecker) handleClass(name *ir.Identifier, stmts []ir.Node, doc phpdoc.Comment) {
classFQN := namegen.ClassFQN(r.state, name.Value)
class, ok := r.globalCtx.Classes.Get(classFQN)
if !ok {
return
}

colors, errs := r.colorsFromDoc(doc)
for _, err := range errs {
r.ctx.Report(name, linter.LevelError, "errorColor", err)
}

class.Colors.Colors = colors.Colors

r.handleClassMethods(classFQN, stmts, colors)
}

func (r *RootChecker) handlePropertyFetch(n *ir.PropertyFetchExpr, blockScope *meta.Scope, nodePath irutil.NodePath) {
var propInfo solver.FindPropertyResult
var propertyName string
Expand Down Expand Up @@ -381,14 +452,7 @@ func (r *RootChecker) handleClassWithoutMethod(static bool, classesWithoutMethod
}
}

func (r *RootChecker) checkColorsInDoc(name ir.Node, doc phpdoc.Comment) {
errs := r.getPhpDocColorErrors(doc)
for _, err := range errs {
r.ctx.Report(name, linter.LevelError, "errorColor", err)
}
}

func (r *RootChecker) getPhpDocColorErrors(comment phpdoc.Comment) (errs []string) {
func (r *RootChecker) colorsFromDoc(comment phpdoc.Comment) (colors palette.ColorContainer, errs []string) {
for _, part := range comment.Parsed {
p, ok := part.(*phpdoc.RawCommentPart)
if !ok {
Expand All @@ -415,9 +479,11 @@ func (r *RootChecker) getPhpDocColorErrors(comment phpdoc.Comment) (errs []strin
errs = append(errs, fmt.Sprintf("Color '%s' missing in palette (either a misprint or a new color that needs to be added)", colorName))
continue
}

colors.Add(r.palette.GetColorByName(colorName))
}

return errs
return colors, errs
}

func (r *RootChecker) getImportAbsPath(path string) (string, bool) {
Expand Down
71 changes: 6 additions & 65 deletions internal/walkers/root_indexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"github.com/VKCOM/noverify/src/ir"
"github.com/VKCOM/noverify/src/linter"
"github.com/VKCOM/noverify/src/meta"
"github.com/VKCOM/noverify/src/phpdoc"
"github.com/vkcom/nocolor/internal/palette"
"github.com/vkcom/nocolor/internal/symbols"
"github.com/vkcom/nocolor/internal/walkers/namegen"
Expand Down Expand Up @@ -47,6 +46,7 @@ func (r *RootIndexer) BeforeEnterFile() {
r.meta.Functions.Add(&symbols.Function{
Name: namegen.FileFunction(r.ctx.Filename()),
Type: symbols.MainFunc,
Colors: &palette.ColorContainer{},
Called: symbols.NewFunctions(),
CalledBy: symbols.NewFunctions(),
})
Expand Down Expand Up @@ -100,7 +100,7 @@ func (r *RootIndexer) BeforeEnterNode(n ir.Node) {
Name: name,
Type: symbols.PlainClass,
Pos: r.getElementPos(n),
Colors: r.colorsFromDoc(n.Doc),
Colors: &palette.ColorContainer{},
})

case *ir.InterfaceStmt:
Expand All @@ -110,7 +110,7 @@ func (r *RootIndexer) BeforeEnterNode(n ir.Node) {
Name: name,
Type: symbols.Interface,
Pos: r.getElementPos(n),
Colors: r.colorsFromDoc(n.Doc),
Colors: &palette.ColorContainer{},
})

case *ir.TraitStmt:
Expand All @@ -120,7 +120,7 @@ func (r *RootIndexer) BeforeEnterNode(n ir.Node) {
Name: name,
Type: symbols.Trait,
Pos: r.getElementPos(n),
Colors: r.colorsFromDoc(n.Doc),
Colors: &palette.ColorContainer{},
})

case *ir.ClassMethodStmt:
Expand All @@ -132,37 +132,11 @@ func (r *RootIndexer) BeforeEnterNode(n ir.Node) {
typ = symbols.ExternFunc
}

colors := r.colorsFromDoc(n.Doc)

class, ok := r.meta.Classes.Get(className)
if ok {
if n.MethodName.Value == "__construct" {
class.WithExplicitConstructor = true
}

if !class.Colors.Empty() {
// We need to mix the colors in the following order,
// first the class colors and then the method colors.
//
// If the class has no colors, then there is no point in copying.
var newColors palette.ColorContainer

for _, classColor := range class.Colors.Colors {
newColors.Add(classColor)
}
for _, methodColor := range colors.Colors {
newColors.Add(methodColor)
}

colors = newColors
}
}

r.meta.Functions.Add(&symbols.Function{
Name: methodName,
Type: typ,
Pos: r.getElementPos(n),
Colors: colors,
Colors: &palette.ColorContainer{},
Called: symbols.NewFunctions(),
CalledBy: symbols.NewFunctions(),
})
Expand All @@ -179,7 +153,7 @@ func (r *RootIndexer) BeforeEnterNode(n ir.Node) {
Name: name,
Type: typ,
Pos: r.getElementPos(n),
Colors: r.colorsFromDoc(n.Doc),
Colors: &palette.ColorContainer{},
Called: symbols.NewFunctions(),
CalledBy: symbols.NewFunctions(),
})
Expand All @@ -197,36 +171,3 @@ func (r *RootIndexer) getElementPos(n ir.Node) meta.ElementPosition {
Length: int32(pos.EndPos - pos.StartPos),
}
}

func (r *RootIndexer) colorsFromDoc(comment phpdoc.Comment) palette.ColorContainer {
var colors palette.ColorContainer

for _, part := range comment.Parsed {
p, ok := part.(*phpdoc.RawCommentPart)
if !ok {
continue
}

if p.Name() != r.colorTag {
continue
}

if len(p.Params) == 0 {
continue
}

colorName := p.Params[0]

if colorName == "transparent" {
continue
}

if !r.palette.ColorExists(colorName) {
continue
}

colors.Add(r.palette.GetColorByName(colorName))
}

return colors
}

0 comments on commit 3c76e98

Please sign in to comment.