Some of the apply rewriter's assumptions were broken by the richer expressions available in HCL2. These changes fix those broken assumptions, in particular the assumption that only scope traversal expressions are sources of eventual values.
58 lines
1.8 KiB
Go
58 lines
1.8 KiB
Go
package python
|
|
|
|
import (
|
|
"io"
|
|
"strings"
|
|
"unicode"
|
|
)
|
|
|
|
// isLegalIdentifierStart returns true if it is legal for c to be the first character of a Python identifier as per
|
|
// https://docs.python.org/3.7/reference/lexical_analysis.html#identifiers.
|
|
func isLegalIdentifierStart(c rune) bool {
|
|
return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '_' ||
|
|
unicode.In(c, unicode.Lu, unicode.Ll, unicode.Lt, unicode.Lm, unicode.Lo, unicode.Nl)
|
|
}
|
|
|
|
// isLegalIdentifierPart returns true if it is legal for c to be part of a Python identifier (besides the first
|
|
// character) as per https://docs.python.org/3.7/reference/lexical_analysis.html#identifiers.
|
|
func isLegalIdentifierPart(c rune) bool {
|
|
return isLegalIdentifierStart(c) || c >= '0' && c <= '9' ||
|
|
unicode.In(c, unicode.Lu, unicode.Ll, unicode.Lt, unicode.Lm, unicode.Lo, unicode.Nl, unicode.Mn, unicode.Mc,
|
|
unicode.Nd, unicode.Pc)
|
|
}
|
|
|
|
// isLegalIdentifier returns true if s is a legal Python identifier as per
|
|
// https://docs.python.org/3.7/reference/lexical_analysis.html#identifiers.
|
|
func isLegalIdentifier(s string) bool {
|
|
reader := strings.NewReader(s)
|
|
c, _, _ := reader.ReadRune()
|
|
if !isLegalIdentifierStart(c) {
|
|
return false
|
|
}
|
|
for {
|
|
c, _, err := reader.ReadRune()
|
|
if err != nil {
|
|
return err == io.EOF
|
|
}
|
|
if !isLegalIdentifierPart(c) {
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
|
|
// cleanName replaces characters that are not allowed in Python identifiers with underscores. No attempt is made to
|
|
// ensure that the result is unique.
|
|
func cleanName(name string) string {
|
|
var builder strings.Builder
|
|
for i, c := range name {
|
|
if !isLegalIdentifierPart(c) {
|
|
builder.WriteRune('_')
|
|
} else {
|
|
if i == 0 && !isLegalIdentifierStart(c) {
|
|
builder.WriteRune('_')
|
|
}
|
|
builder.WriteRune(c)
|
|
}
|
|
}
|
|
return builder.String()
|
|
}
|