Skip to content

Commit ff75f00

Browse files
committed
TODO:
1 parent fe212ff commit ff75f00

File tree

25 files changed

+486
-147
lines changed

25 files changed

+486
-147
lines changed

PROMPT.txt

+3-1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ example error message:
6464

6565
The target audience of this would be students from the Philippines who don't know how to read the error messages or does not know how to do debugging. They also have a short attention span so longer explanations do not work for them. This is learning by doing so make them understand and gradually do not rely on this tool.
6666

67+
---
68+
6769
The expected output should be a unit test case which consists of a sample test program and test template. The format should be like this (STICK TO THIS!):
6870

6971
Source code:
@@ -85,4 +87,4 @@ template: "{{language}}.{{error_code}}"
8587

8688
Notes:
8789
- Filename / class name should be short
88-
- No need to add comments in the source code. Make it simple to reproduce as possible
90+
- No need to add comments in the source code. Make it simple to reproduce as possible

errgoengine.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ type ErrgoEngine struct {
1313
SharedStore *Store
1414
ErrorTemplates ErrorTemplates
1515
FS fs.ReadFileFS
16-
OutputGen OutputGenerator
16+
OutputGen *OutputGenerator
1717
}
1818

1919
func New() *ErrgoEngine {
2020
return &ErrgoEngine{
2121
SharedStore: NewEmptyStore(),
2222
ErrorTemplates: ErrorTemplates{},
2323
FS: &RawFS{},
24-
OutputGen: &MarkdownOutputGenerator{},
24+
OutputGen: &OutputGenerator{},
2525
}
2626
}
2727

error_templates/java/arithmetic_exception.go

+68-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package java
22

3-
import lib "github.com/nedpals/errgoengine"
3+
import (
4+
"strings"
5+
6+
lib "github.com/nedpals/errgoengine"
7+
)
48

59
type arithExceptionKind int
610

@@ -20,29 +24,87 @@ var ArithmeticException = lib.ErrorTemplate{
2024
OnAnalyzeErrorFn: func(cd *lib.ContextData, err *lib.MainError) {
2125
ctx := arithExceptionCtx{}
2226
reason := cd.Variables["reason"]
27+
query := ""
28+
2329
switch reason {
2430
case "/ by zero":
2531
ctx.kind = dividedByZero
32+
query = "(_) \"/\" ((decimal_integer_literal) @literal (#eq? @literal \"0\"))"
2633
case "Non-terminating decimal expansion; no exact representable decimal result.":
2734
ctx.kind = nonTerminatingDecimal
35+
query = "(method_invocation) @methodCall (#eq? @methodCall \".divide\")"
2836
default:
2937
ctx.kind = unknown
3038
}
39+
40+
if len(query) != 0 {
41+
lib.QueryNode(cd.MainError.Nearest, strings.NewReader(query), func(ctx lib.QueryNodeCtx) bool {
42+
match := ctx.Cursor.FilterPredicates(ctx.Match, []byte(cd.MainError.Nearest.Doc.Contents))
43+
for _, c := range match.Captures {
44+
node := lib.WrapNode(cd.MainError.Nearest.Doc, c.Node)
45+
err.Nearest = node
46+
return false
47+
}
48+
return true
49+
})
50+
}
51+
3152
err.Context = ctx
3253
},
3354
OnGenExplainFn: func(cd *lib.ContextData, gen *lib.ExplainGenerator) {
3455
ctx := cd.MainError.Context.(arithExceptionCtx)
3556
switch ctx.kind {
3657
case dividedByZero:
37-
ctx.kind = dividedByZero
38-
gen.Add("One of your variables initialized a double value by dividing a number to zero")
58+
gen.Add("This error is raised when you try to perform arithmetic operations that are not mathematically possible, such as division by zero.")
3959
case nonTerminatingDecimal:
40-
gen.Add("TODO")
60+
gen.Add("This error is raised when dividing two `BigDecimal` numbers, and the division operation results in a non-terminating decimal expansion, meaning the division produces a non-repeating and non-terminating decimal.")
4161
case unknown:
42-
gen.Add("Unknown ArithmeticException")
62+
gen.Add("You just encountered an unknown `ArithmeticException` error of which we cannot explain to you properly.")
4363
}
4464
},
4565
OnGenBugFixFn: func(cd *lib.ContextData, gen *lib.BugFixGenerator) {
46-
// TODO:
66+
ctx := cd.MainError.Context.(arithExceptionCtx)
67+
switch ctx.kind {
68+
case dividedByZero:
69+
gen.Add("Avoid dividing by zero.", func(s *lib.BugFixSuggestion) {
70+
s.AddStep("To fix the 'ArithmeticException: / by zero', you need to ensure you are not dividing by zero, which is mathematically undefined.").
71+
AddFix(lib.SuggestedFix{
72+
NewText: "1",
73+
Description: "This adjustment replaces the division by zero with a value that is not zero, ensuring the operation is valid. Division by zero is mathematically undefined, causing an 'ArithmeticException'. By changing the denominator to a non-zero value, you prevent the error.",
74+
StartPosition: cd.MainError.Nearest.StartPosition(),
75+
EndPosition: cd.MainError.Nearest.EndPosition(),
76+
Replace: true,
77+
})
78+
})
79+
case nonTerminatingDecimal:
80+
gen.Add("Ensure precise division", func(s *lib.BugFixSuggestion) {
81+
s.AddStep("To fix the 'ArithmeticException: Non-terminating decimal expansion', you need to ensure the division operation is precise.").
82+
AddFix(lib.SuggestedFix{
83+
NewText: ", RoundingMode.HALF_UP)",
84+
StartPosition: cd.MainError.Nearest.EndPosition(),
85+
EndPosition: cd.MainError.Nearest.EndPosition(),
86+
Replace: true,
87+
})
88+
})
89+
90+
if parent := cd.MainError.Nearest.Parent(); parent.Type() == "block" {
91+
gen.Add("Catch ArithmeticException", func(s *lib.BugFixSuggestion) {
92+
firstChild := parent.FirstNamedChild()
93+
lastChild := parent.LastNamedChild()
94+
95+
s.AddStep("Handle the ArithmeticException by wrapping the division operation in a try-catch block to manage the potential exception and inform the user about the non-terminating result.").
96+
AddFix(lib.SuggestedFix{
97+
NewText: "try {",
98+
StartPosition: firstChild.StartPosition(),
99+
EndPosition: firstChild.StartPosition(),
100+
}).
101+
AddFix(lib.SuggestedFix{
102+
NewText: "} catch (ArithmeticException e) {\n\tSystem.out.println(\"Non-terminating result: \" + e.getMessage());\n}",
103+
StartPosition: lastChild.StartPosition(),
104+
EndPosition: lastChild.StartPosition(),
105+
})
106+
})
107+
}
108+
}
47109
},
48110
}
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,46 @@
11
package java
22

33
import (
4+
"fmt"
5+
"strconv"
6+
"strings"
7+
48
lib "github.com/nedpals/errgoengine"
59
)
610

711
var ArrayIndexOutOfBoundsException = lib.ErrorTemplate{
812
Name: "ArrayIndexOutOfBoundsException",
913
Pattern: runtimeErrorPattern("java.lang.ArrayIndexOutOfBoundsException", `Index (?P<index>\d+) out of bounds for length (?P<length>\d+)`),
14+
OnAnalyzeErrorFn: func(cd *lib.ContextData, m *lib.MainError) {
15+
lib.QueryNode(m.Nearest, strings.NewReader("(array_access index: (_) @index)"), func(ctx lib.QueryNodeCtx) bool {
16+
match := ctx.Cursor.FilterPredicates(ctx.Match, []byte(m.Nearest.Doc.Contents))
17+
for _, c := range match.Captures {
18+
node := lib.WrapNode(m.Nearest.Doc, c.Node)
19+
m.Nearest = node
20+
return false
21+
}
22+
return true
23+
})
24+
},
1025
OnGenExplainFn: func(cd *lib.ContextData, gen *lib.ExplainGenerator) {
11-
// TODO:
12-
gen.Add("Your program attempted to access an element in index %s on an array that only has %s items", cd.Variables["index"], cd.Variables["length"])
26+
gen.Add("This error occurs because the code is trying to access index %s that is beyond the bounds of the array which only has %s items.", cd.Variables["index"], cd.Variables["length"])
1327
},
1428
OnGenBugFixFn: func(cd *lib.ContextData, gen *lib.BugFixGenerator) {
15-
// TODO:
29+
arrayLen, _ := strconv.Atoi(cd.Variables["length"])
30+
31+
// TODO: add a suggestion to add an if statement if the array length is 0
32+
33+
gen.Add("Accessing Array Index Within Bounds", func(s *lib.BugFixSuggestion) {
34+
sampleIndex := max(0, arrayLen-2)
35+
36+
s.AddStep("The error is caused by trying to access an index that does not exist within the array. Instead of accessing index %s, which is beyond the array's length, change it to a valid index within the array bounds, for example, `nums[%d]`.", cd.Variables["index"], sampleIndex).
37+
AddFix(lib.SuggestedFix{
38+
NewText: fmt.Sprintf("%d", sampleIndex),
39+
StartPosition: cd.MainError.Nearest.StartPosition(),
40+
EndPosition: cd.MainError.Nearest.EndPosition(),
41+
Replace: true,
42+
Description: "This adjustment ensures that you're accessing an index that exists within the array bounds, preventing the `ArrayIndexOutOfBoundsException`.",
43+
})
44+
})
1645
},
1746
}

error_templates/java/test_files/arithmetic_exception/test.txt

-19
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: "DivisionByZero"
2+
template: "Java.ArithmeticException"
3+
---
4+
Exception in thread "main" java.lang.ArithmeticException: / by zero
5+
at Arith.main(Arith.java:3)
6+
===
7+
template: "Java.ArithmeticException"
8+
---
9+
# ArithmeticException
10+
This error is raised when you try to perform arithmetic operations that are not mathematically possible, such as division by zero.
11+
```
12+
public static void main(String[] args) {
13+
double out = 3 / 0;
14+
^
15+
System.out.println(out);
16+
}
17+
}
18+
```
19+
## Steps to fix
20+
### Avoid dividing by zero.
21+
To fix the 'ArithmeticException: / by zero', you need to ensure you are not dividing by zero, which is mathematically undefined.
22+
```diff
23+
public class Arith {
24+
public static void main(String[] args) {
25+
- double out = 3 / 0;
26+
+ double out = 3 / 1;
27+
System.out.println(out);
28+
}
29+
```
30+
This adjustment replaces the division by zero with a value that is not zero, ensuring the operation is valid. Division by zero is mathematically undefined, causing an 'ArithmeticException'. By changing the denominator to a non-zero value, you prevent the error.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import java.math.BigDecimal;
2+
3+
public class ArithEx {
4+
public static void main(String[] args) {
5+
BigDecimal a = new BigDecimal(5);
6+
BigDecimal b = new BigDecimal(3);
7+
BigDecimal result = a.divide(b);
8+
System.out.println(result);
9+
}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: "NonterminatingDecimal"
2+
template: "Java.ArithmeticException"
3+
---
4+
Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
5+
at java.base/java.math.BigDecimal.divide(BigDecimal.java:1722)
6+
at ArithEx.main(ArithEx.java:7)
7+
===
8+
template: "Java.ArithmeticException"
9+
---
10+
# ArithmeticException
11+
This error is raised when dividing two `BigDecimal` numbers, and the division operation results in a non-terminating decimal expansion, meaning the division produces a non-repeating and non-terminating decimal.
12+
13+
## Steps to fix
14+
### 1. Ensure precise division
15+
Adjust the division operation to ensure precision by specifying the scale and rounding mode for the `BigDecimal` division.
16+
17+
```diff
18+
BigDecimal a = new BigDecimal(5);
19+
BigDecimal b = new BigDecimal(3);
20+
- BigDecimal result = a.divide(b);
21+
+ BigDecimal result = a.divide(b, 10, RoundingMode.HALF_UP);
22+
System.out.println(result);
23+
```
24+
25+
### 2. Catch ArithmeticException
26+
Handle the ArithmeticException by wrapping the division operation in a try-catch block to manage the potential exception and inform the user about the non-terminating result.
27+
28+
```diff
29+
+ try {
30+
BigDecimal a = new BigDecimal(5);
31+
BigDecimal b = new BigDecimal(3);
32+
BigDecimal result = a.divide(b);
33+
System.out.println(result);
34+
+ } catch (ArithmeticException e) {
35+
+ System.out.println("Non-terminating result: " + e.getMessage());
36+
+ }
37+
```
38+
39+
This change introduces a try block to execute the division operation and catches any ArithmeticException that might occur, allowing you to manage the exception and inform the user about the non-terminating result.
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
public class OOB {
2-
public static void main(String[] args) {
3-
int nums[] = {1,2,3,4};
4-
System.out.println(nums[5]);
5-
}
2+
public static void main(String[] args) {
3+
int nums[] = {1,2,3,4};
4+
System.out.println(nums[5]);
5+
}
66
}

error_templates/java/test_files/array_index_out_of_bounds/test.txt

+17-19
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,23 @@ Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out
66
template: "Java.ArrayIndexOutOfBoundsException"
77
---
88
# ArrayIndexOutOfBoundsException
9-
This error occurs because the program is attempting to access an element in an array at an index that does not exist.
10-
11-
## Steps to fix
12-
1. **Understanding the issue:** The error is due to the attempt to access the element at index 5 in an array that has a length of 4. Array indices start from 0, so in an array of length 4, the valid indices are from 0 to 3.
13-
14-
```diff
15-
- System.out.println(nums[5]);
16-
+ // Accessing an index beyond the array length causes the ArrayIndexOutOfBoundsException.
9+
This error occurs because the code is trying to access index 5 that is beyond the bounds of the array which only has 4 items.
1710
```
18-
19-
## Steps to fix (Alternative)
20-
1. **Avoid accessing out-of-bounds index:** To fix this, ensure that the index used to access the array elements is within the bounds of the array (0 to array length - 1).
21-
11+
int nums[] = {1,2,3,4};
12+
System.out.println(nums[5]);
13+
^
14+
}
15+
}
16+
```
17+
## Steps to fix
18+
### Accessing Array Index Within Bounds
19+
The error is caused by trying to access an index that does not exist within the array. Instead of accessing index 5, which is beyond the array's length, change it to a valid index within the array bounds, for example, `nums[2]`.
2220
```diff
23-
public static void main(String[] args) {
24-
int nums[] = {1,2,3,4};
25-
- System.out.println(nums[5]);
26-
+ // Ensure the index is within the array bounds.
27-
}
21+
public static void main(String[] args) {
22+
int nums[] = {1,2,3,4};
23+
- System.out.println(nums[5]);
24+
+ System.out.println(nums[2]);
25+
}
26+
}
2827
```
29-
30-
Remember, in Java arrays, indices start from 0, and the last index is always length - 1. Accessing an index beyond the array's length leads to an `ArrayIndexOutOfBoundsException`.
28+
This adjustment ensures that you're accessing an index that exists within the array bounds, preventing the `ArrayIndexOutOfBoundsException`.

error_templates/java/test_files/bracket_mismatch_error/test.txt

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,7 @@ BracketMismatch.java:7: error: '}' expected
44
System.out.println("x is greater than 5.");
55
^
66
1 error
7-
===
7+
===
8+
template: "Java.BracketMismatchError"
9+
---
10+
aaa

error_templates/java/test_files/cannot_be_applied_error/test.txt

+4
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,7 @@ CannotBeApplied.java:3: error: method addValues in class CannotBeApplied cannot
77
found: String,int
88
reason: argument mismatch; String cannot be converted to int
99
1 error
10+
===
11+
template: "Java.CannotBeAppliedError"
12+
---
13+
aa

error_templates/java/test_files/method_not_found_error/test.txt

+3
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,6 @@ Test.java:4: error: cannot find symbol
77
location: class Test
88
1 error
99
===
10+
template: "Java.MethodNotFoundError"
11+
---
12+
a

error_templates/java/test_files/no_class_def_error/test.txt

+4-1
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,7 @@ MyClass.java:5: error: cannot find symbol
1111
symbol: class NonExistingClass
1212
location: class MyClass
1313
2 errors
14-
===
14+
===
15+
template: "Java.NoClassDefError"
16+
---
17+
a

error_templates/java/unknown_variable_error.go

+11-3
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,16 @@ var UnknownVariableError = lib.ErrorTemplate{
3737
OnGenBugFixFn: func(cd *lib.ContextData, gen *lib.BugFixGenerator) {
3838
ctx := cd.MainError.Context.(unknownVarErrorCtx)
3939
variable := cd.Variables["variable"]
40-
gen.AddStep("(%s) Create a variable named \"%s\". For example: ", ctx.parentNode.Type(), variable).
41-
// TODO: use variable type from the inferred parameter
42-
AddFix(fmt.Sprintf("String %s = \"\";", variable), ctx.rootNode.StartPosition(), false)
40+
41+
gen.Add("Create a variable.", func(s *lib.BugFixSuggestion) {
42+
s.AddStep("(%s) Create a variable named \"%s\". For example: ", ctx.parentNode.Type(), variable).
43+
// TODO: use variable type from the inferred parameter
44+
AddFix(lib.SuggestedFix{
45+
NewText: fmt.Sprintf("String %s = \"\";", variable),
46+
StartPosition: ctx.rootNode.StartPosition(),
47+
EndPosition: ctx.rootNode.StartPosition(),
48+
Replace: false,
49+
})
50+
})
4351
},
4452
}

0 commit comments

Comments
 (0)