-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
10738: Go and Python codegen support symbols with hyphens in their names r=iwahbe a=mattolenik # Description This change enables the fix for pulumi/crd2pulumi#43, wherein hyphens `-` were mishandled and led to generation of invalid Go and Python. For example, code such as `func My-Thing() {}` or `class My-Thing`. This change improves the existing casing functions and extracts them to a new subpackage, `cgstrings`. Resolves pulumi/crd2pulumi#43. When this change is merged `go get -u` will fix the crd2pulumi issue. ## Checklist <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works Co-authored-by: Matthew Olenik <molenik@pulumi.com> Co-authored-by: Ian Wahbe <ian@wahbe.com>
- Loading branch information
Showing
27 changed files
with
1,351 additions
and
44 deletions.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// package cgstrings has various string processing functions that are useful during code generation. | ||
package cgstrings | ||
|
||
import ( | ||
"strings" | ||
"unicode" | ||
) | ||
|
||
// Unhyphenate removes all hyphens from s, then uppercasing the letter following each hyphen. | ||
// For example, "abc-def-ghi" becomes "abcDefGhi". | ||
func Unhyphenate(str string) string { | ||
return ModifyStringAroundDelimeter(str, "-", UppercaseFirst) | ||
} | ||
|
||
// Camel converts s to camelCase. | ||
func Camel(s string) string { | ||
if s == "" { | ||
return "" | ||
} | ||
s = Unhyphenate(s) | ||
runes := []rune(s) | ||
res := make([]rune, 0, len(runes)) | ||
for i, r := range runes { | ||
if unicode.IsLower(r) { | ||
res = append(res, runes[i:]...) | ||
break | ||
} | ||
res = append(res, unicode.ToLower(r)) | ||
} | ||
return string(res) | ||
} | ||
|
||
// UppercaseFirst uppercases the first letter of s. | ||
// E.g. "abc" -> "Abc" | ||
func UppercaseFirst(s string) string { | ||
if s == "" { | ||
return "" | ||
} | ||
runes := []rune(s) | ||
runes[0] = unicode.ToUpper(runes[0]) | ||
return string(runes) | ||
} | ||
|
||
func ModifyStringAroundDelimeter(str, delim string, modifyNext func(next string) string) string { | ||
if delim == "" { | ||
return str | ||
} | ||
i := strings.Index(str, delim) | ||
if i < 0 { | ||
return str | ||
} | ||
nextIdx := i + len(delim) | ||
if nextIdx >= len(str) { | ||
// Nothing left after the delimeter, it's at the end of the string. | ||
return str[:len(str)-len(delim)] | ||
} | ||
prev := str[:nextIdx-1] | ||
next := str[nextIdx:] | ||
if next != "" { | ||
next = modifyNext(next) | ||
} | ||
return prev + ModifyStringAroundDelimeter(next, delim, modifyNext) | ||
} |
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,46 @@ | ||
package cgstrings | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestCamel(t *testing.T) { | ||
t.Parallel() | ||
assert := assert.New(t) | ||
|
||
assert.Equal("", Camel("")) | ||
assert.Equal("plugh", Camel("plugh")) | ||
assert.Equal("waldoThudFred", Camel("WaldoThudFred")) | ||
assert.Equal("graultBaz", Camel("Grault-Baz")) | ||
assert.Equal("graultBaz", Camel("grault-baz")) | ||
assert.Equal("graultBaz", Camel("graultBaz")) | ||
assert.Equal("grault_Baz", Camel("Grault_Baz")) | ||
assert.Equal("graultBaz", Camel("Grault-baz")) | ||
} | ||
|
||
func TestUnhyphenate(t *testing.T) { | ||
t.Parallel() | ||
testcases := []struct { | ||
input, expected string | ||
}{ | ||
{"", ""}, | ||
{"waldo", "waldo"}, | ||
{"waldo-thud-fred", "waldoThudFred"}, | ||
{"waldo-Thud-Fred", "waldoThudFred"}, | ||
{"waldo-Thud-Fred-", "waldoThudFred"}, | ||
{"-waldo-Thud-Fred", "WaldoThudFred"}, | ||
{"waldoThudFred", "waldoThudFred"}, | ||
{"WaldoThudFred", "WaldoThudFred"}, | ||
} | ||
for _, tc := range testcases { | ||
tc := tc | ||
t.Run(fmt.Sprintf("Subtest:%q", tc.input), func(t *testing.T) { | ||
t.Parallel() | ||
assert := assert.New(t) | ||
assert.Equal(tc.expected, Unhyphenate(tc.input)) | ||
}) | ||
} | ||
} |
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
Oops, something went wrong.