@@ -13159,74 +13159,24 @@ func (p *parser) visitExprInOut(expr js_ast.Expr, in exprIn) (js_ast.Expr, exprO
13159
13159
return js_ast.Expr{Loc: expr.Loc, Data: js_ast.EUndefinedShared}, exprOut{}
13160
13160
}
13161
13161
13162
- // Recognize "require.resolve()" calls
13163
- if couldBeRequireResolve {
13164
- if dot, ok := e.Target.Data.(*js_ast.EDot); ok && dot.Name == "resolve" {
13165
- if id, ok := dot.Target.Data.(*js_ast.EIdentifier); ok && id.Ref == p.requireRef {
13166
- p.ignoreUsage(p.requireRef)
13167
- return p.maybeTransposeIfExprChain(e.Args[0], func(arg js_ast.Expr) js_ast.Expr {
13168
- if str, ok := e.Args[0].Data.(*js_ast.EString); ok {
13169
- // Ignore calls to require.resolve() if the control flow is provably
13170
- // dead here. We don't want to spend time scanning the required files
13171
- // if they will never be used.
13172
- if p.isControlFlowDead {
13173
- return js_ast.Expr{Loc: arg.Loc, Data: js_ast.ENullShared}
13174
- }
13175
-
13176
- importRecordIndex := p.addImportRecord(ast.ImportRequireResolve, e.Args[0].Loc, helpers.UTF16ToString(str.Value), nil)
13177
- if p.fnOrArrowDataVisit.tryBodyCount != 0 {
13178
- record := &p.importRecords[importRecordIndex]
13179
- record.Flags |= ast.HandlesImportErrors
13180
- record.ErrorHandlerLoc = p.fnOrArrowDataVisit.tryCatchLoc
13181
- }
13182
- p.importRecordsForCurrentPart = append(p.importRecordsForCurrentPart, importRecordIndex)
13183
-
13184
- // Create a new expression to represent the operation
13185
- return js_ast.Expr{Loc: arg.Loc, Data: &js_ast.ERequireResolveString{
13186
- ImportRecordIndex: importRecordIndex,
13187
- }}
13188
- }
13189
-
13190
- // Otherwise just return a clone of the "require.resolve()" call
13191
- return js_ast.Expr{Loc: arg.Loc, Data: &js_ast.ECall{
13192
- Target: js_ast.Expr{Loc: e.Target.Loc, Data: &js_ast.EDot{
13193
- Target: p.valueToSubstituteForRequire(dot.Target.Loc),
13194
- Name: dot.Name,
13195
- NameLoc: dot.NameLoc,
13196
- }},
13197
- Args: []js_ast.Expr{arg},
13198
- }}
13199
- }), exprOut{}
13200
- }
13201
- }
13202
- }
13203
-
13204
- // Recognize "Object.create()" calls
13205
- if couldBeObjectCreate {
13206
- if dot, ok := e.Target.Data.(*js_ast.EDot); ok && dot.Name == "create" {
13207
- if id, ok := dot.Target.Data.(*js_ast.EIdentifier); ok {
13208
- if symbol := &p.symbols[id.Ref.InnerIndex]; symbol.Kind == js_ast.SymbolUnbound && symbol.OriginalName == "Object" {
13209
- switch e.Args[0].Data.(type) {
13210
- case *js_ast.ENull, *js_ast.EObject:
13211
- // Mark "Object.create(null)" and "Object.create({})" as pure
13212
- e.CanBeUnwrappedIfUnused = true
13213
- }
13214
- }
13215
- }
13216
- }
13217
- }
13218
-
13219
13162
// "foo(1, ...[2, 3], 4)" => "foo(1, 2, 3, 4)"
13220
13163
if p.options.minifySyntax && hasSpread && in.assignTarget == js_ast.AssignTargetNone {
13221
13164
e.Args = inlineSpreadsOfArrayLiterals(e.Args)
13222
13165
}
13223
13166
13224
- // Detect if this is a direct eval. Note that "(1 ? eval : 0)(x)" will
13225
- // become "eval(x)" after we visit the target due to dead code elimination,
13226
- // but that doesn't mean it should become a direct eval.
13227
- if wasIdentifierBeforeVisit {
13228
- if id, ok := e.Target.Data.(*js_ast.EIdentifier); ok {
13229
- if symbol := p.symbols[id.Ref.InnerIndex]; symbol.OriginalName == "eval" {
13167
+ switch t := target.Data.(type) {
13168
+ case *js_ast.EImportIdentifier:
13169
+ // If this function is inlined, allow it to be tree-shaken
13170
+ if p.options.minifySyntax && !p.isControlFlowDead {
13171
+ p.convertSymbolUseToCall(t.Ref, len(e.Args) == 1)
13172
+ }
13173
+
13174
+ case *js_ast.EIdentifier:
13175
+ // Detect if this is a direct eval. Note that "(1 ? eval : 0)(x)" will
13176
+ // become "eval(x)" after we visit the target due to dead code elimination,
13177
+ // but that doesn't mean it should become a direct eval.
13178
+ if wasIdentifierBeforeVisit {
13179
+ if symbol := p.symbols[t.Ref.InnerIndex]; symbol.OriginalName == "eval" {
13230
13180
e.IsDirectEval = true
13231
13181
13232
13182
// Pessimistically assume that if this looks like a CommonJS module
@@ -13259,16 +13209,7 @@ func (p *parser) visitExprInOut(expr js_ast.Expr, in exprIn) (js_ast.Expr, exprO
13259
13209
}
13260
13210
}
13261
13211
}
13262
- }
13263
-
13264
- switch t := target.Data.(type) {
13265
- case *js_ast.EImportIdentifier:
13266
- // If this function is inlined, allow it to be tree-shaken
13267
- if p.options.minifySyntax && !p.isControlFlowDead {
13268
- p.convertSymbolUseToCall(t.Ref, len(e.Args) == 1)
13269
- }
13270
13212
13271
- case *js_ast.EIdentifier:
13272
13213
// Copy the call side effect flag over if this is a known target
13273
13214
if t.CallCanBeUnwrappedIfUnused {
13274
13215
e.CanBeUnwrappedIfUnused = true
@@ -13280,6 +13221,59 @@ func (p *parser) visitExprInOut(expr js_ast.Expr, in exprIn) (js_ast.Expr, exprO
13280
13221
}
13281
13222
13282
13223
case *js_ast.EDot:
13224
+ // Recognize "require.resolve()" calls
13225
+ if couldBeRequireResolve && t.Name == "resolve" {
13226
+ if id, ok := t.Target.Data.(*js_ast.EIdentifier); ok && id.Ref == p.requireRef {
13227
+ p.ignoreUsage(p.requireRef)
13228
+ return p.maybeTransposeIfExprChain(e.Args[0], func(arg js_ast.Expr) js_ast.Expr {
13229
+ if str, ok := e.Args[0].Data.(*js_ast.EString); ok {
13230
+ // Ignore calls to require.resolve() if the control flow is provably
13231
+ // dead here. We don't want to spend time scanning the required files
13232
+ // if they will never be used.
13233
+ if p.isControlFlowDead {
13234
+ return js_ast.Expr{Loc: arg.Loc, Data: js_ast.ENullShared}
13235
+ }
13236
+
13237
+ importRecordIndex := p.addImportRecord(ast.ImportRequireResolve, e.Args[0].Loc, helpers.UTF16ToString(str.Value), nil)
13238
+ if p.fnOrArrowDataVisit.tryBodyCount != 0 {
13239
+ record := &p.importRecords[importRecordIndex]
13240
+ record.Flags |= ast.HandlesImportErrors
13241
+ record.ErrorHandlerLoc = p.fnOrArrowDataVisit.tryCatchLoc
13242
+ }
13243
+ p.importRecordsForCurrentPart = append(p.importRecordsForCurrentPart, importRecordIndex)
13244
+
13245
+ // Create a new expression to represent the operation
13246
+ return js_ast.Expr{Loc: arg.Loc, Data: &js_ast.ERequireResolveString{
13247
+ ImportRecordIndex: importRecordIndex,
13248
+ }}
13249
+ }
13250
+
13251
+ // Otherwise just return a clone of the "require.resolve()" call
13252
+ return js_ast.Expr{Loc: arg.Loc, Data: &js_ast.ECall{
13253
+ Target: js_ast.Expr{Loc: e.Target.Loc, Data: &js_ast.EDot{
13254
+ Target: p.valueToSubstituteForRequire(t.Target.Loc),
13255
+ Name: t.Name,
13256
+ NameLoc: t.NameLoc,
13257
+ }},
13258
+ Args: []js_ast.Expr{arg},
13259
+ }}
13260
+ }), exprOut{}
13261
+ }
13262
+ }
13263
+
13264
+ // Recognize "Object.create()" calls
13265
+ if couldBeObjectCreate && t.Name == "create" {
13266
+ if id, ok := t.Target.Data.(*js_ast.EIdentifier); ok {
13267
+ if symbol := &p.symbols[id.Ref.InnerIndex]; symbol.Kind == js_ast.SymbolUnbound && symbol.OriginalName == "Object" {
13268
+ switch e.Args[0].Data.(type) {
13269
+ case *js_ast.ENull, *js_ast.EObject:
13270
+ // Mark "Object.create(null)" and "Object.create({})" as pure
13271
+ e.CanBeUnwrappedIfUnused = true
13272
+ }
13273
+ }
13274
+ }
13275
+ }
13276
+
13283
13277
// Copy the call side effect flag over if this is a known target
13284
13278
if t.CallCanBeUnwrappedIfUnused {
13285
13279
e.CanBeUnwrappedIfUnused = true
0 commit comments