goscript 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cmd/goscript/cmd_compile.go +28 -8
- package/cmd/goscript/cmd_compile_test.go +105 -6
- package/compiler/build-flags.go +9 -10
- package/compiler/gotest/runner_test.go +127 -0
- package/compiler/lowering.go +596 -136
- package/compiler/lowering_bench_test.go +350 -0
- package/compiler/package-graph.go +61 -4
- package/compiler/package-graph_test.go +30 -0
- package/compiler/semantic-model-types.go +8 -0
- package/compiler/semantic-model.go +447 -22
- package/compiler/semantic-model_test.go +138 -0
- package/compiler/skeleton_test.go +948 -14
- package/compiler/typescript-emitter.go +19 -2
- package/dist/gs/builtin/builtin.d.ts +2 -2
- package/dist/gs/builtin/builtin.js +20 -0
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/builtin/slice.js +5 -0
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.d.ts +1 -1
- package/dist/gs/builtin/type.js +72 -5
- package/dist/gs/builtin/type.js.map +1 -1
- package/dist/gs/compress/zlib/index.d.ts +3 -3
- package/dist/gs/compress/zlib/index.js +88 -26
- package/dist/gs/compress/zlib/index.js.map +1 -1
- package/dist/gs/crypto/sha1/index.js +2 -5
- package/dist/gs/crypto/sha1/index.js.map +1 -1
- package/dist/gs/crypto/sha256/index.js +2 -5
- package/dist/gs/crypto/sha256/index.js.map +1 -1
- package/dist/gs/crypto/sha512/index.js +2 -5
- package/dist/gs/crypto/sha512/index.js.map +1 -1
- package/dist/gs/embed/index.d.ts +6 -0
- package/dist/gs/embed/index.js +210 -5
- package/dist/gs/embed/index.js.map +1 -1
- package/dist/gs/fmt/fmt.d.ts +3 -3
- package/dist/gs/fmt/fmt.js +29 -16
- package/dist/gs/fmt/fmt.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +118 -6
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +1 -1
- package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.d.ts +45 -0
- package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.js +229 -0
- package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.js.map +1 -0
- package/dist/gs/io/fs/readdir.js +5 -3
- package/dist/gs/io/fs/readdir.js.map +1 -1
- package/dist/gs/io/io.d.ts +10 -6
- package/dist/gs/io/io.js +87 -42
- package/dist/gs/io/io.js.map +1 -1
- package/dist/gs/math/bits/index.d.ts +26 -5
- package/dist/gs/math/bits/index.js +13 -24
- package/dist/gs/math/bits/index.js.map +1 -1
- package/dist/gs/net/http/index.d.ts +3 -1
- package/dist/gs/net/http/index.js +18 -1
- package/dist/gs/net/http/index.js.map +1 -1
- package/dist/gs/os/types_js.gs.d.ts +6 -2
- package/dist/gs/os/types_js.gs.js +169 -8
- package/dist/gs/os/types_js.gs.js.map +1 -1
- package/dist/gs/reflect/type.d.ts +1 -0
- package/dist/gs/reflect/type.js +80 -51
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/strings/reader.d.ts +1 -1
- package/dist/gs/strings/reader.js +2 -2
- package/dist/gs/strings/reader.js.map +1 -1
- package/dist/gs/sync/sync.d.ts +2 -1
- package/dist/gs/sync/sync.js +37 -16
- package/dist/gs/sync/sync.js.map +1 -1
- package/dist/gs/syscall/js/index.js +9 -0
- package/dist/gs/syscall/js/index.js.map +1 -1
- package/dist/gs/testing/testing.js +8 -6
- package/dist/gs/testing/testing.js.map +1 -1
- package/gs/builtin/builtin.ts +25 -2
- package/gs/builtin/runtime-contract.test.ts +45 -0
- package/gs/builtin/slice.ts +7 -0
- package/gs/builtin/type.ts +85 -5
- package/gs/compress/zlib/index.test.ts +97 -0
- package/gs/compress/zlib/index.ts +117 -27
- package/gs/compress/zlib/meta.json +4 -1
- package/gs/crypto/sha1/index.test.ts +19 -2
- package/gs/crypto/sha1/index.ts +3 -6
- package/gs/crypto/sha256/index.test.ts +14 -2
- package/gs/crypto/sha256/index.ts +3 -6
- package/gs/crypto/sha512/index.test.ts +17 -2
- package/gs/crypto/sha512/index.ts +3 -6
- package/gs/embed/index.test.ts +87 -0
- package/gs/embed/index.ts +229 -5
- package/gs/fmt/fmt.test.ts +41 -3
- package/gs/fmt/fmt.ts +40 -17
- package/gs/fmt/meta.json +6 -1
- package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +8 -1
- package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +139 -11
- package/gs/github.com/go-git/go-billy/v6/osfs/index.test.ts +110 -0
- package/gs/github.com/go-git/go-billy/v6/osfs/index.ts +280 -0
- package/gs/github.com/go-git/go-billy/v6/osfs/meta.json +8 -0
- package/gs/io/fs/readdir.test.ts +38 -0
- package/gs/io/fs/readdir.ts +7 -3
- package/gs/io/io.test.ts +77 -6
- package/gs/io/io.ts +114 -52
- package/gs/io/meta.json +7 -1
- package/gs/math/bits/index.ts +52 -28
- package/gs/net/http/index.test.ts +16 -0
- package/gs/net/http/index.ts +19 -2
- package/gs/os/file_unix_js.test.ts +52 -0
- package/gs/os/meta.json +4 -0
- package/gs/os/readdir.test.ts +56 -0
- package/gs/os/types_js.gs.ts +169 -8
- package/gs/reflect/deepequal.test.ts +10 -1
- package/gs/reflect/type.ts +91 -56
- package/gs/reflect/typefor.test.ts +31 -1
- package/gs/strings/meta.json +5 -2
- package/gs/strings/reader.test.ts +2 -2
- package/gs/strings/reader.ts +2 -2
- package/gs/sync/meta.json +1 -0
- package/gs/sync/sync.test.ts +41 -1
- package/gs/sync/sync.ts +41 -16
- package/gs/syscall/js/index.test.ts +18 -0
- package/gs/syscall/js/index.ts +12 -0
- package/gs/testing/testing.test.ts +32 -3
- package/gs/testing/testing.ts +13 -10
- package/package.json +1 -1
package/compiler/lowering.go
CHANGED
|
@@ -1124,7 +1124,7 @@ func isConstGenDecl(decl ast.Decl) bool {
|
|
|
1124
1124
|
}
|
|
1125
1125
|
|
|
1126
1126
|
func (o *LoweringOwner) lowerGenDecl(ctx lowerFileContext, decl *ast.GenDecl) ([]loweredDecl, []Diagnostic) {
|
|
1127
|
-
|
|
1127
|
+
decls := make([]loweredDecl, 0, len(decl.Specs))
|
|
1128
1128
|
var diagnostics []Diagnostic
|
|
1129
1129
|
for _, spec := range decl.Specs {
|
|
1130
1130
|
switch typed := spec.(type) {
|
|
@@ -1190,7 +1190,7 @@ func (o *LoweringOwner) lowerGenDecl(ctx lowerFileContext, decl *ast.GenDecl) ([
|
|
|
1190
1190
|
code := keyword + " " + declName + ": " + variableType + " = " + value
|
|
1191
1191
|
if lazy {
|
|
1192
1192
|
keyword = "var"
|
|
1193
|
-
code = "var " + declName + ": " + variableType
|
|
1193
|
+
code = "var " + declName + ": " + variableType
|
|
1194
1194
|
}
|
|
1195
1195
|
indexExport := ""
|
|
1196
1196
|
if ctx.topLevel && name.Name != "_" {
|
|
@@ -1402,7 +1402,7 @@ func packageDeclFiles(semPkg *semanticPackage) map[types.Object]string {
|
|
|
1402
1402
|
if semPkg == nil || semPkg.source == nil {
|
|
1403
1403
|
return nil
|
|
1404
1404
|
}
|
|
1405
|
-
declFiles := make(map[types.Object]string)
|
|
1405
|
+
declFiles := make(map[types.Object]string, len(semPkg.declarations))
|
|
1406
1406
|
for _, decl := range semPkg.declarations {
|
|
1407
1407
|
if decl.object != nil && decl.position.file != "" {
|
|
1408
1408
|
declFiles[decl.object] = decl.position.file
|
|
@@ -1962,6 +1962,13 @@ func lowerLargeIntegerConstantValue(value constant.Value) (string, bool) {
|
|
|
1962
1962
|
return value.ExactString(), true
|
|
1963
1963
|
}
|
|
1964
1964
|
|
|
1965
|
+
func lowerWideIntegerConstantValue(value constant.Value) (string, bool) {
|
|
1966
|
+
if value == nil || value.Kind() != constant.Int || constant.BitLen(value) <= 53 {
|
|
1967
|
+
return "", false
|
|
1968
|
+
}
|
|
1969
|
+
return value.ExactString(), true
|
|
1970
|
+
}
|
|
1971
|
+
|
|
1965
1972
|
func lowerConstantStringByteSlice(ctx lowerFileContext, expr ast.Expr) (string, bool) {
|
|
1966
1973
|
value := ctx.semPkg.source.TypesInfo.Types[unwrapParenExpr(expr)].Value
|
|
1967
1974
|
if value == nil || value.Kind() != constant.String {
|
|
@@ -2006,35 +2013,218 @@ func (o *LoweringOwner) lowerGoEmbedValue(
|
|
|
2006
2013
|
typ types.Type,
|
|
2007
2014
|
patterns []string,
|
|
2008
2015
|
) (string, []Diagnostic) {
|
|
2016
|
+
if isEmbedFSType(typ) {
|
|
2017
|
+
return o.lowerGoEmbedFSValue(ctx, patterns)
|
|
2018
|
+
}
|
|
2009
2019
|
if len(patterns) != 1 {
|
|
2010
2020
|
return "", []Diagnostic{loweringUnsupported("declaration", ctx.semPkg.pkgPath, "unsupported go:embed pattern list")}
|
|
2011
2021
|
}
|
|
2012
|
-
|
|
2022
|
+
cleanPattern, diagnostics := cleanGoEmbedFilePattern(ctx, patterns[0])
|
|
2023
|
+
if len(diagnostics) != 0 {
|
|
2024
|
+
return "", diagnostics
|
|
2025
|
+
}
|
|
2026
|
+
data, diagnostics := readGoEmbedFile(ctx, cleanPattern)
|
|
2027
|
+
if len(diagnostics) != 0 {
|
|
2028
|
+
return "", diagnostics
|
|
2029
|
+
}
|
|
2030
|
+
if isStringType(typ) {
|
|
2031
|
+
return strconv.Quote(string(data)), nil
|
|
2032
|
+
}
|
|
2033
|
+
if slice, ok := types.Unalias(typ).Underlying().(*types.Slice); ok && isByteType(slice.Elem()) {
|
|
2034
|
+
return byteSliceLiteral(data), nil
|
|
2035
|
+
}
|
|
2036
|
+
diag := loweringUnsupported("declaration", ctx.semPkg.pkgPath, "unsupported go:embed target type")
|
|
2037
|
+
diag.Detail = "target type: " + types.TypeString(typ, func(pkg *types.Package) string {
|
|
2038
|
+
if pkg == nil {
|
|
2039
|
+
return ""
|
|
2040
|
+
}
|
|
2041
|
+
return pkg.Path()
|
|
2042
|
+
})
|
|
2043
|
+
return "", []Diagnostic{diag}
|
|
2044
|
+
}
|
|
2045
|
+
|
|
2046
|
+
func (o *LoweringOwner) lowerGoEmbedFSValue(ctx lowerFileContext, patterns []string) (string, []Diagnostic) {
|
|
2047
|
+
embedAlias := ctx.importPaths["embed"]
|
|
2048
|
+
if embedAlias == "" {
|
|
2049
|
+
return "", []Diagnostic{loweringUnsupported("declaration", ctx.semPkg.pkgPath, "unsupported go:embed FS import")}
|
|
2050
|
+
}
|
|
2051
|
+
if len(patterns) == 0 {
|
|
2052
|
+
return "", []Diagnostic{loweringUnsupported("declaration", ctx.semPkg.pkgPath, "unsupported go:embed pattern list")}
|
|
2053
|
+
}
|
|
2054
|
+
|
|
2055
|
+
filesByPath := make(map[string][]byte)
|
|
2056
|
+
for _, pattern := range patterns {
|
|
2057
|
+
files, diagnostics := expandGoEmbedPattern(ctx, pattern)
|
|
2058
|
+
if len(diagnostics) != 0 {
|
|
2059
|
+
return "", diagnostics
|
|
2060
|
+
}
|
|
2061
|
+
for _, file := range files {
|
|
2062
|
+
filesByPath[file.path] = file.data
|
|
2063
|
+
}
|
|
2064
|
+
}
|
|
2065
|
+
paths := make([]string, 0, len(filesByPath))
|
|
2066
|
+
for path := range filesByPath {
|
|
2067
|
+
paths = append(paths, path)
|
|
2068
|
+
}
|
|
2069
|
+
slices.Sort(paths)
|
|
2070
|
+
entries := make([]string, 0, len(paths))
|
|
2071
|
+
for _, path := range paths {
|
|
2072
|
+
entries = append(entries, "["+strconv.Quote(path)+", "+byteSliceLiteral(filesByPath[path])+"]")
|
|
2073
|
+
}
|
|
2074
|
+
builtinAlias := o.runtimeOwner.BuiltinImport().Alias
|
|
2075
|
+
return builtinAlias + ".markAsStructValue(new " + embedAlias + ".FS(new Map<string, Uint8Array>([" + strings.Join(entries, ", ") + "])))", nil
|
|
2076
|
+
}
|
|
2077
|
+
|
|
2078
|
+
type goEmbedFile struct {
|
|
2079
|
+
path string
|
|
2080
|
+
data []byte
|
|
2081
|
+
}
|
|
2082
|
+
|
|
2083
|
+
func cleanGoEmbedFilePattern(ctx lowerFileContext, pattern string) (string, []Diagnostic) {
|
|
2084
|
+
cleanPattern, _, diagnostics := cleanGoEmbedPattern(ctx, pattern)
|
|
2085
|
+
if len(diagnostics) != 0 {
|
|
2086
|
+
return "", diagnostics
|
|
2087
|
+
}
|
|
2088
|
+
if strings.Contains(cleanPattern, "*") {
|
|
2089
|
+
return "", []Diagnostic{loweringUnsupported("declaration", ctx.semPkg.pkgPath, "unsupported go:embed pattern")}
|
|
2090
|
+
}
|
|
2091
|
+
info, err := os.Stat(filepath.Join(filepath.Dir(ctx.sourcePath), filepath.FromSlash(cleanPattern)))
|
|
2092
|
+
if err != nil {
|
|
2093
|
+
return "", []Diagnostic{goEmbedReadDiagnostic(ctx, err)}
|
|
2094
|
+
}
|
|
2095
|
+
if info.IsDir() {
|
|
2096
|
+
return "", []Diagnostic{loweringUnsupported("declaration", ctx.semPkg.pkgPath, "unsupported go:embed directory target")}
|
|
2097
|
+
}
|
|
2098
|
+
return cleanPattern, nil
|
|
2099
|
+
}
|
|
2100
|
+
|
|
2101
|
+
func cleanGoEmbedPattern(ctx lowerFileContext, pattern string) (string, bool, []Diagnostic) {
|
|
2102
|
+
pattern = strings.Trim(pattern, "`\"")
|
|
2103
|
+
all := false
|
|
2104
|
+
if strings.HasPrefix(pattern, "all:") {
|
|
2105
|
+
all = true
|
|
2106
|
+
pattern = strings.TrimPrefix(pattern, "all:")
|
|
2107
|
+
}
|
|
2013
2108
|
cleanPattern := path.Clean(pattern)
|
|
2014
2109
|
if pattern == "" ||
|
|
2015
|
-
strings.Contains(pattern, "*") ||
|
|
2016
2110
|
path.IsAbs(pattern) ||
|
|
2017
2111
|
cleanPattern == "." ||
|
|
2018
2112
|
cleanPattern == ".." ||
|
|
2019
2113
|
strings.HasPrefix(cleanPattern, "../") {
|
|
2020
|
-
return "", []Diagnostic{loweringUnsupported("declaration", ctx.semPkg.pkgPath, "unsupported go:embed pattern")}
|
|
2114
|
+
return "", false, []Diagnostic{loweringUnsupported("declaration", ctx.semPkg.pkgPath, "unsupported go:embed pattern")}
|
|
2021
2115
|
}
|
|
2022
|
-
|
|
2116
|
+
return cleanPattern, all, nil
|
|
2117
|
+
}
|
|
2118
|
+
|
|
2119
|
+
func expandGoEmbedPattern(ctx lowerFileContext, pattern string) ([]goEmbedFile, []Diagnostic) {
|
|
2120
|
+
cleanPattern, all, diagnostics := cleanGoEmbedPattern(ctx, pattern)
|
|
2121
|
+
if len(diagnostics) != 0 {
|
|
2122
|
+
return nil, diagnostics
|
|
2123
|
+
}
|
|
2124
|
+
pkgDir := filepath.Dir(ctx.sourcePath)
|
|
2125
|
+
paths := []string{filepath.Join(pkgDir, filepath.FromSlash(cleanPattern))}
|
|
2126
|
+
if strings.Contains(cleanPattern, "*") {
|
|
2127
|
+
matches, err := filepath.Glob(filepath.Join(pkgDir, filepath.FromSlash(cleanPattern)))
|
|
2128
|
+
if err != nil {
|
|
2129
|
+
return nil, []Diagnostic{loweringUnsupported("declaration", ctx.semPkg.pkgPath, "unsupported go:embed pattern")}
|
|
2130
|
+
}
|
|
2131
|
+
if len(matches) == 0 {
|
|
2132
|
+
return nil, []Diagnostic{loweringUnsupported("declaration", ctx.semPkg.pkgPath, "go:embed pattern matched no files")}
|
|
2133
|
+
}
|
|
2134
|
+
paths = matches
|
|
2135
|
+
}
|
|
2136
|
+
|
|
2137
|
+
var files []goEmbedFile
|
|
2138
|
+
for _, path := range paths {
|
|
2139
|
+
collected, diagnostics := collectGoEmbedPath(ctx, pkgDir, path, all)
|
|
2140
|
+
if len(diagnostics) != 0 {
|
|
2141
|
+
return nil, diagnostics
|
|
2142
|
+
}
|
|
2143
|
+
files = append(files, collected...)
|
|
2144
|
+
}
|
|
2145
|
+
slices.SortFunc(files, func(a, b goEmbedFile) int {
|
|
2146
|
+
return cmp.Compare(a.path, b.path)
|
|
2147
|
+
})
|
|
2148
|
+
return files, nil
|
|
2149
|
+
}
|
|
2150
|
+
|
|
2151
|
+
func collectGoEmbedPath(ctx lowerFileContext, pkgDir, absPath string, all bool) ([]goEmbedFile, []Diagnostic) {
|
|
2152
|
+
info, err := os.Stat(absPath)
|
|
2023
2153
|
if err != nil {
|
|
2024
|
-
return
|
|
2025
|
-
Severity: DiagnosticSeverityError,
|
|
2026
|
-
Code: "goscript/lowering:embed",
|
|
2027
|
-
Message: "failed to read go:embed file",
|
|
2028
|
-
Detail: ctx.semPkg.pkgPath + ": " + err.Error(),
|
|
2029
|
-
}}
|
|
2154
|
+
return nil, []Diagnostic{goEmbedReadDiagnostic(ctx, err)}
|
|
2030
2155
|
}
|
|
2031
|
-
if
|
|
2032
|
-
|
|
2156
|
+
if !info.IsDir() {
|
|
2157
|
+
file, diagnostics := readGoEmbedAbsFile(ctx, pkgDir, absPath)
|
|
2158
|
+
if len(diagnostics) != 0 {
|
|
2159
|
+
return nil, diagnostics
|
|
2160
|
+
}
|
|
2161
|
+
return []goEmbedFile{file}, nil
|
|
2033
2162
|
}
|
|
2034
|
-
|
|
2035
|
-
|
|
2163
|
+
|
|
2164
|
+
var files []goEmbedFile
|
|
2165
|
+
if err := filepath.WalkDir(absPath, func(path string, entry os.DirEntry, err error) error {
|
|
2166
|
+
if err != nil {
|
|
2167
|
+
return err
|
|
2168
|
+
}
|
|
2169
|
+
if path != absPath && !all && (strings.HasPrefix(entry.Name(), ".") || strings.HasPrefix(entry.Name(), "_")) {
|
|
2170
|
+
if entry.IsDir() {
|
|
2171
|
+
return filepath.SkipDir
|
|
2172
|
+
}
|
|
2173
|
+
return nil
|
|
2174
|
+
}
|
|
2175
|
+
if entry.IsDir() {
|
|
2176
|
+
return nil
|
|
2177
|
+
}
|
|
2178
|
+
file, diagnostics := readGoEmbedAbsFile(ctx, pkgDir, path)
|
|
2179
|
+
if len(diagnostics) != 0 {
|
|
2180
|
+
return fmt.Errorf("%s", diagnostics[0].Detail)
|
|
2181
|
+
}
|
|
2182
|
+
files = append(files, file)
|
|
2183
|
+
return nil
|
|
2184
|
+
}); err != nil {
|
|
2185
|
+
return nil, []Diagnostic{goEmbedReadDiagnostic(ctx, err)}
|
|
2186
|
+
}
|
|
2187
|
+
if len(files) == 0 {
|
|
2188
|
+
return nil, []Diagnostic{loweringUnsupported("declaration", ctx.semPkg.pkgPath, "go:embed directory matched no files")}
|
|
2036
2189
|
}
|
|
2037
|
-
return
|
|
2190
|
+
return files, nil
|
|
2191
|
+
}
|
|
2192
|
+
|
|
2193
|
+
func readGoEmbedFile(ctx lowerFileContext, cleanPattern string) ([]byte, []Diagnostic) {
|
|
2194
|
+
file, diagnostics := readGoEmbedAbsFile(ctx, filepath.Dir(ctx.sourcePath), filepath.Join(filepath.Dir(ctx.sourcePath), filepath.FromSlash(cleanPattern)))
|
|
2195
|
+
if len(diagnostics) != 0 {
|
|
2196
|
+
return nil, diagnostics
|
|
2197
|
+
}
|
|
2198
|
+
return file.data, nil
|
|
2199
|
+
}
|
|
2200
|
+
|
|
2201
|
+
func readGoEmbedAbsFile(ctx lowerFileContext, pkgDir, absPath string) (goEmbedFile, []Diagnostic) {
|
|
2202
|
+
relPath, err := filepath.Rel(pkgDir, absPath)
|
|
2203
|
+
if err != nil {
|
|
2204
|
+
return goEmbedFile{}, []Diagnostic{goEmbedReadDiagnostic(ctx, err)}
|
|
2205
|
+
}
|
|
2206
|
+
data, err := os.ReadFile(absPath)
|
|
2207
|
+
if err != nil {
|
|
2208
|
+
return goEmbedFile{}, []Diagnostic{goEmbedReadDiagnostic(ctx, err)}
|
|
2209
|
+
}
|
|
2210
|
+
return goEmbedFile{path: filepath.ToSlash(relPath), data: data}, nil
|
|
2211
|
+
}
|
|
2212
|
+
|
|
2213
|
+
func goEmbedReadDiagnostic(ctx lowerFileContext, err error) Diagnostic {
|
|
2214
|
+
return Diagnostic{
|
|
2215
|
+
Severity: DiagnosticSeverityError,
|
|
2216
|
+
Code: "goscript/lowering:embed",
|
|
2217
|
+
Message: "failed to read go:embed file",
|
|
2218
|
+
Detail: ctx.semPkg.pkgPath + ": " + err.Error(),
|
|
2219
|
+
}
|
|
2220
|
+
}
|
|
2221
|
+
|
|
2222
|
+
func isEmbedFSType(typ types.Type) bool {
|
|
2223
|
+
named, _ := types.Unalias(typ).(*types.Named)
|
|
2224
|
+
if named == nil || named.Obj() == nil || named.Obj().Pkg() == nil {
|
|
2225
|
+
return false
|
|
2226
|
+
}
|
|
2227
|
+
return named.Obj().Pkg().Path() == "embed" && named.Obj().Name() == "FS"
|
|
2038
2228
|
}
|
|
2039
2229
|
|
|
2040
2230
|
func byteSliceLiteral(data []byte) string {
|
|
@@ -2202,6 +2392,7 @@ func (o *LoweringOwner) lowerStructType(ctx lowerFileContext, semType *semanticT
|
|
|
2202
2392
|
name: safeIdentifier(semType.name),
|
|
2203
2393
|
typeName: runtimeNamedTypeName(semType.named),
|
|
2204
2394
|
cloneMethod: "clone",
|
|
2395
|
+
fields: make([]loweredStructField, 0, len(semType.fields)),
|
|
2205
2396
|
}
|
|
2206
2397
|
for idx, field := range semType.fields {
|
|
2207
2398
|
structValue := isStructValueType(field.typ)
|
|
@@ -2228,9 +2419,12 @@ func (o *LoweringOwner) lowerStructType(ctx lowerFileContext, semType *semanticT
|
|
|
2228
2419
|
|
|
2229
2420
|
methodDecls := o.methodDeclsForType(ctx, semType.named)
|
|
2230
2421
|
explicitMethods := make(map[string]bool, len(methodDecls))
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2422
|
+
if len(methodDecls) != 0 {
|
|
2423
|
+
lowered.methods = make([]loweredFunction, 0, len(methodDecls))
|
|
2424
|
+
for _, methodDecl := range methodDecls {
|
|
2425
|
+
if methodDecl != nil {
|
|
2426
|
+
explicitMethods[methodDecl.Name.Name] = true
|
|
2427
|
+
}
|
|
2234
2428
|
}
|
|
2235
2429
|
}
|
|
2236
2430
|
var diagnostics []Diagnostic
|
|
@@ -3034,105 +3228,113 @@ func (o *LoweringOwner) lowerStmtListAfter(
|
|
|
3034
3228
|
) ([]loweredStmt, []Diagnostic) {
|
|
3035
3229
|
lowered := make([]loweredStmt, 0, len(stmts))
|
|
3036
3230
|
var diagnostics []Diagnostic
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
group.
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3231
|
+
hasGoto := stmtListHasGoto(stmts)
|
|
3232
|
+
var gotoSpans map[string]int
|
|
3233
|
+
var gotoLabels map[string]bool
|
|
3234
|
+
var forwardStarts map[int]forwardGotoLabelSpan
|
|
3235
|
+
if hasGoto {
|
|
3236
|
+
gotoSpans = backwardGotoLabelSpans(stmts)
|
|
3237
|
+
gotoLabels = make(map[string]bool, len(gotoSpans))
|
|
3238
|
+
for label := range gotoSpans {
|
|
3239
|
+
gotoLabels[label] = true
|
|
3240
|
+
}
|
|
3241
|
+
forwardSpans := forwardGotoLabelSpans(stmts, gotoSpans)
|
|
3242
|
+
forwardStarts = make(map[int]forwardGotoLabelSpan, len(forwardSpans))
|
|
3243
|
+
for label, span := range forwardSpans {
|
|
3244
|
+
span.label = label
|
|
3245
|
+
group := forwardStarts[span.start]
|
|
3246
|
+
if group.forwardLabels == nil {
|
|
3247
|
+
group.forwardLabels = make(map[string]bool)
|
|
3248
|
+
}
|
|
3249
|
+
group.forwardLabels[label] = true
|
|
3250
|
+
if group.label == "" || span.labelIdx > group.labelIdx {
|
|
3251
|
+
group.label = span.label
|
|
3252
|
+
group.start = span.start
|
|
3253
|
+
group.labelIdx = span.labelIdx
|
|
3254
|
+
}
|
|
3255
|
+
forwardStarts[span.start] = group
|
|
3256
|
+
}
|
|
3057
3257
|
}
|
|
3058
3258
|
for idx := 0; idx < len(stmts); idx++ {
|
|
3059
3259
|
stmt := stmts[idx]
|
|
3060
3260
|
startLine := sourceLine(ctx, stmt.Pos())
|
|
3061
3261
|
leading := leadingStmtLines(ctx, prevEndLine, startLine)
|
|
3062
|
-
if
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
}
|
|
3069
|
-
idx = cluster.endIdx
|
|
3070
|
-
continue
|
|
3071
|
-
}
|
|
3072
|
-
if span, ok := leadingGotoBackwardLoopSpan(stmts, idx, gotoSpans); ok {
|
|
3073
|
-
loop, loopDiagnostics := o.lowerBackwardGotoLoop(
|
|
3074
|
-
ctx,
|
|
3075
|
-
gotoLabels,
|
|
3076
|
-
span.label,
|
|
3077
|
-
span.labelIdx,
|
|
3078
|
-
span.endIdx,
|
|
3079
|
-
span.forwardLabel,
|
|
3080
|
-
stmts,
|
|
3081
|
-
leading,
|
|
3082
|
-
)
|
|
3083
|
-
diagnostics = append(diagnostics, loopDiagnostics...)
|
|
3084
|
-
lowered = append(lowered, loop...)
|
|
3085
|
-
if endLine := sourceLine(ctx, stmts[span.endIdx].End()); endLine != 0 {
|
|
3086
|
-
prevEndLine = endLine
|
|
3087
|
-
}
|
|
3088
|
-
idx = span.endIdx
|
|
3089
|
-
continue
|
|
3090
|
-
}
|
|
3091
|
-
if span, ok := forwardStarts[idx]; ok {
|
|
3092
|
-
bodyStmts := stmts[idx:span.labelIdx]
|
|
3093
|
-
body, bodyDiagnostics := o.lowerStmtListAfter(
|
|
3094
|
-
ctx.withForwardGotos(span.forwardLabels),
|
|
3095
|
-
bodyStmts,
|
|
3096
|
-
prevEndLine,
|
|
3097
|
-
)
|
|
3098
|
-
diagnostics = append(diagnostics, bodyDiagnostics...)
|
|
3099
|
-
block := loweredStmt{hasBlock: true, text: span.label + ":", children: body}
|
|
3100
|
-
if len(leading) != 0 {
|
|
3101
|
-
block.leading = append(leading, block.leading...)
|
|
3102
|
-
}
|
|
3103
|
-
lowered = append(lowered, block)
|
|
3104
|
-
if labeled, ok := stmts[span.labelIdx].(*ast.LabeledStmt); ok {
|
|
3105
|
-
labelLowered, labelDiagnostics := o.lowerStmt(ctx, labeled.Stmt)
|
|
3106
|
-
diagnostics = append(diagnostics, labelDiagnostics...)
|
|
3107
|
-
lowered = append(lowered, labelLowered...)
|
|
3108
|
-
if endLine := sourceLine(ctx, labeled.End()); endLine != 0 {
|
|
3262
|
+
if hasGoto {
|
|
3263
|
+
if cluster, ok := gotoStateClusterAt(stmts, idx); ok {
|
|
3264
|
+
clusterLowered, clusterDiagnostics := o.lowerGotoStateCluster(ctx, stmts, cluster, leading)
|
|
3265
|
+
diagnostics = append(diagnostics, clusterDiagnostics...)
|
|
3266
|
+
lowered = append(lowered, clusterLowered...)
|
|
3267
|
+
if endLine := sourceLine(ctx, stmts[cluster.endIdx].End()); endLine != 0 {
|
|
3109
3268
|
prevEndLine = endLine
|
|
3110
3269
|
}
|
|
3270
|
+
idx = cluster.endIdx
|
|
3271
|
+
continue
|
|
3111
3272
|
}
|
|
3112
|
-
idx
|
|
3113
|
-
continue
|
|
3114
|
-
}
|
|
3115
|
-
if labeled, ok := stmt.(*ast.LabeledStmt); ok {
|
|
3116
|
-
label := safeIdentifier(labeled.Label.Name)
|
|
3117
|
-
if endIdx, ok := gotoSpans[label]; ok {
|
|
3273
|
+
if span, ok := leadingGotoBackwardLoopSpan(stmts, idx, gotoSpans); ok {
|
|
3118
3274
|
loop, loopDiagnostics := o.lowerBackwardGotoLoop(
|
|
3119
3275
|
ctx,
|
|
3120
3276
|
gotoLabels,
|
|
3121
|
-
label,
|
|
3122
|
-
|
|
3123
|
-
endIdx,
|
|
3124
|
-
|
|
3277
|
+
span.label,
|
|
3278
|
+
span.labelIdx,
|
|
3279
|
+
span.endIdx,
|
|
3280
|
+
span.forwardLabel,
|
|
3125
3281
|
stmts,
|
|
3126
3282
|
leading,
|
|
3127
3283
|
)
|
|
3128
3284
|
diagnostics = append(diagnostics, loopDiagnostics...)
|
|
3129
3285
|
lowered = append(lowered, loop...)
|
|
3130
|
-
if endLine := sourceLine(ctx, stmts[endIdx].End()); endLine != 0 {
|
|
3286
|
+
if endLine := sourceLine(ctx, stmts[span.endIdx].End()); endLine != 0 {
|
|
3131
3287
|
prevEndLine = endLine
|
|
3132
3288
|
}
|
|
3133
|
-
idx = endIdx
|
|
3289
|
+
idx = span.endIdx
|
|
3134
3290
|
continue
|
|
3135
3291
|
}
|
|
3292
|
+
if span, ok := forwardStarts[idx]; ok {
|
|
3293
|
+
bodyStmts := stmts[idx:span.labelIdx]
|
|
3294
|
+
body, bodyDiagnostics := o.lowerStmtListAfter(
|
|
3295
|
+
ctx.withForwardGotos(span.forwardLabels),
|
|
3296
|
+
bodyStmts,
|
|
3297
|
+
prevEndLine,
|
|
3298
|
+
)
|
|
3299
|
+
diagnostics = append(diagnostics, bodyDiagnostics...)
|
|
3300
|
+
block := loweredStmt{hasBlock: true, text: span.label + ":", children: body}
|
|
3301
|
+
if len(leading) != 0 {
|
|
3302
|
+
block.leading = append(leading, block.leading...)
|
|
3303
|
+
}
|
|
3304
|
+
lowered = append(lowered, block)
|
|
3305
|
+
if labeled, ok := stmts[span.labelIdx].(*ast.LabeledStmt); ok {
|
|
3306
|
+
labelLowered, labelDiagnostics := o.lowerStmt(ctx, labeled.Stmt)
|
|
3307
|
+
diagnostics = append(diagnostics, labelDiagnostics...)
|
|
3308
|
+
lowered = append(lowered, labelLowered...)
|
|
3309
|
+
if endLine := sourceLine(ctx, labeled.End()); endLine != 0 {
|
|
3310
|
+
prevEndLine = endLine
|
|
3311
|
+
}
|
|
3312
|
+
}
|
|
3313
|
+
idx = span.labelIdx
|
|
3314
|
+
continue
|
|
3315
|
+
}
|
|
3316
|
+
if labeled, ok := stmt.(*ast.LabeledStmt); ok {
|
|
3317
|
+
label := safeIdentifier(labeled.Label.Name)
|
|
3318
|
+
if endIdx, ok := gotoSpans[label]; ok {
|
|
3319
|
+
loop, loopDiagnostics := o.lowerBackwardGotoLoop(
|
|
3320
|
+
ctx,
|
|
3321
|
+
gotoLabels,
|
|
3322
|
+
label,
|
|
3323
|
+
idx,
|
|
3324
|
+
endIdx,
|
|
3325
|
+
"",
|
|
3326
|
+
stmts,
|
|
3327
|
+
leading,
|
|
3328
|
+
)
|
|
3329
|
+
diagnostics = append(diagnostics, loopDiagnostics...)
|
|
3330
|
+
lowered = append(lowered, loop...)
|
|
3331
|
+
if endLine := sourceLine(ctx, stmts[endIdx].End()); endLine != 0 {
|
|
3332
|
+
prevEndLine = endLine
|
|
3333
|
+
}
|
|
3334
|
+
idx = endIdx
|
|
3335
|
+
continue
|
|
3336
|
+
}
|
|
3337
|
+
}
|
|
3136
3338
|
}
|
|
3137
3339
|
if stmtCtx, nextCtx, ok := o.lowerDeclStatementContext(ctx, stmt); ok {
|
|
3138
3340
|
stmtLowered, stmtDiagnostics := o.lowerStmt(stmtCtx, stmt)
|
|
@@ -3204,7 +3406,7 @@ func (o *LoweringOwner) lowerDeclStatementContext(
|
|
|
3204
3406
|
if def == nil || aliases[def] != "" {
|
|
3205
3407
|
continue
|
|
3206
3408
|
}
|
|
3207
|
-
if shortDeclDefShadowsOuterName(name.Name, def) {
|
|
3409
|
+
if shortDeclDefShadowsOuterName(ctx, name.Name, def) || valueSpecUsesOuterName(ctx, valueSpec, name.Name, def) {
|
|
3208
3410
|
aliases[def] = ctx.tempName("Shadow")
|
|
3209
3411
|
}
|
|
3210
3412
|
}
|
|
@@ -3452,9 +3654,30 @@ type leadingGotoBackwardLoop struct {
|
|
|
3452
3654
|
}
|
|
3453
3655
|
|
|
3454
3656
|
func stmtListNeedsLoopBranchLabel(stmts []ast.Stmt) bool {
|
|
3657
|
+
if !stmtListHasGoto(stmts) {
|
|
3658
|
+
return false
|
|
3659
|
+
}
|
|
3455
3660
|
return len(backwardGotoLabelSpans(stmts)) != 0
|
|
3456
3661
|
}
|
|
3457
3662
|
|
|
3663
|
+
func stmtListHasGoto(stmts []ast.Stmt) bool {
|
|
3664
|
+
for _, stmt := range stmts {
|
|
3665
|
+
hasGoto := false
|
|
3666
|
+
ast.Inspect(stmt, func(node ast.Node) bool {
|
|
3667
|
+
branch, ok := node.(*ast.BranchStmt)
|
|
3668
|
+
if ok && branch.Tok == token.GOTO && branch.Label != nil {
|
|
3669
|
+
hasGoto = true
|
|
3670
|
+
return false
|
|
3671
|
+
}
|
|
3672
|
+
return !hasGoto
|
|
3673
|
+
})
|
|
3674
|
+
if hasGoto {
|
|
3675
|
+
return true
|
|
3676
|
+
}
|
|
3677
|
+
}
|
|
3678
|
+
return false
|
|
3679
|
+
}
|
|
3680
|
+
|
|
3458
3681
|
func backwardGotoLabelSpans(stmts []ast.Stmt) map[string]int {
|
|
3459
3682
|
seenLabels := make(map[string]bool)
|
|
3460
3683
|
spans := make(map[string]int)
|
|
@@ -3734,15 +3957,11 @@ func (o *LoweringOwner) lowerAssignStmt(ctx lowerFileContext, stmt *ast.AssignSt
|
|
|
3734
3957
|
if starTarget && stmt.Tok != token.DEFINE {
|
|
3735
3958
|
pointer, pointerDiagnostics := o.lowerPointerStorageExpr(ctx, star.X)
|
|
3736
3959
|
diagnostics = append(diagnostics, pointerDiagnostics...)
|
|
3737
|
-
if stmt.Tok == token.AND_NOT_ASSIGN {
|
|
3738
|
-
stmts = append(stmts, loweredStmt{text: pointer + " = " + pointer + " & ~(" + right + ")"})
|
|
3739
|
-
continue
|
|
3740
|
-
}
|
|
3741
3960
|
if value, ok := integerQuotientAssignExpr(targetType, pointer, right, stmt.Tok); ok {
|
|
3742
3961
|
stmts = append(stmts, loweredStmt{text: value})
|
|
3743
3962
|
continue
|
|
3744
3963
|
}
|
|
3745
|
-
stmts = append(stmts, loweredStmt{text: pointer + " " +
|
|
3964
|
+
stmts = append(stmts, loweredStmt{text: pointer + " = " + lowerCompoundAssignValue(o.runtimeOwner, targetType, pointer, right, stmt.Tok)})
|
|
3746
3965
|
continue
|
|
3747
3966
|
}
|
|
3748
3967
|
if isShortDecl {
|
|
@@ -3752,10 +3971,6 @@ func (o *LoweringOwner) lowerAssignStmt(ctx lowerFileContext, stmt *ast.AssignSt
|
|
|
3752
3971
|
stmts = append(stmts, loweredStmt{text: "let " + left + o.shortDeclTypeAnnotation(ctx, lhs, stmt.Rhs[idx]) + " = " + right})
|
|
3753
3972
|
continue
|
|
3754
3973
|
}
|
|
3755
|
-
if stmt.Tok == token.AND_NOT_ASSIGN {
|
|
3756
|
-
stmts = append(stmts, loweredStmt{text: left + " = " + left + " & ~(" + right + ")"})
|
|
3757
|
-
continue
|
|
3758
|
-
}
|
|
3759
3974
|
if helper, ok := wideIntegerAssignHelper(targetType, stmt.Tok); ok {
|
|
3760
3975
|
stmts = append(stmts, loweredStmt{text: left + " = " + o.runtimeOwner.QualifiedHelper(helper) + "(" + left + ", " + right + ")"})
|
|
3761
3976
|
continue
|
|
@@ -3768,6 +3983,10 @@ func (o *LoweringOwner) lowerAssignStmt(ctx lowerFileContext, stmt *ast.AssignSt
|
|
|
3768
3983
|
if stmt.Tok == token.DEFINE {
|
|
3769
3984
|
op = "="
|
|
3770
3985
|
}
|
|
3986
|
+
if stmt.Tok != token.ASSIGN && stmt.Tok != token.DEFINE {
|
|
3987
|
+
stmts = append(stmts, loweredStmt{text: left + " = " + lowerCompoundAssignValue(o.runtimeOwner, targetType, left, right, stmt.Tok)})
|
|
3988
|
+
continue
|
|
3989
|
+
}
|
|
3771
3990
|
stmts = append(stmts, loweredStmt{text: left + " " + op + " " + right})
|
|
3772
3991
|
}
|
|
3773
3992
|
return stmts, diagnostics
|
|
@@ -3810,6 +4029,7 @@ func lowerCompoundAssignValue(
|
|
|
3810
4029
|
if value, ok := integerQuotientAssignValueExpr(targetType, left, right, tok); ok {
|
|
3811
4030
|
return value
|
|
3812
4031
|
}
|
|
4032
|
+
right = "(" + right + ")"
|
|
3813
4033
|
switch tok {
|
|
3814
4034
|
case token.ADD_ASSIGN:
|
|
3815
4035
|
return left + " + " + right
|
|
@@ -3830,6 +4050,9 @@ func lowerCompoundAssignValue(
|
|
|
3830
4050
|
case token.SHL_ASSIGN:
|
|
3831
4051
|
return left + " << " + right
|
|
3832
4052
|
case token.SHR_ASSIGN:
|
|
4053
|
+
if bits, ok := unsignedIntegerBits(targetType); ok && bits <= 32 {
|
|
4054
|
+
return "(" + left + " >>> " + right + ") >>> 0"
|
|
4055
|
+
}
|
|
3833
4056
|
return left + " >> " + right
|
|
3834
4057
|
case token.AND_NOT_ASSIGN:
|
|
3835
4058
|
return left + " & ~(" + right + ")"
|
|
@@ -3866,30 +4089,31 @@ func integerQuotientAssignValueExpr(targetType types.Type, left string, right st
|
|
|
3866
4089
|
}
|
|
3867
4090
|
|
|
3868
4091
|
func wideIntegerAssignHelper(targetType types.Type, tok token.Token) (RuntimeHelper, bool) {
|
|
3869
|
-
if !
|
|
4092
|
+
if !isRuntimeWideIntegerType(targetType) {
|
|
3870
4093
|
return "", false
|
|
3871
4094
|
}
|
|
4095
|
+
signed := isFixedSignedWideIntegerType(targetType)
|
|
3872
4096
|
switch tok {
|
|
3873
4097
|
case token.SHL_ASSIGN:
|
|
3874
|
-
return RuntimeHelperUint64Shl, true
|
|
4098
|
+
return wideIntegerHelper(signed, RuntimeHelperUint64Shl, RuntimeHelperInt64Shl), true
|
|
3875
4099
|
case token.SHR_ASSIGN:
|
|
3876
|
-
return RuntimeHelperUint64Shr, true
|
|
4100
|
+
return wideIntegerHelper(signed, RuntimeHelperUint64Shr, RuntimeHelperInt64Shr), true
|
|
3877
4101
|
case token.MUL_ASSIGN:
|
|
3878
|
-
return wideIntegerHelper(
|
|
4102
|
+
return wideIntegerHelper(signed, RuntimeHelperUint64Mul, RuntimeHelperInt64Mul), true
|
|
3879
4103
|
case token.QUO_ASSIGN:
|
|
3880
|
-
return wideIntegerHelper(
|
|
4104
|
+
return wideIntegerHelper(signed, RuntimeHelperUint64Div, RuntimeHelperInt64Div), true
|
|
3881
4105
|
case token.REM_ASSIGN:
|
|
3882
|
-
return wideIntegerHelper(
|
|
4106
|
+
return wideIntegerHelper(signed, RuntimeHelperUint64Mod, RuntimeHelperInt64Mod), true
|
|
3883
4107
|
case token.ADD_ASSIGN:
|
|
3884
|
-
return wideIntegerHelper(
|
|
4108
|
+
return wideIntegerHelper(signed, RuntimeHelperUint64Add, RuntimeHelperInt64Add), true
|
|
3885
4109
|
case token.SUB_ASSIGN:
|
|
3886
|
-
return wideIntegerHelper(
|
|
4110
|
+
return wideIntegerHelper(signed, RuntimeHelperUint64Sub, RuntimeHelperInt64Sub), true
|
|
3887
4111
|
case token.AND_ASSIGN:
|
|
3888
|
-
return wideIntegerHelper(
|
|
4112
|
+
return wideIntegerHelper(signed, RuntimeHelperUint64And, RuntimeHelperInt64And), true
|
|
3889
4113
|
case token.OR_ASSIGN:
|
|
3890
|
-
return wideIntegerHelper(
|
|
4114
|
+
return wideIntegerHelper(signed, RuntimeHelperUint64Or, RuntimeHelperInt64Or), true
|
|
3891
4115
|
case token.XOR_ASSIGN:
|
|
3892
|
-
return wideIntegerHelper(
|
|
4116
|
+
return wideIntegerHelper(signed, RuntimeHelperUint64Xor, RuntimeHelperInt64Xor), true
|
|
3893
4117
|
default:
|
|
3894
4118
|
return "", false
|
|
3895
4119
|
}
|
|
@@ -4172,7 +4396,7 @@ func (o *LoweringOwner) lowerShortDeclNewShadowAliases(
|
|
|
4172
4396
|
if entry.def == nil || aliases[entry.def] != "" {
|
|
4173
4397
|
continue
|
|
4174
4398
|
}
|
|
4175
|
-
if shortDeclDefShadowsOuterName(entry.name, entry.def) {
|
|
4399
|
+
if shortDeclDefShadowsOuterName(ctx, entry.name, entry.def) {
|
|
4176
4400
|
aliases[entry.def] = ctx.tempName("Shadow")
|
|
4177
4401
|
}
|
|
4178
4402
|
}
|
|
@@ -4201,12 +4425,24 @@ func shortDeclShadowNonValueIdents(ctx lowerFileContext, expr ast.Expr) map[*ast
|
|
|
4201
4425
|
return idents
|
|
4202
4426
|
}
|
|
4203
4427
|
|
|
4204
|
-
func shortDeclDefShadowsOuterName(name string, def types.Object) bool {
|
|
4428
|
+
func shortDeclDefShadowsOuterName(ctx lowerFileContext, name string, def types.Object) bool {
|
|
4205
4429
|
for scope := def.Parent(); scope != nil; scope = scope.Parent() {
|
|
4206
4430
|
if scope == def.Parent() {
|
|
4207
4431
|
continue
|
|
4208
4432
|
}
|
|
4209
4433
|
obj := scope.Lookup(name)
|
|
4434
|
+
if scope.Parent() == types.Universe {
|
|
4435
|
+
if obj == nil {
|
|
4436
|
+
return false
|
|
4437
|
+
}
|
|
4438
|
+
if _, isTypeName := obj.(*types.TypeName); isTypeName {
|
|
4439
|
+
return true
|
|
4440
|
+
}
|
|
4441
|
+
if _, isFunc := obj.(*types.Func); isFunc {
|
|
4442
|
+
return sameSourceFile(ctx, obj.Pos(), def.Pos()) && obj.Pos() < def.Pos()
|
|
4443
|
+
}
|
|
4444
|
+
return false
|
|
4445
|
+
}
|
|
4210
4446
|
if obj != nil && obj.Pos().IsValid() && obj.Pos() < def.Pos() {
|
|
4211
4447
|
return true
|
|
4212
4448
|
}
|
|
@@ -4214,6 +4450,40 @@ func shortDeclDefShadowsOuterName(name string, def types.Object) bool {
|
|
|
4214
4450
|
return false
|
|
4215
4451
|
}
|
|
4216
4452
|
|
|
4453
|
+
func sameSourceFile(ctx lowerFileContext, left token.Pos, right token.Pos) bool {
|
|
4454
|
+
if !left.IsValid() || !right.IsValid() || ctx.semPkg == nil || ctx.semPkg.source == nil {
|
|
4455
|
+
return false
|
|
4456
|
+
}
|
|
4457
|
+
leftPos := sourcePos(ctx.semPkg.source, left)
|
|
4458
|
+
rightPos := sourcePos(ctx.semPkg.source, right)
|
|
4459
|
+
return leftPos.file != "" && leftPos.file == rightPos.file
|
|
4460
|
+
}
|
|
4461
|
+
|
|
4462
|
+
func valueSpecUsesOuterName(ctx lowerFileContext, spec *ast.ValueSpec, name string, def types.Object) bool {
|
|
4463
|
+
if spec == nil || name == "" || def == nil {
|
|
4464
|
+
return false
|
|
4465
|
+
}
|
|
4466
|
+
usesOuter := false
|
|
4467
|
+
for _, value := range spec.Values {
|
|
4468
|
+
ast.Inspect(value, func(node ast.Node) bool {
|
|
4469
|
+
ident, ok := node.(*ast.Ident)
|
|
4470
|
+
if !ok || ident.Name != name {
|
|
4471
|
+
return true
|
|
4472
|
+
}
|
|
4473
|
+
obj := ctx.semPkg.source.TypesInfo.Uses[ident]
|
|
4474
|
+
if obj != nil && obj != def {
|
|
4475
|
+
usesOuter = true
|
|
4476
|
+
return false
|
|
4477
|
+
}
|
|
4478
|
+
return true
|
|
4479
|
+
})
|
|
4480
|
+
if usesOuter {
|
|
4481
|
+
return true
|
|
4482
|
+
}
|
|
4483
|
+
}
|
|
4484
|
+
return false
|
|
4485
|
+
}
|
|
4486
|
+
|
|
4217
4487
|
func (o *LoweringOwner) mapIndexDefaultUsesShortDeclName(
|
|
4218
4488
|
ctx lowerFileContext,
|
|
4219
4489
|
rhs ast.Expr,
|
|
@@ -5273,7 +5543,7 @@ func (o *LoweringOwner) lowerRangeFuncStmt(
|
|
|
5273
5543
|
diagnostics = append(diagnostics, assignmentDiagnostics...)
|
|
5274
5544
|
body = append(assignments, body...)
|
|
5275
5545
|
}
|
|
5276
|
-
async := ctx.asyncFunction
|
|
5546
|
+
async := ctx.asyncFunction || stmtsContainAwait(body) || o.rangeFunctionValueNeedsAwait(ctx, stmt.X)
|
|
5277
5547
|
|
|
5278
5548
|
return loweredStmt{rangeFunc: &loweredRangeFunc{
|
|
5279
5549
|
value: rangeValue,
|
|
@@ -5902,6 +6172,19 @@ func (o *LoweringOwner) lowerComplexEqualityExpr(ctx lowerFileContext, expr *ast
|
|
|
5902
6172
|
return value, true
|
|
5903
6173
|
}
|
|
5904
6174
|
|
|
6175
|
+
func (o *LoweringOwner) lowerStructEqualityExpr(ctx lowerFileContext, expr *ast.BinaryExpr, left string, right string) (string, bool) {
|
|
6176
|
+
leftType := ctx.semPkg.source.TypesInfo.TypeOf(expr.X)
|
|
6177
|
+
rightType := ctx.semPkg.source.TypesInfo.TypeOf(expr.Y)
|
|
6178
|
+
if !isStructComparableType(leftType) || !isStructComparableType(rightType) {
|
|
6179
|
+
return "", false
|
|
6180
|
+
}
|
|
6181
|
+
value := o.runtimeOwner.QualifiedHelper(RuntimeHelperComparableEqual) + "(" + left + ", " + right + ")"
|
|
6182
|
+
if expr.Op == token.NEQ {
|
|
6183
|
+
value = "!" + value
|
|
6184
|
+
}
|
|
6185
|
+
return value, true
|
|
6186
|
+
}
|
|
6187
|
+
|
|
5905
6188
|
func (o *LoweringOwner) lowerStringEqualityExpr(ctx lowerFileContext, expr *ast.BinaryExpr, left string, right string) (string, bool) {
|
|
5906
6189
|
leftType := ctx.semPkg.source.TypesInfo.TypeOf(expr.X)
|
|
5907
6190
|
rightType := ctx.semPkg.source.TypesInfo.TypeOf(expr.Y)
|
|
@@ -6030,6 +6313,9 @@ func (o *LoweringOwner) lowerExpr(ctx lowerFileContext, expr ast.Expr) (string,
|
|
|
6030
6313
|
if value, ok := o.lowerComplexEqualityExpr(ctx, typed, left, right); ok {
|
|
6031
6314
|
return value, append(leftDiagnostics, rightDiagnostics...)
|
|
6032
6315
|
}
|
|
6316
|
+
if value, ok := o.lowerStructEqualityExpr(ctx, typed, left, right); ok {
|
|
6317
|
+
return value, append(leftDiagnostics, rightDiagnostics...)
|
|
6318
|
+
}
|
|
6033
6319
|
if value, ok := o.lowerStringEqualityExpr(ctx, typed, left, right); ok {
|
|
6034
6320
|
return value, append(leftDiagnostics, rightDiagnostics...)
|
|
6035
6321
|
}
|
|
@@ -6073,6 +6359,10 @@ func (o *LoweringOwner) lowerExpr(ctx lowerFileContext, expr ast.Expr) (string,
|
|
|
6073
6359
|
return lowerPrefixUnaryExpr(typed.Op, value), diagnostics
|
|
6074
6360
|
}
|
|
6075
6361
|
if typed.Op == token.XOR {
|
|
6362
|
+
if bits, ok := unsignedIntegerBits(ctx.semPkg.source.TypesInfo.TypeOf(typed)); ok && bits <= 32 {
|
|
6363
|
+
return o.runtimeOwner.QualifiedHelper(RuntimeHelperUint) +
|
|
6364
|
+
"(~" + value + ", " + strconv.Itoa(bits) + ")", diagnostics
|
|
6365
|
+
}
|
|
6076
6366
|
return "~" + value, diagnostics
|
|
6077
6367
|
}
|
|
6078
6368
|
return value, append(diagnostics, loweringUnsupported("expression", ctx.semPkg.pkgPath, "unsupported unary operator"))
|
|
@@ -6155,7 +6445,7 @@ func isLegacyOctalLiteral(value string) bool {
|
|
|
6155
6445
|
func (o *LoweringOwner) lowerFuncLit(ctx lowerFileContext, lit *ast.FuncLit) (string, bool, []Diagnostic) {
|
|
6156
6446
|
signature, _ := ctx.semPkg.source.TypesInfo.TypeOf(lit).(*types.Signature)
|
|
6157
6447
|
deferState := &loweredDeferState{}
|
|
6158
|
-
bodyCtx := ctx.withSignature(signature).withDeferState(deferState).withoutRangeBranch()
|
|
6448
|
+
bodyCtx := ctx.withSignature(signature).withAsyncFunction(false).withDeferState(deferState).withoutRangeBranch()
|
|
6159
6449
|
asyncCompatibleParams := funcLiteralNeedsAsyncFunctionParamCalls(signature)
|
|
6160
6450
|
if asyncCompatibleParams || funcLiteralUsesFunctionIdentifierCall(ctx, lit) {
|
|
6161
6451
|
bodyCtx = bodyCtx.withAsyncFunction(true)
|
|
@@ -6276,7 +6566,7 @@ func (o *LoweringOwner) lowerIdent(ctx lowerFileContext, ident *ast.Ident, raw b
|
|
|
6276
6566
|
}
|
|
6277
6567
|
return alias
|
|
6278
6568
|
}
|
|
6279
|
-
if constObj, ok := obj.(*types.Const); ok &&
|
|
6569
|
+
if constObj, ok := obj.(*types.Const); ok && !raw {
|
|
6280
6570
|
if constValue, ok := lowerConstantValue(constObj.Val()); ok {
|
|
6281
6571
|
return constValue
|
|
6282
6572
|
}
|
|
@@ -6962,6 +7252,8 @@ func (o *LoweringOwner) lowerConversionExpr(
|
|
|
6962
7252
|
return o.runtimeOwner.QualifiedHelper(RuntimeHelperRunesToString) + "(" + value + ")", diagnostics
|
|
6963
7253
|
case isByteSliceType(sourceType):
|
|
6964
7254
|
return o.runtimeOwner.QualifiedHelper(RuntimeHelperBytesToString) + "(" + value + ")", diagnostics
|
|
7255
|
+
case overrideNamedStringType(ctx, o, sourceType):
|
|
7256
|
+
return "String(" + value + ")", diagnostics
|
|
6965
7257
|
case isStringType(sourceType):
|
|
6966
7258
|
return value, diagnostics
|
|
6967
7259
|
case isNumericType(sourceType):
|
|
@@ -7020,7 +7312,7 @@ func (o *LoweringOwner) lowerConversionExpr(
|
|
|
7020
7312
|
return renderNamedStructConversion(conversion), diagnostics
|
|
7021
7313
|
}
|
|
7022
7314
|
if isNumericType(targetType) {
|
|
7023
|
-
if constantValue, ok :=
|
|
7315
|
+
if constantValue, ok := o.lowerNumericConstantExprForTarget(ctx, expr.Args[0], targetType); ok {
|
|
7024
7316
|
return constantValue, diagnostics
|
|
7025
7317
|
}
|
|
7026
7318
|
}
|
|
@@ -7052,8 +7344,8 @@ func (o *LoweringOwner) lowerConversionExpr(
|
|
|
7052
7344
|
}
|
|
7053
7345
|
|
|
7054
7346
|
func (o *LoweringOwner) lowerWideIntegerBinaryExpr(ctx lowerFileContext, expr *ast.BinaryExpr, left string, right string) (string, bool) {
|
|
7055
|
-
resultWide :=
|
|
7056
|
-
leftWide :=
|
|
7347
|
+
resultWide := isRuntimeWideIntegerType(ctx.semPkg.source.TypesInfo.TypeOf(expr))
|
|
7348
|
+
leftWide := isRuntimeWideIntegerType(ctx.semPkg.source.TypesInfo.TypeOf(expr.X))
|
|
7057
7349
|
if !resultWide && !leftWide {
|
|
7058
7350
|
return "", false
|
|
7059
7351
|
}
|
|
@@ -7329,6 +7621,12 @@ func (o *LoweringOwner) lowerPointerReceiverMethodCall(
|
|
|
7329
7621
|
methodMemberName(selector.Sel.Name) + "(" + strings.Join(args, ", ") + ")"
|
|
7330
7622
|
return call, diagnostics, true
|
|
7331
7623
|
}
|
|
7624
|
+
if crossPackageUnexportedNamedType(ctx, receiver) {
|
|
7625
|
+
call := o.runtimeOwner.QualifiedHelper(RuntimeHelperPointerValue) +
|
|
7626
|
+
"<any>(" + receiverExpr + ")." + methodMemberName(selector.Sel.Name) +
|
|
7627
|
+
"(" + strings.Join(args, ", ") + ")"
|
|
7628
|
+
return call, diagnostics, true
|
|
7629
|
+
}
|
|
7332
7630
|
callArgs := append([]string{receiverExpr}, args...)
|
|
7333
7631
|
call := o.namedTypeExpr(ctx, receiver) + ".prototype." + selector.Sel.Name + ".call(" + strings.Join(callArgs, ", ") + ")"
|
|
7334
7632
|
return call, diagnostics, true
|
|
@@ -8492,12 +8790,40 @@ func (o *LoweringOwner) lowerStructCompositeLit(
|
|
|
8492
8790
|
func compositeLiteralFieldNeedsPreEval(ctx lowerFileContext, expr ast.Expr) bool {
|
|
8493
8791
|
switch typed := unwrapParenExpr(expr).(type) {
|
|
8494
8792
|
case *ast.CallExpr:
|
|
8793
|
+
for _, arg := range typed.Args {
|
|
8794
|
+
if compositeLiteralFieldNeedsPreEval(ctx, arg) {
|
|
8795
|
+
return true
|
|
8796
|
+
}
|
|
8797
|
+
}
|
|
8495
8798
|
if ident, ok := typed.Fun.(*ast.Ident); ok && isBuiltinCallTarget(ctx, ident) {
|
|
8496
8799
|
return false
|
|
8497
8800
|
}
|
|
8498
8801
|
return typeFromExpr(ctx, typed.Fun) == nil
|
|
8499
8802
|
case *ast.UnaryExpr:
|
|
8500
|
-
return typed.Op == token.ARROW
|
|
8803
|
+
return typed.Op == token.ARROW || compositeLiteralFieldNeedsPreEval(ctx, typed.X)
|
|
8804
|
+
case *ast.BinaryExpr:
|
|
8805
|
+
return compositeLiteralFieldNeedsPreEval(ctx, typed.X) ||
|
|
8806
|
+
compositeLiteralFieldNeedsPreEval(ctx, typed.Y)
|
|
8807
|
+
case *ast.IndexExpr:
|
|
8808
|
+
return compositeLiteralFieldNeedsPreEval(ctx, typed.X) ||
|
|
8809
|
+
compositeLiteralFieldNeedsPreEval(ctx, typed.Index)
|
|
8810
|
+
case *ast.IndexListExpr:
|
|
8811
|
+
if compositeLiteralFieldNeedsPreEval(ctx, typed.X) {
|
|
8812
|
+
return true
|
|
8813
|
+
}
|
|
8814
|
+
for _, index := range typed.Indices {
|
|
8815
|
+
if compositeLiteralFieldNeedsPreEval(ctx, index) {
|
|
8816
|
+
return true
|
|
8817
|
+
}
|
|
8818
|
+
}
|
|
8819
|
+
return false
|
|
8820
|
+
case *ast.SliceExpr:
|
|
8821
|
+
return compositeLiteralFieldNeedsPreEval(ctx, typed.X) ||
|
|
8822
|
+
compositeLiteralFieldNeedsPreEval(ctx, typed.Low) ||
|
|
8823
|
+
compositeLiteralFieldNeedsPreEval(ctx, typed.High) ||
|
|
8824
|
+
compositeLiteralFieldNeedsPreEval(ctx, typed.Max)
|
|
8825
|
+
case *ast.StarExpr:
|
|
8826
|
+
return compositeLiteralFieldNeedsPreEval(ctx, typed.X)
|
|
8501
8827
|
default:
|
|
8502
8828
|
return false
|
|
8503
8829
|
}
|
|
@@ -8562,6 +8888,9 @@ func (o *LoweringOwner) lowerArrayCompositeLit(
|
|
|
8562
8888
|
lit *ast.CompositeLit,
|
|
8563
8889
|
array *types.Array,
|
|
8564
8890
|
) (string, []Diagnostic) {
|
|
8891
|
+
if len(lit.Elts) == 0 && isByteType(array.Elem()) {
|
|
8892
|
+
return "new Uint8Array(" + strconv.FormatInt(array.Len(), 10) + ")", nil
|
|
8893
|
+
}
|
|
8565
8894
|
values := make([]string, int(array.Len()))
|
|
8566
8895
|
for idx := range values {
|
|
8567
8896
|
values[idx] = o.lowerZeroValueExprFor(ctx, array.Elem())
|
|
@@ -8715,7 +9044,7 @@ func (o *LoweringOwner) lowerValueForTarget(
|
|
|
8715
9044
|
}
|
|
8716
9045
|
}
|
|
8717
9046
|
if isNumericType(targetType) {
|
|
8718
|
-
if constantValue, ok :=
|
|
9047
|
+
if constantValue, ok := o.lowerNumericConstantExprForTarget(ctx, expr, targetType); ok {
|
|
8719
9048
|
return constantValue
|
|
8720
9049
|
}
|
|
8721
9050
|
}
|
|
@@ -8744,6 +9073,28 @@ func lowerRealNumericConstantExpr(ctx lowerFileContext, expr ast.Expr) (string,
|
|
|
8744
9073
|
}
|
|
8745
9074
|
}
|
|
8746
9075
|
|
|
9076
|
+
func (o *LoweringOwner) lowerNumericConstantExprForTarget(ctx lowerFileContext, expr ast.Expr, targetType types.Type) (string, bool) {
|
|
9077
|
+
if ctx.semPkg == nil || ctx.semPkg.source == nil {
|
|
9078
|
+
return "", false
|
|
9079
|
+
}
|
|
9080
|
+
tv, ok := ctx.semPkg.source.TypesInfo.Types[expr]
|
|
9081
|
+
if ok && tv.Value != nil {
|
|
9082
|
+
if bits, ok := unsignedIntegerBits(targetType); ok && bits >= 64 {
|
|
9083
|
+
if value, ok := lowerWideIntegerConstantValue(tv.Value); ok {
|
|
9084
|
+
return o.runtimeOwner.QualifiedHelper(RuntimeHelperUint) + "(" +
|
|
9085
|
+
strconv.Quote(value) + ", 64)", true
|
|
9086
|
+
}
|
|
9087
|
+
}
|
|
9088
|
+
if bits, ok := signedIntegerBits(targetType); ok && bits >= 64 {
|
|
9089
|
+
if value, ok := lowerWideIntegerConstantValue(tv.Value); ok {
|
|
9090
|
+
return o.runtimeOwner.QualifiedHelper(RuntimeHelperInt) + "(" +
|
|
9091
|
+
strconv.Quote(value) + ", 64)", true
|
|
9092
|
+
}
|
|
9093
|
+
}
|
|
9094
|
+
}
|
|
9095
|
+
return lowerRealNumericConstantExpr(ctx, expr)
|
|
9096
|
+
}
|
|
9097
|
+
|
|
8747
9098
|
func isRealNumericConstantExpr(ctx lowerFileContext, expr ast.Expr) bool {
|
|
8748
9099
|
if ctx.semPkg != nil && ctx.semPkg.source != nil {
|
|
8749
9100
|
if tv, ok := ctx.semPkg.source.TypesInfo.Types[expr]; ok && tv.Value != nil {
|
|
@@ -8789,6 +9140,9 @@ func (o *LoweringOwner) lowerValueForTargetTypes(
|
|
|
8789
9140
|
return wrapper
|
|
8790
9141
|
}
|
|
8791
9142
|
}
|
|
9143
|
+
if wrapper := o.lowerNumericInterfaceWrapper(ctx, targetType, sourceType, value); wrapper != "" {
|
|
9144
|
+
return wrapper
|
|
9145
|
+
}
|
|
8792
9146
|
if isInterfaceType(targetType) && isStructValueType(sourceType) {
|
|
8793
9147
|
if cloneStructValue {
|
|
8794
9148
|
value = o.lowerStructClone(value)
|
|
@@ -8837,6 +9191,25 @@ func (o *LoweringOwner) lowerValueForTargetTypes(
|
|
|
8837
9191
|
return value
|
|
8838
9192
|
}
|
|
8839
9193
|
|
|
9194
|
+
func (o *LoweringOwner) lowerNumericInterfaceWrapper(
|
|
9195
|
+
ctx lowerFileContext,
|
|
9196
|
+
targetType types.Type,
|
|
9197
|
+
sourceType types.Type,
|
|
9198
|
+
value string,
|
|
9199
|
+
) string {
|
|
9200
|
+
if targetType == nil || sourceType == nil || !isInterfaceType(targetType) || isInterfaceType(sourceType) {
|
|
9201
|
+
return ""
|
|
9202
|
+
}
|
|
9203
|
+
basic, ok := types.Unalias(sourceType).(*types.Basic)
|
|
9204
|
+
if !ok || basic.Info()&types.IsNumeric == 0 || basic.Info()&types.IsUntyped != 0 {
|
|
9205
|
+
return ""
|
|
9206
|
+
}
|
|
9207
|
+
return o.runtimeOwner.QualifiedHelper(RuntimeHelperNamedValueInterfaceValue) +
|
|
9208
|
+
"<" + o.tsTypeFor(ctx, targetType) + ">(" + value + ", " +
|
|
9209
|
+
strconv.Quote(goRuntimeTypeString(sourceType)) + ", {}, " +
|
|
9210
|
+
o.runtimeTypeInfoExpr(sourceType) + ")"
|
|
9211
|
+
}
|
|
9212
|
+
|
|
8840
9213
|
func isBasicFixedWideIntegerType(typ types.Type) bool {
|
|
8841
9214
|
basic, ok := types.Unalias(typ).(*types.Basic)
|
|
8842
9215
|
if !ok {
|
|
@@ -8876,7 +9249,8 @@ func (o *LoweringOwner) lowerNamedValueInterfaceWrapper(
|
|
|
8876
9249
|
}
|
|
8877
9250
|
return o.runtimeOwner.QualifiedHelper(RuntimeHelperNamedValueInterfaceValue) +
|
|
8878
9251
|
"<" + o.tsTypeFor(ctx, targetType) + ">(" + value + ", " +
|
|
8879
|
-
strconv.Quote(goRuntimeTypeString(sourceType)) + ", " + methods + "
|
|
9252
|
+
strconv.Quote(goRuntimeTypeString(sourceType)) + ", " + methods + ", " +
|
|
9253
|
+
o.runtimeTypeInfoExpr(sourceType) + ")"
|
|
8880
9254
|
}
|
|
8881
9255
|
|
|
8882
9256
|
func (o *LoweringOwner) lowerPrimitiveErrorWrapper(ctx lowerFileContext, sourceType types.Type, value string) string {
|
|
@@ -8898,7 +9272,8 @@ func (o *LoweringOwner) lowerPrimitiveErrorWrapper(ctx lowerFileContext, sourceT
|
|
|
8898
9272
|
}
|
|
8899
9273
|
return o.runtimeOwner.QualifiedHelper(RuntimeHelperNamedValueInterfaceValue) +
|
|
8900
9274
|
"<$.GoError>(" + value + ", " + strconv.Quote(goRuntimeTypeString(sourceType)) +
|
|
8901
|
-
", {\"Error\": " + o.methodFunctionExpr(ctx, named, fn, "Error") + "}
|
|
9275
|
+
", {\"Error\": " + o.methodFunctionExpr(ctx, named, fn, "Error") + "}, " +
|
|
9276
|
+
o.runtimeTypeInfoExpr(sourceType) + ")"
|
|
8902
9277
|
}
|
|
8903
9278
|
|
|
8904
9279
|
func (o *LoweringOwner) lowerStructClone(value string) string {
|
|
@@ -8955,7 +9330,7 @@ func (o *LoweringOwner) lowerZeroValueExprFor(ctx lowerFileContext, typ types.Ty
|
|
|
8955
9330
|
|
|
8956
9331
|
func (o *LoweringOwner) lowerDeclarationZeroValueExpr(ctx lowerFileContext, typ types.Type) string {
|
|
8957
9332
|
if isFunctionType(typ) {
|
|
8958
|
-
return "null as " + o.
|
|
9333
|
+
return "null as unknown as " + o.tsFunctionZeroValueTypeFor(ctx, typ)
|
|
8959
9334
|
}
|
|
8960
9335
|
typeParam, ok := types.Unalias(typ).(*types.TypeParam)
|
|
8961
9336
|
if !ok {
|
|
@@ -8972,6 +9347,13 @@ func (o *LoweringOwner) lowerDeclarationZeroValueExpr(ctx lowerFileContext, typ
|
|
|
8972
9347
|
"(__typeArgs, " + strconv.Quote(typeParam.Obj().Name()) + ", " + zeroValueExpr(typ) + ")"
|
|
8973
9348
|
}
|
|
8974
9349
|
|
|
9350
|
+
func (o *LoweringOwner) tsFunctionZeroValueTypeFor(ctx lowerFileContext, typ types.Type) string {
|
|
9351
|
+
if signature := unnamedSignatureForType(typ); signature != nil {
|
|
9352
|
+
return o.tsAsyncCompatibleFunctionTypeFor(ctx, signature)
|
|
9353
|
+
}
|
|
9354
|
+
return o.tsTypeFor(ctx, typ)
|
|
9355
|
+
}
|
|
9356
|
+
|
|
8975
9357
|
func (o *LoweringOwner) runtimeTypeInfoExpr(typ types.Type) string {
|
|
8976
9358
|
return o.runtimeTypeInfoExprWithSeen(typ, make(map[types.Type]bool))
|
|
8977
9359
|
}
|
|
@@ -9588,6 +9970,11 @@ func namedFunctionType(typ types.Type) *types.Named {
|
|
|
9588
9970
|
return named
|
|
9589
9971
|
}
|
|
9590
9972
|
|
|
9973
|
+
func overrideNamedStringType(ctx lowerFileContext, owner *LoweringOwner, typ types.Type) bool {
|
|
9974
|
+
named, _ := types.Unalias(typ).(*types.Named)
|
|
9975
|
+
return named != nil && isStringType(named) && owner.typeUsesOverride(named)
|
|
9976
|
+
}
|
|
9977
|
+
|
|
9591
9978
|
func isBuiltinErrorType(typ types.Type) bool {
|
|
9592
9979
|
if typ == nil {
|
|
9593
9980
|
return false
|
|
@@ -9738,6 +10125,16 @@ func isStructValueType(typ types.Type) bool {
|
|
|
9738
10125
|
return namedStructType(typ) != nil
|
|
9739
10126
|
}
|
|
9740
10127
|
|
|
10128
|
+
func isStructComparableType(typ types.Type) bool {
|
|
10129
|
+
if typ == nil {
|
|
10130
|
+
return false
|
|
10131
|
+
}
|
|
10132
|
+
if _, ok := types.Unalias(typ).Underlying().(*types.Struct); !ok {
|
|
10133
|
+
return false
|
|
10134
|
+
}
|
|
10135
|
+
return types.Comparable(typ)
|
|
10136
|
+
}
|
|
10137
|
+
|
|
9741
10138
|
func isPointerToStructType(typ types.Type) bool {
|
|
9742
10139
|
pointer, ok := types.Unalias(typ).Underlying().(*types.Pointer)
|
|
9743
10140
|
if !ok {
|
|
@@ -9917,6 +10314,14 @@ func isFixedSignedWideIntegerType(typ types.Type) bool {
|
|
|
9917
10314
|
return ok && basic.Kind() == types.Int64
|
|
9918
10315
|
}
|
|
9919
10316
|
|
|
10317
|
+
func isRuntimeWideIntegerType(typ types.Type) bool {
|
|
10318
|
+
if isFixedWideIntegerType(typ) {
|
|
10319
|
+
return true
|
|
10320
|
+
}
|
|
10321
|
+
bits, ok := unsignedIntegerBits(typ)
|
|
10322
|
+
return ok && bits > 32
|
|
10323
|
+
}
|
|
10324
|
+
|
|
9920
10325
|
func isRuneSliceType(typ types.Type) bool {
|
|
9921
10326
|
slice, ok := types.Unalias(typ).Underlying().(*types.Slice)
|
|
9922
10327
|
return ok && isRuneType(slice.Elem())
|
|
@@ -10002,8 +10407,7 @@ func (o *LoweringOwner) functionAsync(ctx lowerFileContext, fn *types.Func) bool
|
|
|
10002
10407
|
if fn == nil || ctx.model == nil {
|
|
10003
10408
|
return false
|
|
10004
10409
|
}
|
|
10005
|
-
|
|
10006
|
-
return semFn != nil && semFn.async
|
|
10410
|
+
return ctx.model.functionAsync(fn)
|
|
10007
10411
|
}
|
|
10008
10412
|
|
|
10009
10413
|
func (o *LoweringOwner) callNeedsAwait(ctx lowerFileContext, fun ast.Expr) bool {
|
|
@@ -10152,6 +10556,18 @@ func (o *LoweringOwner) inferGenericTypeArg(
|
|
|
10152
10556
|
}
|
|
10153
10557
|
return
|
|
10154
10558
|
}
|
|
10559
|
+
if paramNamed, ok := types.Unalias(paramType).(*types.Named); ok {
|
|
10560
|
+
if argNamed, ok := types.Unalias(argType).(*types.Named); ok &&
|
|
10561
|
+
namedOriginsEqual(paramNamed, argNamed) {
|
|
10562
|
+
paramArgs := paramNamed.TypeArgs()
|
|
10563
|
+
argArgs := argNamed.TypeArgs()
|
|
10564
|
+
if paramArgs != nil && argArgs != nil {
|
|
10565
|
+
for idx := range min(paramArgs.Len(), argArgs.Len()) {
|
|
10566
|
+
o.inferGenericTypeArg(inferred, paramArgs.At(idx), argArgs.At(idx))
|
|
10567
|
+
}
|
|
10568
|
+
}
|
|
10569
|
+
}
|
|
10570
|
+
}
|
|
10155
10571
|
switch param := types.Unalias(paramType).Underlying().(type) {
|
|
10156
10572
|
case *types.Slice:
|
|
10157
10573
|
if arg, ok := types.Unalias(argType).Underlying().(*types.Slice); ok {
|
|
@@ -10164,6 +10580,24 @@ func (o *LoweringOwner) inferGenericTypeArg(
|
|
|
10164
10580
|
}
|
|
10165
10581
|
}
|
|
10166
10582
|
|
|
10583
|
+
func namedOriginsEqual(a, b *types.Named) bool {
|
|
10584
|
+
if a == nil || b == nil {
|
|
10585
|
+
return false
|
|
10586
|
+
}
|
|
10587
|
+
aOrigin := a.Origin()
|
|
10588
|
+
if aOrigin == nil {
|
|
10589
|
+
aOrigin = a
|
|
10590
|
+
}
|
|
10591
|
+
bOrigin := b.Origin()
|
|
10592
|
+
if bOrigin == nil {
|
|
10593
|
+
bOrigin = b
|
|
10594
|
+
}
|
|
10595
|
+
if aOrigin.Obj() == nil || bOrigin.Obj() == nil {
|
|
10596
|
+
return aOrigin == bOrigin
|
|
10597
|
+
}
|
|
10598
|
+
return aOrigin.Obj() == bOrigin.Obj()
|
|
10599
|
+
}
|
|
10600
|
+
|
|
10167
10601
|
func (o *LoweringOwner) genericTypeDescriptorExpr(ctx lowerFileContext, typ types.Type) string {
|
|
10168
10602
|
if typeParam, ok := types.Unalias(typ).(*types.TypeParam); ok && typeParamInScope(ctx, typeParam) {
|
|
10169
10603
|
return "__typeArgs?.[" + strconv.Quote(typeParam.Obj().Name()) + "] ?? { type: " +
|
|
@@ -10377,6 +10811,32 @@ func basicRuntimeName(basic *types.Basic) string {
|
|
|
10377
10811
|
return "bool"
|
|
10378
10812
|
case types.String:
|
|
10379
10813
|
return "string"
|
|
10814
|
+
case types.Int:
|
|
10815
|
+
return "int"
|
|
10816
|
+
case types.Int8:
|
|
10817
|
+
return "int8"
|
|
10818
|
+
case types.Int16:
|
|
10819
|
+
return "int16"
|
|
10820
|
+
case types.Int32:
|
|
10821
|
+
return "int32"
|
|
10822
|
+
case types.Int64:
|
|
10823
|
+
return "int64"
|
|
10824
|
+
case types.Uint:
|
|
10825
|
+
return "uint"
|
|
10826
|
+
case types.Uint8:
|
|
10827
|
+
return "uint8"
|
|
10828
|
+
case types.Uint16:
|
|
10829
|
+
return "uint16"
|
|
10830
|
+
case types.Uint32:
|
|
10831
|
+
return "uint32"
|
|
10832
|
+
case types.Uint64:
|
|
10833
|
+
return "uint64"
|
|
10834
|
+
case types.Uintptr:
|
|
10835
|
+
return "uintptr"
|
|
10836
|
+
case types.Float32:
|
|
10837
|
+
return "float32"
|
|
10838
|
+
case types.Float64:
|
|
10839
|
+
return "float64"
|
|
10380
10840
|
case types.Complex64:
|
|
10381
10841
|
return "complex64"
|
|
10382
10842
|
case types.Complex128:
|