or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-usage.mdindex.mdsafe-transforms.mdunsafe-transforms.md
tile.json

unsafe-transforms.mddocs/

0

# Unsafe Transforms

1

2

Unsafe transforms should be applied with caution. They either use heuristics which can't guarantee equivalent code, or they have significant bugs which can break your code.

3

4

## Capabilities

5

6

### Let/Const Variables

7

8

Converts `var` to `let`/`const` based on usage patterns.

9

10

```javascript { .api }

11

// Transform name: "let"

12

```

13

14

**What it transforms:**

15

16

- Never-modified variables to `const`

17

- Block-scoped variables to `let`

18

- Properly recognizes block-scoping rules

19

- Splits single var declarations to multiple let/const if needed

20

- Recognizes destructuring assignments

21

22

**Limitations and Bugs:**

23

24

- BUG: Fails with repeated variable definitions that use destructuring

25

- BUG: Fails with closure over a loop variable

26

- BUG: Fails when function closes over variable declared after function is called

27

- Variables that conflict with block-scoping are not converted

28

- Repeated declarations of the same var are not converted

29

30

**Usage Example:**

31

32

```javascript

33

// Before

34

var name = 'John'; // Never modified

35

var age = 25; // Modified later

36

age = 26;

37

var items = [1, 2, 3]; // Never modified

38

39

// After

40

const name = 'John'; // Converted to const

41

let age = 25; // Converted to let

42

age = 26;

43

const items = [1, 2, 3]; // Converted to const

44

```

45

46

### ES6 Classes

47

48

Converts function constructors and prototypes to ES6 classes.

49

50

```javascript { .api }

51

// Transform name: "class"

52

```

53

54

**What it transforms:**

55

56

- `Foo.prototype.method = function(){}` to class methods

57

- `Foo.prototype = { ...methods... }` to class body

58

- Static methods like `Foo.method = function(){}`

59

- Getters/setters defined with `Object.defineProperty()`

60

- Inheritance with `Child.prototype = new Parent()`

61

- Inheritance with `util.inherits(Child, Parent)`

62

- Superclass constructor calls to `super()`

63

- Superclass method calls to `super.method()`

64

65

**Limitations:**

66

67

- Does not require `super()` call in subclass constructor

68

- Does not enforce `super()` call position in subclass constructor

69

- Does not support namespaced classes

70

71

**Usage Example:**

72

73

```javascript

74

// Before

75

function Person(name) {

76

this.name = name;

77

}

78

79

Person.prototype.greet = function() {

80

return 'Hello, ' + this.name;

81

};

82

83

Person.prototype.getName = function() {

84

return this.name;

85

};

86

87

// After

88

class Person {

89

constructor(name) {

90

this.name = name;

91

}

92

93

greet() {

94

return 'Hello, ' + this.name;

95

}

96

97

getName() {

98

return this.name;

99

}

100

}

101

```

102

103

### ES6 Modules

104

105

Converts CommonJS modules to ES6 import/export syntax.

106

107

```javascript { .api }

108

// Transform name: "commonjs"

109

```

110

111

**What it transforms:**

112

113

- `var foo = require("foo")` to `import foo from "foo"`

114

- `var bar = require("foo").bar` to `import {bar} from "foo"`

115

- `var {bar} = require("foo")` to `import {bar} from "foo"`

116

- `module.exports = <anything>` to `export default <anything>`

117

- `exports.foo = function(){}` to `export function foo(){}`

118

- `exports.Foo = class {}` to `export class Foo {}`

119

- `exports.foo = 123` to `export var foo = 123`

120

- `exports.foo = bar` to `export {bar as foo}`

121

122

**Limitations:**

123

124

- Does not check if named export conflicts with existing variable names

125

- Ignores imports/exports inside nested blocks/functions

126

- Only handles `require()` calls in `var` declarations

127

- Does not ensure that imported variable is treated as `const`

128

- Does not ensure named exports are imported with correct ES6 syntax

129

130

**Usage Example:**

131

132

```javascript

133

// Before

134

var fs = require('fs');

135

var {readFile} = require('fs');

136

var express = require('express');

137

138

exports.readData = function() {

139

return fs.readFileSync('data.txt');

140

};

141

142

module.exports = {

143

version: '1.0.0'

144

};

145

146

// After

147

import fs from 'fs';

148

import {readFile} from 'fs';

149

import express from 'express';

150

151

export function readData() {

152

return fs.readFileSync('data.txt');

153

}

154

155

export default {

156

version: '1.0.0'

157

};

158

```

159

160

### Template Literals

161

162

Converts string concatenation to template literals.

163

164

```javascript { .api }

165

// Transform name: "template"

166

```

167

168

**What it transforms:**

169

170

- String concatenation using `+` to template literals

171

- Variables and expressions to `${...}` syntax

172

173

**Limitations and Bugs:**

174

175

- BUG: Removes indentation of multi-line strings

176

- LIMITATION: Ignores difference between `.toString()` and `.valueOf()`

177

178

**Usage Example:**

179

180

```javascript

181

// Before

182

var message = 'Hello ' + name + ', you have ' + count + ' messages';

183

var url = 'https://api.example.com/users/' + userId + '/profile';

184

185

// After

186

var message = `Hello ${name}, you have ${count} messages`;

187

var url = `https://api.example.com/users/${userId}/profile`;

188

```

189

190

### Default Parameters

191

192

Converts default parameter patterns to ES6 default parameters.

193

194

```javascript { .api }

195

// Transform name: "default-param"

196

```

197

198

**What it transforms:**

199

200

- `a = a || 2` patterns to default parameters

201

- `a = a ? a : 2` patterns to default parameters

202

- `a = typeof a !== 'undefined' ? a : 2` patterns

203

204

**Usage Example:**

205

206

```javascript

207

// Before

208

function greet(name, greeting) {

209

name = name || 'World';

210

greeting = greeting || 'Hello';

211

return greeting + ', ' + name + '!';

212

}

213

214

// After

215

function greet(name = 'World', greeting = 'Hello') {

216

return greeting + ', ' + name + '!';

217

}

218

```

219

220

### Destructuring Parameters

221

222

Converts parameter patterns to destructuring syntax.

223

224

```javascript { .api }

225

// Transform name: "destruct-param"

226

```

227

228

**What it transforms:**

229

230

- Functions that access object properties to destructuring parameters

231

- Parameter object property access patterns

232

233

**Usage Example:**

234

235

```javascript

236

// Before

237

function processUser(user) {

238

var name = user.name;

239

var age = user.age;

240

var email = user.email;

241

242

console.log(name, age, email);

243

}

244

245

// After

246

function processUser({name, age, email}) {

247

console.log(name, age, email);

248

}

249

```

250

251

### Array Includes

252

253

Converts `indexOf()` usage to `includes()` method.

254

255

```javascript { .api }

256

// Transform name: "includes"

257

```

258

259

**What it transforms:**

260

261

- `array.indexOf(item) !== -1` to `array.includes(item)`

262

- `array.indexOf(item) >= 0` to `array.includes(item)`

263

- `array.indexOf(item) > -1` to `array.includes(item)`

264

- `array.indexOf(item) === -1` to `!array.includes(item)`

265

266

**Usage Example:**

267

268

```javascript

269

// Before

270

if (items.indexOf('apple') !== -1) {

271

console.log('Found apple');

272

}

273

274

if (users.indexOf(currentUser) >= 0) {

275

console.log('User exists');

276

}

277

278

// After

279

if (items.includes('apple')) {

280

console.log('Found apple');

281

}

282

283

if (users.includes(currentUser)) {

284

console.log('User exists');

285

}

286

```