Skip to content

Commit

Permalink
feat: add UnclosedCharacterLiteralError
Browse files Browse the repository at this point in the history
  • Loading branch information
nedpals committed Nov 25, 2023
1 parent 230a55a commit 3c6dd3c
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,32 @@ UnclosedCharacterLiteralError.java:4: error: unclosed character literal
template: "Java.UnclosedCharacterLiteralError"
---
# UnclosedCharacterLiteralError
This error occurs because the character literal in the code is not correctly closed. In Java, character literals should contain only a single character enclosed in single quotes. However, in this case, 'Hello World' is a string and cannot be stored in a single character variable.

This error occurs when there's an attempt to define a character literal with more than one character, or if the character literal is not closed properly.
```
public static void main(String[] args) {
char ch = 'Hello World'; // This will cause an error because the character literal is not closed.
^^^^^^^^^^^^^
}
}
```
## Steps to fix
1. Change the variable type from `char` to `String` as 'Hello World' is a string.
### 1. Store as a String
The character literal should contain only one character. If you intend to store a string, use double quotes (`"`).
```diff
public static void main(String[] args) {
- char ch = 'Hello World'; // This will cause an error because the character literal is not closed.
+ String ch = "Hello World"; // Change the variable type to String for a string value.
- char ch = 'Hello World'; // This will cause an error because the character literal is not closed.
+ String ch = "Hello World"; // This will cause an error because the character literal is not closed.
}
}
```

2. If you want to store a single character, correct the character literal to contain only one character within single quotes.
### 2. Use single quotes for characters
If you want to store a single character, ensure that you use single quotes (`'`).
```diff
public static void main(String[] args) {
- char ch = 'Hello World'; // This will cause an error because the character literal is not closed.
+ char ch = 'H'; // Store a single character within single quotes.
- char ch = 'Hello World'; // This will cause an error because the character literal is not closed.
+ char ch = 'H'; // This will cause an error because the character literal is not closed.
}
}
```

The error message highlights an attempt to assign multiple characters within single quotes to a `char` variable, which causes the "UnclosedCharacterLiteralError". To fix this, either change the variable type to `String` or ensure that only a single character is enclosed within the single quotes for a `char` variable.
83 changes: 80 additions & 3 deletions error_templates/java/unclosed_character_literal_error.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,92 @@
package java

import lib "github.com/nedpals/errgoengine"
import (
"fmt"
"strings"

lib "github.com/nedpals/errgoengine"
)

type unclosedCharacterLiteralErrorCtx struct {
parent lib.SyntaxNode
}

var UnclosedCharacterLiteralError = lib.ErrorTemplate{
Name: "UnclosedCharacterLiteralError",
Pattern: comptimeErrorPattern(`unclosed character literal`),
StackTracePattern: comptimeStackTracePattern,
OnAnalyzeErrorFn: func(cd *lib.ContextData, err *lib.MainError) {
err.Context = unclosedCharacterLiteralErrorCtx{
parent: err.Nearest,
}

if err.Nearest.Type() == "character_literal" {
return
}

lib.QueryNode(err.Nearest, strings.NewReader("(character_literal) @literal"), func(ctx lib.QueryNodeCtx) bool {
for _, c := range ctx.Match.Captures {
node := lib.WrapNode(err.Document, c.Node)
err.Nearest = node
return false
}
return true
})
},
OnGenExplainFn: func(cd *lib.ContextData, gen *lib.ExplainGenerator) {
gen.Add("Unclosed character literal")
gen.Add("This error occurs when there's an attempt to define a character literal with more than one character, or if the character literal is not closed properly.")
},
OnGenBugFixFn: func(cd *lib.ContextData, gen *lib.BugFixGenerator) {
// TODO:
ctx := cd.MainError.Context.(unclosedCharacterLiteralErrorCtx)
valueNode := cd.MainError.Nearest

if ctx.parent.Type() == "local_variable_declaration" {
if isString := len(valueNode.Text()) > 1; isString {
valueStartPos := valueNode.StartPosition()
valueEndPos := valueNode.EndPosition()

gen.Add("Store as a String", func(s *lib.BugFixSuggestion) {
typeNode := ctx.parent.ChildByFieldName("type")

s.AddStep("The character literal should contain only one character. If you intend to store a string, use double quotes (`\"`).").
AddFix(lib.FixSuggestion{
NewText: "String",
StartPosition: typeNode.StartPosition(),
EndPosition: typeNode.EndPosition(),
}).
AddFix(lib.FixSuggestion{
NewText: "\"",
StartPosition: lib.Position{
Line: valueStartPos.Line,
Column: valueStartPos.Column,
},
EndPosition: lib.Position{
Line: valueEndPos.Line,
Column: valueStartPos.Column + 1,
},
}).
AddFix(lib.FixSuggestion{
NewText: "\"",
StartPosition: lib.Position{
Line: valueStartPos.Line,
Column: valueEndPos.Column - 1,
},
EndPosition: lib.Position{
Line: valueEndPos.Line,
Column: valueEndPos.Column,
},
})
})

gen.Add("Use single quotes for characters", func(s *lib.BugFixSuggestion) {
s.AddStep("If you want to store a single character, ensure that you use single quotes (`'`).").
AddFix(lib.FixSuggestion{
NewText: fmt.Sprintf("'%c'", valueNode.Text()[1]),
StartPosition: valueStartPos,
EndPosition: valueEndPos,
})
})
}
}
},
}

0 comments on commit 3c6dd3c

Please sign in to comment.