You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							104 lines
						
					
					
						
							2.8 KiB
						
					
					
				
			
		
		
	
	
							104 lines
						
					
					
						
							2.8 KiB
						
					
					
				"use strict";
 | 
						|
 | 
						|
Object.defineProperty(exports, "__esModule", {
 | 
						|
  value: true
 | 
						|
});
 | 
						|
exports.annexB33FunctionsVisitor = void 0;
 | 
						|
exports.isVarScope = isVarScope;
 | 
						|
var _core = require("@babel/core");
 | 
						|
 | 
						|
const annexB33FunctionsVisitor = {
 | 
						|
  VariableDeclaration(path) {
 | 
						|
    if (isStrict(path)) return;
 | 
						|
    if (path.node.kind !== "var") return;
 | 
						|
    const varScope = path.scope.getFunctionParent() || path.scope.getProgramParent();
 | 
						|
    varScope.path.traverse(functionsToVarVisitor, {
 | 
						|
      names: Object.keys(path.getBindingIdentifiers())
 | 
						|
    });
 | 
						|
  },
 | 
						|
 | 
						|
  BlockStatement(path) {
 | 
						|
    if (isStrict(path)) return;
 | 
						|
    if (_core.types.isFunction(path.parent, {
 | 
						|
      body: path.node
 | 
						|
    })) return;
 | 
						|
    transformStatementList(path.get("body"));
 | 
						|
  },
 | 
						|
  SwitchCase(path) {
 | 
						|
    if (isStrict(path)) return;
 | 
						|
    transformStatementList(path.get("consequent"));
 | 
						|
  }
 | 
						|
};
 | 
						|
exports.annexB33FunctionsVisitor = annexB33FunctionsVisitor;
 | 
						|
function transformStatementList(paths) {
 | 
						|
  outer: for (const path of paths) {
 | 
						|
    if (!path.isFunctionDeclaration()) continue;
 | 
						|
    if (path.node.async || path.node.generator) return;
 | 
						|
    const {
 | 
						|
      scope
 | 
						|
    } = path.parentPath;
 | 
						|
    if (isVarScope(scope)) return;
 | 
						|
    const {
 | 
						|
      name
 | 
						|
    } = path.node.id;
 | 
						|
    let currScope = scope;
 | 
						|
    do {
 | 
						|
      if (currScope.parent.hasOwnBinding(name)) continue outer;
 | 
						|
      currScope = currScope.parent;
 | 
						|
    } while (!isVarScope(currScope));
 | 
						|
    maybeTransformBlockScopedFunction(path);
 | 
						|
  }
 | 
						|
}
 | 
						|
function maybeTransformBlockScopedFunction(path) {
 | 
						|
  const {
 | 
						|
    node,
 | 
						|
    parentPath: {
 | 
						|
      scope
 | 
						|
    }
 | 
						|
  } = path;
 | 
						|
  const {
 | 
						|
    id
 | 
						|
  } = node;
 | 
						|
  scope.removeOwnBinding(id.name);
 | 
						|
  node.id = null;
 | 
						|
  const varNode = _core.types.variableDeclaration("var", [_core.types.variableDeclarator(id, _core.types.toExpression(node))]);
 | 
						|
  varNode._blockHoist = 2;
 | 
						|
  const [varPath] = path.replaceWith(varNode);
 | 
						|
  scope.registerDeclaration(varPath);
 | 
						|
}
 | 
						|
const functionsToVarVisitor = {
 | 
						|
  Scope(path, {
 | 
						|
    names
 | 
						|
  }) {
 | 
						|
    for (const name of names) {
 | 
						|
      const binding = path.scope.getOwnBinding(name);
 | 
						|
      if (binding && binding.kind === "hoisted") {
 | 
						|
        maybeTransformBlockScopedFunction(binding.path);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  },
 | 
						|
  "Expression|Declaration"(path) {
 | 
						|
    path.skip();
 | 
						|
  }
 | 
						|
};
 | 
						|
function isVarScope(scope) {
 | 
						|
  return scope.path.isFunctionParent() || scope.path.isProgram();
 | 
						|
}
 | 
						|
function isStrict(path) {
 | 
						|
  return !!path.find(({
 | 
						|
    node
 | 
						|
  }) => {
 | 
						|
    var _node$directives;
 | 
						|
    if (_core.types.isProgram(node)) {
 | 
						|
      if (node.sourceType === "module") return true;
 | 
						|
    } else if (_core.types.isClass(node)) {
 | 
						|
      return true;
 | 
						|
    } else if (!_core.types.isBlockStatement(node)) {
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
    return (_node$directives = node.directives) == null ? void 0 : _node$directives.some(directive => directive.value.value === "use strict");
 | 
						|
  });
 | 
						|
}
 | 
						|
 | 
						|
//# sourceMappingURL=annex-B_3_3.js.map
 |