Skip to content

Commit

Permalink
feat: implement Java.OperatorCannotBeAppliedError template
Browse files Browse the repository at this point in the history
  • Loading branch information
nedpals committed Dec 12, 2023
1 parent 492d7b6 commit d519b0d
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 0 deletions.
1 change: 1 addition & 0 deletions error_templates/java/java.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ func LoadErrorTemplates(errorTemplates *lib.ErrorTemplates) {
errorTemplates.MustAdd(java.Language, SymbolNotFoundError)
errorTemplates.MustAdd(java.Language, NonStaticMethodAccessError)
errorTemplates.MustAdd(java.Language, UnclosedCharacterLiteralError)
errorTemplates.MustAdd(java.Language, OperatorCannotBeAppliedError)
}

func runtimeErrorPattern(errorName string, pattern string) string {
Expand Down
75 changes: 75 additions & 0 deletions error_templates/java/operator_cannot_be_applied_error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package java

import (
"fmt"
"strings"

lib "github.com/nedpals/errgoengine"
)

type opCannotBeAppliedCtx struct {
Parent lib.SyntaxNode
}

var OperatorCannotBeAppliedError = lib.ErrorTemplate{
Name: "OperatorCannotBeAppliedError",
Pattern: comptimeErrorPattern("bad operand types for binary operator '(?P<operator>.)'", `first type\:\s+(?P<firstType>\S+)\s+second type\:\s+(?P<secondType>\S+)`),
StackTracePattern: comptimeStackTracePattern,
OnAnalyzeErrorFn: func(cd *lib.ContextData, m *lib.MainError) {
oCtx := opCannotBeAppliedCtx{}
operator := cd.Variables["operator"]
query := fmt.Sprintf(`((binary_expression) @binary_expr (#eq @binary_expr "%s"))`, operator)
lib.QueryNode(m.Nearest, 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)
oCtx.Parent = node
m.Nearest = node.Child(1)
return false
}
return true
})
m.Context = oCtx
},
OnGenExplainFn: func(cd *lib.ContextData, gen *lib.ExplainGenerator) {
gen.Add(
"This error occurs when you try to apply a binary operator to incompatible operand types, such as trying to use the '%s' operator between a %s and an %s.",
cd.Variables["operator"],
cd.Variables["firstType"],
cd.Variables["secondType"],
)
},
OnGenBugFixFn: func(cd *lib.ContextData, gen *lib.BugFixGenerator) {
ctx := cd.MainError.Context.(opCannotBeAppliedCtx)
left := ctx.Parent.ChildByFieldName("left")
right := ctx.Parent.ChildByFieldName("right")

gen.Add(fmt.Sprintf("Use %s's compareTo method", cd.Variables["firstType"]), func(s *lib.BugFixSuggestion) {

s.AddStep(
"Since you are comparing a %s and an %s, you need to use the `compareTo` method to compare their values.",
cd.Variables["firstType"],
cd.Variables["secondType"],
).AddFix(lib.FixSuggestion{
NewText: ".compareTo(String.valueOf(" + right.Text() + "))",
StartPosition: left.EndPosition(),
EndPosition: left.EndPosition(),
Description: "The `compareTo` method returns a negative integer if the calling string is lexicographically less than the argument string.",
})
})

gen.Add(fmt.Sprintf("Convert %s to %s for direct comparison", cd.Variables["secondType"], cd.Variables["firstType"]), func(s *lib.BugFixSuggestion) {
s.AddStep(
"If you want to compare them directly, convert the %s to %s using `%s.valueOf()`.",
cd.Variables["secondType"],
cd.Variables["firstType"],
cd.Variables["firstType"],
).AddFix(lib.FixSuggestion{
Description: "This ensures both operands are of the same type for comparison.",
NewText: ".equals(" + cd.Variables["firstType"] + ".valueOf(" + right.Text() + "))",
StartPosition: left.EndPosition(),
EndPosition: ctx.Parent.EndPosition(),
})
})
},
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
public class OperatorCannotBeApplied {
public static void main(String[] args) {
String text = "Hello";
int number = 5;

// Operator '<' cannot be applied to String and int
if (text < number) {}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
template: "Java.OperatorCannotBeAppliedError"
---
OperatorCannotBeApplied.java:7: error: bad operand types for binary operator '<'
if (text < number) {}
^
first type: String
second type: int
1 error
===
template: "Java.OperatorCannotBeAppliedError"
---
# OperatorCannotBeAppliedError
This error occurs when you try to apply a binary operator to incompatible operand types, such as trying to use the '<' operator between a String and an int.
```
// Operator '<' cannot be applied to String and int
if (text < number) {}
^
}
}
```
## Steps to fix
### 1. Use String's compareTo method
Since you are comparing a String and an int, you need to use the `compareTo` method to compare their values.
```diff

// Operator '<' cannot be applied to String and int
- if (text < number) {}
+ if (text.compareTo(String.valueOf(number)) < number) {}
}
}
```
The `compareTo` method returns a negative integer if the calling string is lexicographically less than the argument string.

### 2. Convert int to String for direct comparison
If you want to compare them directly, convert the int to String using `String.valueOf()`.
```diff

// Operator '<' cannot be applied to String and int
- if (text < number) {}
+ if (text.equals(String.valueOf(number))) {}
}
}
```
This ensures both operands are of the same type for comparison.

0 comments on commit d519b0d

Please sign in to comment.