diff --git a/error_templates/java/input_mismatch_exception.go b/error_templates/java/input_mismatch_exception.go new file mode 100644 index 0000000..6a0590b --- /dev/null +++ b/error_templates/java/input_mismatch_exception.go @@ -0,0 +1,109 @@ +package java + +import ( + "fmt" + + lib "github.com/nedpals/errgoengine" + sitter "github.com/smacker/go-tree-sitter" +) + +var scannerMethodsToTypes = map[string]string{ + "nextInt": "integer", + "nextLong": "long", + "nextByte": "byte", + "nextChar": "character", + "nextDouble": "double", + "nextFloat": "float", + "nextShort": "short", +} + +var InputMismatchException = lib.ErrorTemplate{ + Name: "InputMismatchException", + Pattern: runtimeErrorPattern("java.util.InputMismatchException", ""), + OnAnalyzeErrorFn: func(cd *lib.ContextData, m *lib.MainError) { + query := "(method_invocation object: (_) name: (identifier) @fn-name arguments: (argument_list) (#eq? @fn-name \"nextInt\"))" + for q := m.Nearest.Query(query); q.Next(); { + if q.CurrentTagName() != "fn-name" { + continue + } + + node := q.CurrentNode() + m.Nearest = node + } + }, + OnGenExplainFn: func(cd *lib.ContextData, gen *lib.ExplainGenerator) { + methodName := cd.MainError.Nearest.Text() + expectedType := scannerMethodsToTypes[methodName] + gen.Add( + "This error occurs when a non-%s input is passed to the `%s()` method of the `Scanner` class.", + expectedType, + methodName) + }, + OnGenBugFixFn: func(cd *lib.ContextData, gen *lib.BugFixGenerator) { + // get nearest block from position + cursor := sitter.NewTreeCursor(cd.MainError.Document.RootNode().Node) + rawNearestBlock := nearestNodeFromPosByType(cursor, "block", cd.MainError.Nearest.StartPosition()) + + if rawNearestBlock != nil && !rawNearestBlock.IsNull() { + nearestBlock := lib.WrapNode(cd.MainError.Document, rawNearestBlock) + + gen.Add("Add a try-catch for error handling", func(s *lib.BugFixSuggestion) { + step := s.AddStep("Implement error handling to account for input mismatches and prompt the user for valid input.") + + wrapStatement( + step, + "try {", + "} catch (InputMismatchException e) {\n\tSystem.out.println(\"Invalid input. Please try again.\");\n\t}", + lib.Location{ + StartPos: lib.Position{ + Line: nearestBlock.FirstNamedChild().StartPosition().Line, + }, + EndPos: nearestBlock.LastNamedChild().EndPosition(), + }, + true, + ) + }) + } + }, +} + +func nearestNodeFromPosByType(cursor *sitter.TreeCursor, expType string, pos lib.Position) *sitter.Node { + cursor.GoToFirstChild() + defer cursor.GoToParent() + + var nearest *sitter.Node + + for { + currentNode := cursor.CurrentNode() + pointA := currentNode.StartPoint() + pointB := currentNode.EndPoint() + + fmt.Println(currentNode.Type(), currentNode.StartByte()) + + // stop if node is above the position + if uint32(pos.Line) < pointA.Row+1 { + break + } + + // check if the current node is the nearest + if currentNode.Type() == expType && uint32(pos.Line) >= pointA.Row+1 && uint32(pos.Line) <= pointB.Row+1 { + nearest = currentNode + } + + if currentNode.ChildCount() != 0 && uint32(pos.Line) >= pointA.Row+1 && uint32(pos.Line) <= pointB.Row+1 { + nearestFromInner := nearestNodeFromPosByType(cursor, expType, pos) + // check if the nearest from the inner nodes is nearer than the current nearest + if nearestFromInner != nil && !nearestFromInner.IsNull() { + nearest = nearestFromInner + } + } + + if !cursor.GoToNextSibling() { + break + } + + fmt.Println("next") + } + + return nearest +} diff --git a/error_templates/java/java.go b/error_templates/java/java.go index 6903198..74a6d54 100644 --- a/error_templates/java/java.go +++ b/error_templates/java/java.go @@ -19,6 +19,7 @@ func LoadErrorTemplates(errorTemplates *lib.ErrorTemplates) { errorTemplates.MustAdd(java.Language, StringIndexOutOfBoundsException) errorTemplates.MustAdd(java.Language, NoSuchElementException) errorTemplates.MustAdd(java.Language, NumberFormatException) + errorTemplates.MustAdd(java.Language, InputMismatchException) // Compile time errorTemplates.MustAdd(java.Language, PublicClassFilenameMismatchError) diff --git a/error_templates/java/test_files/input_mismatch_exception/Main.java b/error_templates/java/test_files/input_mismatch_exception/Main.java new file mode 100644 index 0000000..c7d627e --- /dev/null +++ b/error_templates/java/test_files/input_mismatch_exception/Main.java @@ -0,0 +1,10 @@ +import java.util.Scanner; + +public class Main { + public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); + System.out.print("Enter an integer: "); + int number = scanner.nextInt(); // Error: InputMismatchException for non-integer input + System.out.println("You entered: " + number); + } +} diff --git a/error_templates/java/test_files/input_mismatch_exception/test.txt b/error_templates/java/test_files/input_mismatch_exception/test.txt new file mode 100644 index 0000000..ad6fc96 --- /dev/null +++ b/error_templates/java/test_files/input_mismatch_exception/test.txt @@ -0,0 +1,41 @@ +template: "Java.InputMismatchException" +--- +Exception in thread "main" java.util.InputMismatchException + at java.base/java.util.Scanner.throwFor(Scanner.java:947) + at java.base/java.util.Scanner.next(Scanner.java:1602) + at java.base/java.util.Scanner.nextInt(Scanner.java:2267) + at java.base/java.util.Scanner.nextInt(Scanner.java:2221) + at Main.main(Main.java:7) +=== +template: "Java.InputMismatchException" +--- +# InputMismatchException +This error occurs when a non-integer input is passed to the `nextInt()` method of the `Scanner` class. +``` + System.out.print("Enter an integer: "); + int number = scanner.nextInt(); // Error: InputMismatchException for non-integer input + ^^^^^^^ + System.out.println("You entered: " + number); + } +``` +## Steps to fix +### Add a try-catch for error handling +Implement error handling to account for input mismatches and prompt the user for valid input. +```diff +public class Main { + public static void main(String[] args) { +- Scanner scanner = new Scanner(System.in); +- System.out.print("Enter an integer: "); +- int number = scanner.nextInt(); // Error: InputMismatchException for non-integer input +- System.out.println("You entered: " + number); ++ try { ++ Scanner scanner = new Scanner(System.in); ++ System.out.print("Enter an integer: "); ++ int number = scanner.nextInt(); // Error: InputMismatchException for non-integer input ++ System.out.println("You entered: " + number); ++ } catch (InputMismatchException e) { ++ System.out.println("Invalid input. Please try again."); ++ } + } +} +```