smithy-lang / smithy-language-server

A Language Server Protocol implementation for the Smithy IDL
https://smithy.io
Apache License 2.0
33 stars 19 forks source link

IndexOutOfBoundsException preventing project load when a naming conflict occurs #110

Closed kubukoz closed 1 year ago

kubukoz commented 1 year ago

To reproduce:

  1. Create a file, a.smithy, with this content:
$version: "2"

namespace a

operation HelloWorld {
    input := {
        @required
        name: String
    }
    output := {
        @required
        name: String
    }
}
  1. Create another one, b.smithy, with this content:
$version: "2"

namespace b

string Ignored

operation HelloWorld {
    input := {
        @required
        name: String
    }
    output := {
        @required
        name: String
    }
}
  1. See errors. In your extension output panel you may see this:
    java.lang.IndexOutOfBoundsException: Index 15 out of bounds for length 14
    at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
    at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
    at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:266)
    at java.base/java.util.Objects.checkIndex(Objects.java:359)
    at java.base/java.util.ArrayList.get(ArrayList.java:427)
    at software.amazon.smithy.lsp.ext.FileCachingCollector.getNextEndMarker(FileCachingCollector.java:362)
    at software.amazon.smithy.lsp.ext.FileCachingCollector.getEndPosition(FileCachingCollector.java:421)
    at software.amazon.smithy.lsp.ext.FileCachingCollector.collectInlineInputOutputLocations(FileCachingCollector.java:153)
    at software.amazon.smithy.lsp.ext.FileCachingCollector.lambda$collectDefinitionLocations$0(FileCachingCollector.java:79)

I debugged this a little bit while minimizing, and it's pretty obvious to me now that the problem is the HelloWorld naming conflict - somewhere in the file caching collector there's some logic that doesn't disambiguate the two operations, while it should.

I'll investigate this further and work on a fix.

kubukoz commented 1 year ago

Looks like collectInlineInputOutputLocations thinks both HelloWorldOutputs are related to the operation in b.smithy:

image

and it looks for the getEndPosition of the operation b#HelloWorld in the file a.smithy:

image

so something is definitely happening around the file/operation matching. I'll try to get a test.

kubukoz commented 1 year ago

I have a test that reproduces this, but it only fails ~40% of the time (tested across 50 runs): https://github.com/disneystreaming/smithy-language-server/tree/iiobe-error-repro