Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit b123493

Browse filesBrowse files
authored
Merge pull request #1249 from nevkontakte/generics16
Add type parameter support for built-in functions.
2 parents 29a46a5 + 72ba5b1 commit b123493
Copy full SHA for b123493

File tree

5 files changed

+320
-44
lines changed
Filter options

5 files changed

+320
-44
lines changed

‎compiler/expressions.go

Copy file name to clipboardExpand all lines: compiler/expressions.go
+28-29Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,26 +1049,16 @@ func (fc *funcContext) translateBuiltin(name string, sig *types.Signature, args
10491049
return fc.formatExpr("$newDataPointer(%e, %s)", fc.zeroValue(t.Elem()), fc.typeName(t))
10501050
}
10511051
case "make":
1052-
switch argType := fc.pkgCtx.TypeOf(args[0]).Underlying().(type) {
1053-
case *types.Slice:
1054-
t := fc.typeName(fc.pkgCtx.TypeOf(args[0]))
1055-
if len(args) == 3 {
1056-
return fc.formatExpr("$makeSlice(%s, %f, %f)", t, args[1], args[2])
1057-
}
1058-
return fc.formatExpr("$makeSlice(%s, %f)", t, args[1])
1059-
case *types.Map:
1060-
if len(args) == 2 && fc.pkgCtx.Types[args[1]].Value == nil {
1061-
return fc.formatExpr(`((%1f < 0 || %1f > 2147483647) ? $throwRuntimeError("makemap: size out of range") : new $global.Map())`, args[1])
1062-
}
1063-
return fc.formatExpr("new $global.Map()")
1064-
case *types.Chan:
1065-
length := "0"
1066-
if len(args) == 2 {
1067-
length = fc.formatExpr("%f", args[1]).String()
1068-
}
1069-
return fc.formatExpr("new $Chan(%s, %s)", fc.typeName(fc.pkgCtx.TypeOf(args[0]).Underlying().(*types.Chan).Elem()), length)
1052+
typeName := fc.typeName(fc.pkgCtx.TypeOf(args[0]))
1053+
switch len(args) {
1054+
case 1:
1055+
return fc.formatExpr("%s.$make()", typeName)
1056+
case 2:
1057+
return fc.formatExpr("%s.$make(%f)", typeName, args[1])
1058+
case 3:
1059+
return fc.formatExpr("%s.$make(%f, %f)", typeName, args[1], args[2])
10701060
default:
1071-
panic(fmt.Sprintf("Unhandled make type: %T\n", argType))
1061+
panic(fmt.Errorf("builtin make(): invalid number of arguments: %d", len(args)))
10721062
}
10731063
case "len":
10741064
switch argType := fc.pkgCtx.TypeOf(args[0]).Underlying().(type) {
@@ -1082,6 +1072,8 @@ func (fc *funcContext) translateBuiltin(name string, sig *types.Signature, args
10821072
return fc.formatExpr("(%e ? %e.size : 0)", args[0], args[0])
10831073
case *types.Chan:
10841074
return fc.formatExpr("%e.$buffer.length", args[0])
1075+
case *types.Interface: // *types.TypeParam has interface as underlying type.
1076+
return fc.formatExpr("%s.$len(%e)", fc.typeName(fc.pkgCtx.TypeOf(args[0])), args[0])
10851077
// length of array is constant
10861078
default:
10871079
panic(fmt.Sprintf("Unhandled len type: %T\n", argType))
@@ -1092,9 +1084,13 @@ func (fc *funcContext) translateBuiltin(name string, sig *types.Signature, args
10921084
return fc.formatExpr("%e.$capacity", args[0])
10931085
case *types.Pointer:
10941086
return fc.formatExpr("(%e, %d)", args[0], argType.Elem().(*types.Array).Len())
1095-
// capacity of array is constant
1087+
case *types.Array:
1088+
// This should never happen™
1089+
panic(fmt.Errorf("array capacity should have been inlined as constant"))
1090+
case *types.Interface: // *types.TypeParam has interface as underlying type.
1091+
return fc.formatExpr("%s.$cap(%e)", fc.typeName(fc.pkgCtx.TypeOf(args[0])), args[0])
10961092
default:
1097-
panic(fmt.Sprintf("Unhandled cap type: %T\n", argType))
1093+
panic(fmt.Errorf("unhandled cap type: %T", argType))
10981094
}
10991095
case "panic":
11001096
return fc.formatExpr("$panic(%s)", fc.translateImplicitConversion(args[0], types.NewInterface(nil, nil)))
@@ -1103,11 +1099,11 @@ func (fc *funcContext) translateBuiltin(name string, sig *types.Signature, args
11031099
argStr := fc.translateArgs(sig, args, ellipsis)
11041100
return fc.formatExpr("$appendSlice(%s, %s)", argStr[0], argStr[1])
11051101
}
1106-
sliceType := sig.Results().At(0).Type().Underlying().(*types.Slice)
1107-
return fc.formatExpr("$append(%e, %s)", args[0], strings.Join(fc.translateExprSlice(args[1:], sliceType.Elem()), ", "))
1102+
elType := sig.Params().At(1).Type().(*types.Slice).Elem()
1103+
return fc.formatExpr("$append(%e, %s)", args[0], strings.Join(fc.translateExprSlice(args[1:], elType), ", "))
11081104
case "delete":
11091105
args = fc.expandTupleArgs(args)
1110-
keyType := fc.pkgCtx.TypeOf(args[0]).Underlying().(*types.Map).Key()
1106+
keyType := sig.Params().At(1).Type()
11111107
return fc.formatExpr(
11121108
`$mapDelete(%1e, %2s.keyFor(%3s))`,
11131109
args[0],
@@ -1116,10 +1112,8 @@ func (fc *funcContext) translateBuiltin(name string, sig *types.Signature, args
11161112
)
11171113
case "copy":
11181114
args = fc.expandTupleArgs(args)
1119-
if basic, isBasic := fc.pkgCtx.TypeOf(args[1]).Underlying().(*types.Basic); isBasic && isString(basic) {
1120-
return fc.formatExpr("$copyString(%e, %e)", args[0], args[1])
1121-
}
1122-
return fc.formatExpr("$copySlice(%e, %e)", args[0], args[1])
1115+
dst, src := args[0], args[1]
1116+
return fc.formatExpr("%s.$copy(%e, %e)", fc.typeName(fc.pkgCtx.TypeOf(src)), dst, src)
11231117
case "print":
11241118
args = fc.expandTupleArgs(args)
11251119
return fc.formatExpr("$print(%s)", strings.Join(fc.translateExprSlice(args, nil), ", "))
@@ -1573,11 +1567,16 @@ func (fc *funcContext) formatExprInternal(format string, a []interface{}, parens
15731567
out.WriteString(strconv.FormatInt(d, 10))
15741568
return
15751569
}
1576-
if is64Bit(fc.pkgCtx.TypeOf(e).Underlying().(*types.Basic)) {
1570+
if t, ok := fc.pkgCtx.TypeOf(e).Underlying().(*types.Basic); ok && is64Bit(t) {
15771571
out.WriteString("$flatten64(")
15781572
writeExpr("")
15791573
out.WriteString(")")
15801574
return
1575+
} else if t, ok := fc.pkgCtx.TypeOf(e).(*types.TypeParam); ok {
1576+
out.WriteString("$flatten64(")
1577+
writeExpr("")
1578+
fmt.Fprintf(out, ", %s)", fc.typeName(t))
1579+
return
15811580
}
15821581
writeExpr("")
15831582
case 'h':

‎compiler/prelude/types.js

Copy file name to clipboardExpand all lines: compiler/prelude/types.js
+20-1Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ var $newType = (size, kind, string, named, pkg, exported, constructor) => {
9393
typ.wrapped = true;
9494
typ.wrap = (v) => new typ(v);
9595
typ.keyFor = x => { return "$" + x; };
96+
typ.$len = (v) => v.length;
97+
typ.$copy = (dst, src) => $copyString(dst, src);
9698
break;
9799

98100
case $kindFloat32:
@@ -163,6 +165,8 @@ var $newType = (size, kind, string, named, pkg, exported, constructor) => {
163165
typ.ptr.init(typ);
164166
Object.defineProperty(typ.ptr.nil, "nilCheck", { get: $throwNilPointerError });
165167
};
168+
typ.$len = (v) => typ.len;
169+
typ.$cap = (v) => typ.len;
166170
break;
167171

168172
case $kindChan:
@@ -175,6 +179,9 @@ var $newType = (size, kind, string, named, pkg, exported, constructor) => {
175179
typ.sendOnly = sendOnly;
176180
typ.recvOnly = recvOnly;
177181
};
182+
typ.$make = (bufsize) => new $Chan(typ.elem, bufsize ? bufsize : 0);
183+
typ.$len = (v) => v.$buffer.length;
184+
typ.$cap = (v) => v.$capacity;
178185
break;
179186

180187
case $kindFunc:
@@ -210,6 +217,12 @@ var $newType = (size, kind, string, named, pkg, exported, constructor) => {
210217
typ.elem = elem;
211218
typ.comparable = false;
212219
};
220+
typ.$make = (size) => {
221+
if (size === undefined) { size = 0; }
222+
if (size < 0 || size > 2147483647) { $throwRuntimeError("makemap: size out of range"); }
223+
return new $global.Map();
224+
};
225+
typ.$len = (v) => v ? v.size : 0;
213226
break;
214227

215228
case $kindPtr:
@@ -230,6 +243,8 @@ var $newType = (size, kind, string, named, pkg, exported, constructor) => {
230243
}
231244
typ.nil = new typ($throwNilPointerError, $throwNilPointerError);
232245
};
246+
typ.$len = (v) => typ.elem.$len(typ.wrapped ? v : v.$get());
247+
typ.$cap = (v) => typ.elem.$cap(typ.wrapped ? v : v.$get());
233248
break;
234249

235250
case $kindSlice:
@@ -250,6 +265,10 @@ var $newType = (size, kind, string, named, pkg, exported, constructor) => {
250265
typ.nativeArray = $nativeArray(elem.kind);
251266
typ.nil = new typ([]);
252267
};
268+
typ.$make = (size, capacity) => $makeSlice(typ, size, capacity);
269+
typ.$len = (v) => v.$length;
270+
typ.$cap = (v) => v.$capacity;
271+
typ.$copy = (dst, src) => $copySlice(dst, src);
253272
break;
254273

255274
case $kindStruct:
@@ -838,7 +857,7 @@ var $ptrType = elem => {
838857
};
839858

840859
var $newDataPointer = (data, constructor) => {
841-
if (constructor.elem.kind === $kindStruct) {
860+
if (constructor.elem.kind === $kindStruct || constructor.elem.kind === $kindArray) {
842861
return data;
843862
}
844863
return new constructor(() => { return data; }, v => { data = v; });

‎compiler/utils.go

Copy file name to clipboardExpand all lines: compiler/utils.go
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,8 @@ func toJavaScriptType(t *types.Basic) string {
704704
return "Int32"
705705
case types.UnsafePointer:
706706
return "UnsafePointer"
707+
case types.UntypedString:
708+
return "String"
707709
default:
708710
name := t.String()
709711
return strings.ToUpper(name[:1]) + name[1:]

‎tests/gorepo/run.go

Copy file name to clipboardExpand all lines: tests/gorepo/run.go
+12-14Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -155,20 +155,18 @@ var knownFails = map[string]failReason{
155155
// Failures related to the lack of generics support. Ideally, this section
156156
// should be emptied once https://github.com/gopherjs/gopherjs/issues/1013 is
157157
// fixed.
158-
"typeparam/absdiff2.go": {category: generics, desc: "missing support for unary minus operator"},
159-
"typeparam/absdiff3.go": {category: generics, desc: "missing support for unary minus operator"},
160-
"typeparam/boundmethod.go": {category: generics, desc: "missing support for method expressions with a type param"},
161-
"typeparam/dictionaryCapture.go": {category: generics, desc: "make() doesn't support generic slice types"},
162-
"typeparam/double.go": {category: generics, desc: "make() doesn't support generic slice types"},
163-
"typeparam/index2.go": {category: generics, desc: "missing index operator support for generic types"},
164-
"typeparam/issue47716.go": {category: generics, desc: "unsafe.Sizeof() doesn't work with generic types"},
165-
"typeparam/issue48453.go": {category: generics, desc: "make() doesn't support generic slice types"},
166-
"typeparam/issue49295.go": {category: generics, desc: "len() doesn't support generic pointer to array types"},
167-
"typeparam/issue51303.go": {category: generics, desc: "missing support for range over type parameter"},
168-
"typeparam/nested.go": {category: generics, desc: "missing comparison operator support for generic types"},
169-
"typeparam/typeswitch2.go": {category: generics, desc: "complex types have different print() format"},
170-
"typeparam/typeswitch3.go": {category: generics, desc: "missing support for type switching on generic types"},
171-
"typeparam/typeswitch5.go": {category: generics, desc: "different print() format for floating point types"},
158+
"typeparam/absdiff2.go": {category: generics, desc: "missing support for unary minus operator"},
159+
"typeparam/absdiff3.go": {category: generics, desc: "missing support for unary minus operator"},
160+
"typeparam/boundmethod.go": {category: generics, desc: "missing support for method expressions with a type param"},
161+
"typeparam/double.go": {category: generics, desc: "missing support for range over type parameter"},
162+
"typeparam/index2.go": {category: generics, desc: "missing index operator support for generic types"},
163+
"typeparam/issue47716.go": {category: generics, desc: "unsafe.Sizeof() doesn't work with generic types"},
164+
"typeparam/issue48453.go": {category: generics, desc: "missing support for range over type parameter"},
165+
"typeparam/issue51303.go": {category: generics, desc: "missing support for range over type parameter"},
166+
"typeparam/nested.go": {category: generics, desc: "missing comparison operator support for generic types"},
167+
"typeparam/typeswitch2.go": {category: generics, desc: "complex types have different print() format"},
168+
"typeparam/typeswitch3.go": {category: generics, desc: "missing support for type switching on generic types"},
169+
"typeparam/typeswitch5.go": {category: generics, desc: "different print() format for floating point types"},
172170
}
173171

174172
type failCategory uint8

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.