// testMainSlice emits to fn code to construct a slice of type slice // (one of []testing.Internal{Test,Benchmark,Example}) for all // functions in testfuncs. It returns the slice value. // func testMainSlice(fn *Function, testfuncs []*Function, slice types.Type) Value { if testfuncs == nil { return nilConst(slice) } tElem := slice.(*types.Slice).Elem() tPtrString := types.NewPointer(tString) tPtrElem := types.NewPointer(tElem) tPtrFunc := types.NewPointer(funcField(slice)) // Emit: array = new [n]testing.InternalTest tArray := types.NewArray(tElem, int64(len(testfuncs))) array := emitNew(fn, tArray, token.NoPos) array.Comment = "test main" for i, testfunc := range testfuncs { // Emit: pitem = &array[i] ia := &IndexAddr{X: array, Index: intConst(int64(i))} ia.setType(tPtrElem) pitem := fn.emit(ia) // Emit: pname = &pitem.Name fa := &FieldAddr{X: pitem, Field: 0} // .Name fa.setType(tPtrString) pname := fn.emit(fa) // Emit: *pname = "testfunc" emitStore(fn, pname, stringConst(testfunc.Name()), token.NoPos) // Emit: pfunc = &pitem.F fa = &FieldAddr{X: pitem, Field: 1} // .F fa.setType(tPtrFunc) pfunc := fn.emit(fa) // Emit: *pfunc = testfunc emitStore(fn, pfunc, testfunc, token.NoPos) } // Emit: slice array[:] sl := &Slice{X: array} sl.setType(slice) return fn.emit(sl) }
// sliceToArray returns the type representing the arrays to which // slice type slice points. func sliceToArray(slice types.Type) *types.Array { return types.NewArray(slice.Underlying().(*types.Slice).Elem(), 1) }