Skip to content

Commit

Permalink
Temptative solution for basic annotation inspection
Browse files Browse the repository at this point in the history
Signed-off-by: Juan Manuel Leflet Estrada <[email protected]>
  • Loading branch information
jmle committed Jun 18, 2024
1 parent b5c166d commit c2d701c
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"os"
"os/exec"
"path/filepath"
"regexp"
"strconv"
"strings"

Expand All @@ -21,6 +22,8 @@ const (
KIND_EXTRA_KEY = "kind"
SYMBOL_NAME_KEY = "name"
FILE_KEY = "file"
PACKAGE = "package"
CONTAINER_NAME = "containerName"
)

func (p *javaServiceClient) filterVariableDeclaration(symbols []protocol.WorkspaceSymbol) ([]provider.IncidentContext, error) {
Expand Down Expand Up @@ -91,6 +94,40 @@ func (p *javaServiceClient) filterDefault(symbols []protocol.WorkspaceSymbol) ([
return incidents, nil
}

func (p *javaServiceClient) filterAnnotated(cond *javaCondition, symbols []protocol.WorkspaceSymbol) ([]provider.IncidentContext, error) {
incidents := []provider.IncidentContext{}
for _, symbol := range symbols {
incident, err := p.convertToIncidentContext(symbol)
if err != nil {
return nil, err
}
// TODO: problem: for kind == METHOD || kind == CLASS, the containerName returns name of the method or the class, which is fine, but when
// kind == FIELD we would probably want to look for the type of the field, not the name. That is not possible atm
kind := strings.ToLower(incident.Variables[KIND_EXTRA_KEY].(string))
containerName := incident.Variables[CONTAINER_NAME].(string)
pkg := incident.Variables[PACKAGE].(string)
pattern := regexp.MustCompile(cond.Referenced.Pattern)
if kind == strings.ToLower(cond.Referenced.Location) {
// pattern for annotated classes or methods could be a regex
if kind == "class" {
// for classes, we need the fully qualified name (package + class name)
fqn := strings.Join([]string{pkg, containerName}, ".")
if pattern.Match([]byte(fqn)) && kind == strings.ToLower(cond.Referenced.Location) {
incidents = append(incidents, incident)
}
} else if kind == "method" {
if pattern.Match([]byte(containerName)) && kind == strings.ToLower(cond.Referenced.Location) {
incidents = append(incidents, incident)
}
} else if incident.Variables[CONTAINER_NAME] == pattern && kind == strings.ToLower(cond.Referenced.Location) {
incidents = append(incidents, incident)
}
}
}
return incidents, nil

}

// TODO: we will probably want to filter symbols bassed on if in any way the method is being used in the code directly.
// This will need to be part of a "filtration" concept that windup has. Searching partiular subsets of things (just the application, applicatoin + corp libraries and the everything.)
// Today this is just giving everything.
Expand Down Expand Up @@ -152,7 +189,8 @@ func (p *javaServiceClient) convertToIncidentContext(symbol protocol.WorkspaceSy
KIND_EXTRA_KEY: symbolKindToString(symbol.Kind),
SYMBOL_NAME_KEY: symbol.Name,
FILE_KEY: string(u),
"package": n,
PACKAGE: n,
CONTAINER_NAME: symbol.ContainerName,
},
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,13 @@ type javaCondition struct {
}

type referenceCondition struct {
Pattern string `yaml:"pattern"`
Location string `yaml:"location"`
Pattern string `yaml:"pattern"`
Location string `yaml:"location"`
Annotated annotatedCondition `yaml:"annotated""`
}

type annotatedCondition struct {
Pattern string `yaml:"pattern"`
}

func NewJavaProvider(log logr.Logger, lspServerName string, contextLines int) *javaProvider {
Expand Down Expand Up @@ -291,6 +296,7 @@ func (p *javaProvider) Init(ctx context.Context, log logr.Logger, config provide
"-Djava.net.useSystemProxies=true",
"-configuration",
"./",
//"--jvm-arg=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:1044",
"-data",
workspace,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"os"
"os/exec"
"path/filepath"
"reflect"
"regexp"
"strings"
"sync"
Expand Down Expand Up @@ -51,14 +52,24 @@ func (p *javaServiceClient) Evaluate(ctx context.Context, cap string, conditionI
return provider.ProviderEvaluateResponse{}, fmt.Errorf("unable to get query info: %v", err)
}

if cond.Referenced.Pattern == "" {
// if "annotated" is present, do look for the annotation instead and then filter out according to the
// original location and reference
location := cond.Referenced.Location
pattern := cond.Referenced.Pattern
isAnnotated := !reflect.DeepEqual(cond.Referenced.Annotated, annotatedCondition{})
if isAnnotated {
location = "annotation"
pattern = cond.Referenced.Annotated.Pattern
}

if pattern == "" {
return provider.ProviderEvaluateResponse{}, fmt.Errorf("provided query pattern empty")
}
symbols := p.GetAllSymbols(ctx, cond.Referenced.Pattern, cond.Referenced.Location)
symbols := p.GetAllSymbols(ctx, pattern, location)
p.log.V(5).Info("Symbols retrieved", "symbols", symbols)

incidents := []provider.IncidentContext{}
switch locationToCode[strings.ToLower(cond.Referenced.Location)] {
switch locationToCode[strings.ToLower(location)] {
case 0:
// Filter handle for type, find all the referneces to this type.
incidents, err = p.filterDefault(symbols)
Expand All @@ -69,7 +80,11 @@ func (p *javaServiceClient) Evaluate(ctx context.Context, cap string, conditionI
case 3:
incidents, err = p.filterConstructorSymbols(ctx, symbols)
case 4:
incidents, err = p.filterDefault(symbols)
if isAnnotated {
incidents, err = p.filterAnnotated(cond, symbols)
} else {
incidents, err = p.filterDefault(symbols)
}
case 7:
incidents, err = p.filterMethodSymbols(symbols)
case 8:
Expand Down

0 comments on commit c2d701c

Please sign in to comment.