Skip to content

Commit

Permalink
✨ try to get import references when found (#688)
Browse files Browse the repository at this point in the history
@djzager 

Basically, when we do our fall back we can find the imports mostly
correct, but imports are for namespaces not for actual objects so no
definition can be used. Therefore we are getting zero results back for
the definiton.

We can get all the references for the import though, and we can just let
the analyzer dedup.

If you could help get me a windows container image to test with that
would helpful (or show me how)

Signed-off-by: Shawn Hurley <shawn@hurley.page>
  • Loading branch information
shawn-hurley committed Aug 8, 2024
1 parent 332153d commit 974a5d2
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 48 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/demo-testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ jobs:
with:
fetch-depth: 0
repository: konveyor/tackle2-addon-analyzer
ref: refs/pull/97/merge
ref: ${{ steps.extract-info.outputs.ADDON_REF }}
path: tackle2-addon-analyzer

- name: Build addon and push images
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,52 +86,62 @@ func (d *dotnetServiceClient) Evaluate(ctx context.Context, cap string, conditio
// Not a valid regex, can't do anything more
return provider.ProviderEvaluateResponse{Matched: false}, nil
}
var positions []protocol.TextDocumentPositionParams
var positions []interface{}
positions, err = parallelWalk(d.config.Location, regex)
if err != nil {
d.log.Error(err, "failed parallel walk")
return provider.ProviderEvaluateResponse{Matched: false}, nil
}
for _, position := range positions {
fmt.Println(position)
fmt.Println("%#v", position)
res := []protocol.Location{}
_, err := d.rpc.Call(d.ctx, "textDocument/definition", position, &res)
if err != nil {
d.log.Error(err, "problem getting definition")
continue
}

if len(res) == 0 || len(res) > 1 {
d.log.Error(fmt.Errorf("only expect one result"), "too many, or not enough, results")
continue
switch position.(type) {
case protocol.ReferenceParams:
_, err := d.rpc.Call(d.ctx, protocol.MethodTextDocumentReferences, position, &res)
if err != nil {
d.log.Error(err, "failed to get references")
}
case protocol.TextDocumentPositionParams:
_, err := d.rpc.Call(d.ctx, "textDocument/definition", position, &res)
if err != nil {
d.log.Error(err, "problem getting definition")
continue
}
if len(res) == 0 || len(res) > 1 {
d.log.Error(fmt.Errorf("only expect one result"), "too many, or not enough, results")
continue
}
}

switch filename := string(res[0].URI); {
case strings.HasPrefix(filename, "csharp"):
// As best I understand, this would require the definition to be defined
// outside the project...like a third-party dep.

// "csharp:/metadata/projects/NerdDinner/assemblies/System.Web.Mvc/symbols/System.Web.Mvc.Controller.cs"
split := strings.Split(filename, "assemblies/")
if strings.HasPrefix(split[1], namespace) {
lineNumber := int(position.Position.Line)
incidents = append(incidents, provider.IncidentContext{
FileURI: position.TextDocument.URI,
LineNumber: &lineNumber,
Variables: map[string]interface{}{
"file": string(position.TextDocument.URI),
},
CodeLocation: &provider.Location{
StartPosition: provider.Position{Line: float64(lineNumber)},
EndPosition: provider.Position{Line: float64(lineNumber)},
},
})
for _, r := range res {
switch filename := string(res[0].URI); {
case strings.HasPrefix(filename, "csharp"):
// As best I understand, this would require the definition to be defined
// outside the project...like a third-party dep.

// "csharp:/metadata/projects/NerdDinner/assemblies/System.Web.Mvc/symbols/System.Web.Mvc.Controller.cs"
split := strings.Split(filename, "assemblies/")
if strings.HasPrefix(split[1], namespace) {
lineNumber := int(r.Range.Start.Line)
incidents = append(incidents, provider.IncidentContext{
FileURI: r.URI,
LineNumber: &lineNumber,
Variables: map[string]interface{}{
"file": string(r.URI),
},
CodeLocation: &provider.Location{
StartPosition: provider.Position{Line: float64(lineNumber)},
EndPosition: provider.Position{Line: float64(lineNumber)},
},
})
}
case strings.HasPrefix(filename, "file"):
// TODO(djzager): do we even need to handle these?
d.log.Error(fmt.Errorf("not implemented"), "don't know how to handle file URI")
continue
}
case strings.HasPrefix(filename, "file"):
// TODO(djzager): do we even need to handle these?
d.log.Error(fmt.Errorf("not implemented"), "don't know how to handle file URI")
continue
}

}
}
return provider.ProviderEvaluateResponse{
Expand All @@ -140,7 +150,7 @@ func (d *dotnetServiceClient) Evaluate(ctx context.Context, cap string, conditio
}, nil
}

func processFile(path string, regex *regexp.Regexp, positionsChan chan<- protocol.TextDocumentPositionParams, wg *sync.WaitGroup) {
func processFile(path string, regex *regexp.Regexp, positionsChan chan<- interface{}, wg *sync.WaitGroup) {
defer wg.Done()

content, err := os.ReadFile(path)
Expand All @@ -158,24 +168,38 @@ func processFile(path string, regex *regexp.Regexp, positionsChan chan<- protoco
if err != nil {
return
}
positionsChan <- protocol.TextDocumentPositionParams{
TextDocument: protocol.TextDocumentIdentifier{
URI: uri.New(fmt.Sprintf("file:///%s", absPath)),
},
Position: protocol.Position{
Line: uint32(lineNumber),
Character: uint32(loc[1]),
},
if strings.Contains(scanner.Text(), "using") {
positionsChan <- protocol.ReferenceParams{
TextDocumentPositionParams: protocol.TextDocumentPositionParams{
TextDocument: protocol.TextDocumentIdentifier{
URI: uri.New(fmt.Sprintf("file:///%s", absPath)),
},
Position: protocol.Position{
Line: uint32(lineNumber),
Character: uint32(loc[1]),
},
},
}
} else {
positionsChan <- protocol.TextDocumentPositionParams{
TextDocument: protocol.TextDocumentIdentifier{
URI: uri.New(fmt.Sprintf("file:///%s", absPath)),
},
Position: protocol.Position{
Line: uint32(lineNumber),
Character: uint32(loc[1]),
},
}
}
}
lineNumber++
}
}
}

func parallelWalk(location string, regex *regexp.Regexp) ([]protocol.TextDocumentPositionParams, error) {
var positions []protocol.TextDocumentPositionParams
positionsChan := make(chan protocol.TextDocumentPositionParams)
func parallelWalk(location string, regex *regexp.Regexp) ([]interface{}, error) {
var positions []interface{}
positionsChan := make(chan interface{})
wg := &sync.WaitGroup{}

go func() {
Expand Down

0 comments on commit 974a5d2

Please sign in to comment.