From 5bebaebcc06137755b0b78c0b51f65673033350d Mon Sep 17 00:00:00 2001 From: Sam Carlberg Date: Wed, 17 Dec 2025 01:23:30 -0500 Subject: [PATCH] [cmd3] Report incorrect coroutine usage on the variable use site (#8481) This makes error messages point directly at the variable use, instead of on the enclosing AST node: ``` error: `outerCoroutine` may not be in scope outerCoroutine.yield() ^ error: `outerCoroutine` may not be in scope consume(x, outerCoroutine); ^ ``` instead of ``` error: `outerCoroutine` may not be in scope outerCoroutine.yield() ^ error: `outerCoroutine` may not be in scope consume(x, outerCoroutine); ^ ``` --- .../wpilib/javacplugin/IncorrectCoroutineUseDetector.java | 7 +++++-- .../javacplugin/IncorrectCoroutineUseDetectorTest.java | 7 +++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/javacPlugin/src/main/java/org/wpilib/javacplugin/IncorrectCoroutineUseDetector.java b/javacPlugin/src/main/java/org/wpilib/javacplugin/IncorrectCoroutineUseDetector.java index fb786ad456..7dcbd2fb4e 100644 --- a/javacPlugin/src/main/java/org/wpilib/javacplugin/IncorrectCoroutineUseDetector.java +++ b/javacPlugin/src/main/java/org/wpilib/javacplugin/IncorrectCoroutineUseDetector.java @@ -145,7 +145,7 @@ public class IncorrectCoroutineUseDetector extends CoroutineBasedDetector { && ve.asType().equals(m_coroutineType) && !state.isLocalCoroutine(ve)) { m_trees.printMessage( - Diagnostic.Kind.ERROR, nonlocalCoroutineUsageMessage(ve, state), node, m_root); + Diagnostic.Kind.ERROR, nonlocalCoroutineUsageMessage(ve, state), id, m_root); } } @@ -157,7 +157,10 @@ public class IncorrectCoroutineUseDetector extends CoroutineBasedDetector { && ve.asType().equals(m_coroutineType) && !state.isLocalCoroutine(ve)) { m_trees.printMessage( - Diagnostic.Kind.ERROR, nonlocalCoroutineUsageMessage(ve, state), node, m_root); + Diagnostic.Kind.ERROR, + nonlocalCoroutineUsageMessage(ve, state), + argPath.getLeaf(), + m_root); } } diff --git a/javacPlugin/src/test/java/org/wpilib/javacplugin/IncorrectCoroutineUseDetectorTest.java b/javacPlugin/src/test/java/org/wpilib/javacplugin/IncorrectCoroutineUseDetectorTest.java index c719e7d1a3..652ae3838e 100644 --- a/javacPlugin/src/test/java/org/wpilib/javacplugin/IncorrectCoroutineUseDetectorTest.java +++ b/javacPlugin/src/test/java/org/wpilib/javacplugin/IncorrectCoroutineUseDetectorTest.java @@ -55,6 +55,7 @@ class IncorrectCoroutineUseDetectorTest { assertEquals( "Coroutine `outerCoroutine` may not be in scope. Consider using `innerCoroutine`", error.getMessage(null)); + assertEquals(7, error.getColumnNumber()); // leading "o" in "outerCoroutine.yield()" } @Test @@ -90,6 +91,8 @@ class IncorrectCoroutineUseDetectorTest { assertEquals( "Coroutine `outerCoroutine` may not be in scope. Consider using `innerCoroutine`", error.getMessage(null)); + // leading "o" in "outerCoroutine" passed to `method(outerCoroutine)` + assertEquals(14, error.getColumnNumber()); } @Test @@ -126,6 +129,8 @@ class IncorrectCoroutineUseDetectorTest { assertEquals( "Coroutine `outerCoroutine` may not be in scope. Consider using `a` or `b`", error.getMessage(null)); + // leading "o" in "outerCoroutine" passed to `method(outerCoroutine)` + assertEquals(14, error.getColumnNumber()); } @Test @@ -166,6 +171,8 @@ class IncorrectCoroutineUseDetectorTest { assertEquals( "Coroutine `outerCoroutine` may not be in scope. Consider using `a`, `b`, or `c`", error.getMessage(null)); + // leading "o" in "outerCoroutine" passed to `method(outerCoroutine)` + assertEquals(14, error.getColumnNumber()); } @Test