-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
277 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package java | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
|
||
lib "github.com/nedpals/errgoengine" | ||
) | ||
|
||
type missingReturnErrorCtx struct { | ||
NearestMethod lib.SyntaxNode | ||
} | ||
|
||
var MissingReturnError = lib.ErrorTemplate{ | ||
Name: "MissingReturnError", | ||
Pattern: comptimeErrorPattern(`missing return statement`), | ||
StackTracePattern: comptimeStackTracePattern, | ||
OnAnalyzeErrorFn: func(cd *lib.ContextData, m *lib.MainError) { | ||
// get nearest method declaration | ||
mCtx := missingReturnErrorCtx{} | ||
rootNode := lib.WrapNode(m.Document, m.Document.Tree.RootNode()) | ||
pos := m.ErrorNode.StartPos | ||
lib.QueryNode(rootNode, strings.NewReader("(method_declaration) @method"), func(ctx lib.QueryNodeCtx) bool { | ||
match := ctx.Cursor.FilterPredicates(ctx.Match, []byte(m.Nearest.Doc.Contents)) | ||
for _, c := range match.Captures { | ||
pointA := c.Node.StartPoint() | ||
pointB := c.Node.EndPoint() | ||
if uint32(pos.Line) >= pointA.Row+1 && uint32(pos.Line) <= pointB.Row+1 { | ||
node := lib.WrapNode(m.Nearest.Doc, c.Node) | ||
mCtx.NearestMethod = node | ||
return false | ||
} | ||
} | ||
return true | ||
}) | ||
fmt.Println(mCtx.NearestMethod.Text()) | ||
m.Context = mCtx | ||
}, | ||
OnGenExplainFn: func(cd *lib.ContextData, gen *lib.ExplainGenerator) { | ||
gen.Add("This error occurs when a method is declared to return a value, but there is no return statement within the method.") | ||
}, | ||
OnGenBugFixFn: func(cd *lib.ContextData, gen *lib.BugFixGenerator) { | ||
ctx := cd.MainError.Context.(missingReturnErrorCtx) | ||
|
||
// TODO | ||
gen.Add("Provide a return statement", func(s *lib.BugFixSuggestion) { | ||
bodyNode := ctx.NearestMethod.ChildByFieldName("body") | ||
lastStartPosInBlock := bodyNode.EndPosition() | ||
lastEndPosInBlock := bodyNode.EndPosition() | ||
if bodyNode.NamedChildCount() > 0 { | ||
lastStartPosInBlock = bodyNode.LastNamedChild().StartPosition() | ||
lastEndPosInBlock = bodyNode.LastNamedChild().EndPosition() | ||
} | ||
|
||
s.AddStep( | ||
"Since the `%s` method is declared to return an `%s`, you need to provide a return statement with the result", | ||
ctx.NearestMethod.ChildByFieldName("name").Text(), | ||
ctx.NearestMethod.ChildByFieldName("type").Text(), | ||
).AddFix(lib.FixSuggestion{ | ||
NewText: "\n" + cd.MainError.Document.LineAt(lastStartPosInBlock.Line)[:lastStartPosInBlock.Column] + fmt.Sprintf("return %s;", ctx.NearestMethod.ChildByFieldName("type").Text()), | ||
StartPosition: lastEndPosInBlock, | ||
EndPosition: lastEndPosInBlock, | ||
Description: "This ensures that the method returns the sum of the two input numbers.", | ||
}) | ||
}) | ||
|
||
gen.Add("Set the method return type to void", func(s *lib.BugFixSuggestion) { | ||
s.AddStep( | ||
"If you don't intend to return a value from the `%s` method, you can change its return type to `void`.", | ||
ctx.NearestMethod.ChildByFieldName("name").Text(), | ||
).AddFix(lib.FixSuggestion{ | ||
NewText: "void", | ||
StartPosition: ctx.NearestMethod.ChildByFieldName("type").StartPosition(), | ||
EndPosition: ctx.NearestMethod.ChildByFieldName("type").EndPosition(), | ||
Description: "This is appropriate if you're using the method for side effects rather than returning a value.", | ||
}) | ||
}) | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package java | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
|
||
lib "github.com/nedpals/errgoengine" | ||
) | ||
|
||
type privateAccessErrorCtx struct { | ||
ClassDeclarationNode lib.SyntaxNode | ||
} | ||
|
||
var PrivateAccessError = lib.ErrorTemplate{ | ||
Name: "PrivateAccessError", | ||
Pattern: comptimeErrorPattern(`(?P<field>\S+) has private access in (?P<class>\S+)`), | ||
StackTracePattern: comptimeStackTracePattern, | ||
OnAnalyzeErrorFn: func(cd *lib.ContextData, m *lib.MainError) { | ||
pCtx := privateAccessErrorCtx{} | ||
className := cd.Variables["class"] | ||
rootNode := lib.WrapNode(m.Nearest.Doc, m.Nearest.Doc.Tree.RootNode()) | ||
|
||
// locate the right node first | ||
query := fmt.Sprintf(`((field_access (identifier) . (identifier) @field-name) @field (#eq? @field-name "%s"))`, cd.Variables["field"]) | ||
lib.QueryNode(rootNode, strings.NewReader(query), func(ctx lib.QueryNodeCtx) bool { | ||
match := ctx.Cursor.FilterPredicates(ctx.Match, []byte(m.Nearest.Doc.Contents)) | ||
for _, c := range match.Captures { | ||
node := lib.WrapNode(m.Nearest.Doc, c.Node) | ||
m.Nearest = node | ||
return false | ||
} | ||
return true | ||
}) | ||
|
||
// get class declaration node | ||
classQuery := fmt.Sprintf(`(class_declaration name: (identifier) @class-name (#eq? @class-name "%s"))`, className) | ||
lib.QueryNode(rootNode, strings.NewReader(classQuery), func(ctx lib.QueryNodeCtx) bool { | ||
match := ctx.Cursor.FilterPredicates(ctx.Match, []byte(m.Nearest.Doc.Contents)) | ||
for _, c := range match.Captures { | ||
node := lib.WrapNode(m.Nearest.Doc, c.Node) | ||
pCtx.ClassDeclarationNode = node | ||
return false | ||
} | ||
return true | ||
}) | ||
|
||
m.Context = pCtx | ||
}, | ||
OnGenExplainFn: func(cd *lib.ContextData, gen *lib.ExplainGenerator) { | ||
gen.Add("This error occurs when you try to access a private variable from another class, which is not allowed.") | ||
}, | ||
OnGenBugFixFn: func(cd *lib.ContextData, gen *lib.BugFixGenerator) { | ||
// ctx := cd.MainError.Context.(privateAccessErrorCtx) | ||
fmt.Println(cd.MainError.Nearest.String()) | ||
fmt.Println(cd.Analyzer.AnalyzeNode(cd.MainError.Nearest)) | ||
|
||
gen.Add("Use a public accessor method", func(s *lib.BugFixSuggestion) { | ||
// methodCreatorSb := &strings.Builder{} | ||
|
||
// get return type of the private field | ||
|
||
// methodCreatorSb.WriteString("public ") | ||
|
||
// s.AddStep("To access a private variable from another class, create a public accessor method in `%s`", cd.Variables["class"]). | ||
// AddFix() | ||
}) | ||
}, | ||
} |
11 changes: 11 additions & 0 deletions
11
error_templates/java/test_files/missing_return_error/MissingReturn.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
public class MissingReturn { | ||
public int addNumbers(int a, int b) { | ||
// Missing return statement | ||
} | ||
|
||
public static void main(String[] args) { | ||
MissingReturn calculator = new MissingReturn(); | ||
int result = calculator.addNumbers(5, 7); | ||
System.out.println("Result: " + result); | ||
} | ||
} |
41 changes: 41 additions & 0 deletions
41
error_templates/java/test_files/missing_return_error/test.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
template: "Java.MissingReturnError" | ||
--- | ||
MissingReturn.java:4: error: missing return statement | ||
} | ||
^ | ||
1 error | ||
=== | ||
template: "Java.MissingReturnError" | ||
--- | ||
# MissingReturnError | ||
This error occurs when a method is declared to return a value, but there is no return statement within the method. | ||
``` | ||
// Missing return statement | ||
} | ||
^ | ||
|
||
public static void main(String[] args) { | ||
``` | ||
## Steps to fix | ||
### 1. Provide a return statement | ||
Since the `addNumbers` method is declared to return an `int`, you need to provide a return statement with the result. | ||
```diff | ||
public class MissingReturn { | ||
public int addNumbers(int a, int b) { | ||
- // Missing return statement | ||
+ // Missing return statement | ||
+ return a; | ||
} | ||
``` | ||
This ensures that the method returns the sum of the two input numbers. | ||
|
||
### 2. Set the method return type to void | ||
If you don't intend to return a value from the `addNumbers` method, you can change its return type to `void`. | ||
```diff | ||
public class MissingReturn { | ||
- public int addNumbers(int a, int b) { | ||
+ public void addNumbers(int a, int b) { | ||
// Missing return statement | ||
} | ||
``` | ||
This is appropriate if you're using the method for side effects rather than returning a value. |
12 changes: 12 additions & 0 deletions
12
error_templates/java/test_files/private_access_error/Main.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
public class Main { | ||
public static void main(String[] args) { | ||
AnotherClass anotherClass = new AnotherClass(); | ||
// Attempting to access a private variable from another class | ||
int value = anotherClass.privateVariable; | ||
System.out.println(value); | ||
} | ||
} | ||
|
||
class AnotherClass { | ||
private int privateVariable = 10; | ||
} |
39 changes: 39 additions & 0 deletions
39
error_templates/java/test_files/private_access_error/test.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
template: "Java.PrivateAccessError" | ||
--- | ||
Main.java:5: error: privateVariable has private access in AnotherClass | ||
int value = anotherClass.privateVariable; | ||
^ | ||
1 error | ||
=== | ||
template: "Java.PrivateAccessError" | ||
--- | ||
# AlreadyDefinedError | ||
This error occurs when you try to access a private variable from another class, which is not allowed. | ||
|
||
## Steps to fix | ||
### 1. Use a public accessor method | ||
1. To access a private variable from another class, create a public accessor method in `AnotherClass`. | ||
```diff | ||
+ public int getPrivateVariable() { | ||
+ return privateVariable; | ||
+ } | ||
``` | ||
2. Then, use this method to get the value in the `Main` class. | ||
```diff | ||
- int value = anotherClass.privateVariable; | ||
+ int value = anotherClass.getPrivateVariable(); | ||
``` | ||
This way, you respect encapsulation by using a method to access the private variable. | ||
|
||
### 2. Make the variable public (not recommended) | ||
1. If you must access the variable directly, you can make it public, but this is generally not recommended for maintaining encapsulation. | ||
```diff | ||
- private int privateVariable = 10; | ||
+ public int privateVariable = 10; | ||
``` | ||
2. Access it directly in the `Main` class. | ||
```diff | ||
- int value = anotherClass.privateVariable; | ||
+ int value = anotherClass.privateVariable; | ||
``` | ||
Choose the fix that aligns with your design principles. Using an accessor method is a better practice for encapsulation. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
{ | ||
"bugbuddy.path": "/Users/nedpals/Documents/coding/bugbuddy-proto/server/cmd/bugbuddy" | ||
"bugbuddy.path": "/Users/nedpals/Documents/coding/bugbuddy-proto/server/cmd/bugbuddy", | ||
"java.debug.settings.onBuildFailureProceed": true | ||
} |