From 88e8fddcb638ec86d544c14a685d2548e420b9ed Mon Sep 17 00:00:00 2001 From: David Francoeur Date: Tue, 28 Nov 2023 12:38:45 -0500 Subject: [PATCH] Avoid substring if not suffixed (#133) * Add a test for input/output fix ``` java.lang.RuntimeException: Exception while collecting container shape locations in model file: /var/folders/zv/7_jglb8d4tz6_zs72sfkq9v40000gq/T/hs7886717560855699356/main.smithy at software.amazon.smithy.lsp.ext.FileCachingCollector.collectDefinitionLocations(FileCachingCollector.java:70) at software.amazon.smithy.lsp.ext.SmithyProject.collectLocations(SmithyProject.java:205) at software.amazon.smithy.lsp.ext.SmithyProject.lambda$new$0(SmithyProject.java:73) at java.base/java.util.Optional.ifPresent(Optional.java:178) at software.amazon.smithy.lsp.ext.SmithyProject.(SmithyProject.java:73) at software.amazon.smithy.lsp.ext.SmithyProject.load(SmithyProject.java:184) at software.amazon.smithy.lsp.ext.SmithyProject.load(SmithyProject.java:149) at software.amazon.smithy.lsp.ext.Harness.loadHarness(Harness.java:127) at software.amazon.smithy.lsp.ext.Harness.create(Harness.java:117) at software.amazon.smithy.lsp.ext.SmithyProjectTest.shapeIdFromLocationV2(SmithyProjectTest.java:425) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63) at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329) at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293) at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) at org.junit.runners.ParentRunner.run(ParentRunner.java:413) at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:110) at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58) at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38) at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62) at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33) at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94) at jdk.proxy1/jdk.proxy1.$Proxy2.processTestClass(Unknown Source) at org.gradle.api.internal.tasks.testing.worker.TestWorker$2.run(TestWorker.java:176) at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129) at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100) at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60) at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56) at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:133) at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:71) at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69) at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74) Caused by: java.lang.StringIndexOutOfBoundsException: begin 0, end -3, length 6 at java.base/java.lang.String.checkBoundsBeginEnd(String.java:4601) at java.base/java.lang.String.substring(String.java:2704) at software.amazon.smithy.lsp.ext.FileCachingCollector.getOperationForInlinedInputOrOutput(FileCachingCollector.java:243) at software.amazon.smithy.lsp.ext.FileCachingCollector.collectContainerShapeLocationsInModelFile(FileCachingCollector.java:111) at software.amazon.smithy.lsp.ext.FileCachingCollector.collectDefinitionLocations(FileCachingCollector.java:67) ... 52 more ``` * Avoid substring if not suffixed --- .../smithy/lsp/ext/FileCachingCollector.java | 5 ++++- .../amazon/smithy/lsp/ext/SmithyProjectTest.java | 8 ++++++++ .../amazon/smithy/lsp/ext/models/v2/main.smithy | 15 +++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/main/java/software/amazon/smithy/lsp/ext/FileCachingCollector.java b/src/main/java/software/amazon/smithy/lsp/ext/FileCachingCollector.java index ec9c8ef5..334bcd28 100644 --- a/src/main/java/software/amazon/smithy/lsp/ext/FileCachingCollector.java +++ b/src/main/java/software/amazon/smithy/lsp/ext/FileCachingCollector.java @@ -240,7 +240,10 @@ private Optional getOperationForInlinedInputOrOutput(Shape shape String suffix = getOperationInputOrOutputSuffix(shape, preamble); String shapeName = shape.getId().getName(); - String matchingOperationName = shapeName.substring(0, shapeName.length() - suffix.length()); + String matchingOperationName = + shapeName.endsWith(suffix) + ? shapeName.substring(0, shapeName.length() - suffix.length()) + : shapeName; ShapeId matchingOperationId = ShapeId.fromParts(shape.getId().getNamespace(), matchingOperationName); return model.shapes(OperationShape.class) diff --git a/src/test/java/software/amazon/smithy/lsp/ext/SmithyProjectTest.java b/src/test/java/software/amazon/smithy/lsp/ext/SmithyProjectTest.java index 407038d7..e7c68347 100644 --- a/src/test/java/software/amazon/smithy/lsp/ext/SmithyProjectTest.java +++ b/src/test/java/software/amazon/smithy/lsp/ext/SmithyProjectTest.java @@ -493,6 +493,14 @@ public void shapeIdFromLocationV2() throws Exception { new Position(160,8)).get()); assertEquals(ShapeId.from("com.example#OtherStructure"), project.getShapeIdFromLocation(testUri, new Position(7, 15)).get()); + assertEquals(ShapeId.from("com.foo#ShortI"), project.getShapeIdFromLocation(uri, + new Position(210,5)).get()); + assertEquals(ShapeId.from("com.foo#ShortI$c"), project.getShapeIdFromLocation(uri, + new Position(211,6)).get()); + assertEquals(ShapeId.from("com.foo#ShortO"), project.getShapeIdFromLocation(uri, + new Position(215,5)).get()); + assertEquals(ShapeId.from("com.foo#ShortO$d"), project.getShapeIdFromLocation(uri, + new Position(216,6)).get()); } } diff --git a/src/test/resources/software/amazon/smithy/lsp/ext/models/v2/main.smithy b/src/test/resources/software/amazon/smithy/lsp/ext/models/v2/main.smithy index 93485a2f..d6a0e9ce 100644 --- a/src/test/resources/software/amazon/smithy/lsp/ext/models/v2/main.smithy +++ b/src/test/resources/software/amazon/smithy/lsp/ext/models/v2/main.smithy @@ -201,3 +201,18 @@ structure FalseInlinedReversedBarOutput { @trait structure emptyTraitStruct {} + +operation ShortInputOutput { + output: ShortO + input: ShortI +} + +@input +structure ShortI { + c: String +} + +@output +structure ShortO { + d: String +} \ No newline at end of file