Files
codeql-action/node_modules/ts-poet/build/Code.js
Angela P Wen a196a714b8 Bump artifact dependencies if CODEQL_ACTION_ARTIFACT_V2_UPGRADE enabled (#2482)
Co-authored-by: Andrew Eisenberg <aeisenberg@github.com>
Co-authored-by: Henry Mercer <henrymercer@github.com>
2024-10-01 09:59:05 -07:00

306 lines
12 KiB
JavaScript

"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Def = exports.deepGenerate = exports.Code = void 0;
const Node_1 = require("./Node");
const Import_1 = require("./Import");
const prettier_1 = __importStar(require("prettier"));
const parser_typescript_1 = __importDefault(require("prettier/parser-typescript"));
const is_plain_object_1 = require("./is-plain-object");
const ConditionalOutput_1 = require("./ConditionalOutput");
const index_1 = require("./index");
// We only have a single top-level Code.toStringWithImports running at a time,
// so use a global var to capture this contextual state.
let usedConditionals = [];
class Code extends Node_1.Node {
constructor(literals, placeholders) {
super();
this.literals = literals;
this.placeholders = placeholders;
// Used by joinCode
this.trim = false;
this.oneline = false;
}
/**
* Returns the code with any necessary import statements prefixed.
*
* This method will also use any local `.prettierrc` settings, hence needs
* to return a `Promise<String>`.
*/
toStringWithImports(opts) {
const { path = '', forceDefaultImport, forceModuleImport, prefix, prettierOverrides = {}, importMappings = {} } = opts || {};
const ourModulePath = path.replace(/\.[tj]sx?/, '');
if (forceDefaultImport || forceModuleImport) {
this.deepReplaceNamedImports(forceDefaultImport || [], forceModuleImport || []);
}
usedConditionals = this.deepConditionalOutput();
const imports = this.deepFindImports();
const defs = this.deepFindDefs();
assignAliasesIfNeeded(defs, imports, ourModulePath);
const importPart = Import_1.emitImports(imports, ourModulePath, importMappings);
const bodyPart = this.generateCode();
const maybePrefix = prefix ? `${prefix}\n` : '';
return maybePrettyWithConfig(maybePrefix + importPart + '\n' + bodyPart, prettierOverrides);
}
/**
* Returns the formatted code, without any imports.
*
* Note that we don't use `.prettierrc` b/c that requires async I/O to resolve.
*/
toString() {
return maybePretty(this.generateCode());
}
asOneline() {
this.oneline = true;
return this;
}
get childNodes() {
return this.placeholders;
}
toCodeString() {
return this.generateCode();
}
deepFindImports() {
const imports = [];
let todo = [this];
while (todo.length > 0) {
const placeholder = todo.shift();
if (placeholder instanceof Import_1.Import) {
imports.push(placeholder);
}
else if (placeholder instanceof Node_1.Node) {
todo = [...todo, ...placeholder.childNodes];
}
else if (placeholder instanceof ConditionalOutput_1.MaybeOutput) {
if (usedConditionals.includes(placeholder.parent)) {
todo = [...todo, placeholder.code];
}
}
else if (Array.isArray(placeholder)) {
todo = [...todo, ...placeholder];
}
}
return imports;
}
deepFindDefs() {
const defs = [];
let todo = [this];
while (todo.length > 0) {
const placeholder = todo.shift();
if (placeholder instanceof Def) {
defs.push(placeholder);
}
else if (placeholder instanceof Node_1.Node) {
todo = [...todo, ...placeholder.childNodes];
}
else if (placeholder instanceof ConditionalOutput_1.MaybeOutput) {
if (usedConditionals.includes(placeholder.parent)) {
todo = [...todo, placeholder.code];
}
}
else if (Array.isArray(placeholder)) {
todo = [...todo, ...placeholder];
}
}
return defs;
}
deepConditionalOutput() {
const used = [];
let todo = [this];
while (todo.length > 0) {
const placeholder = todo.shift();
if (placeholder instanceof ConditionalOutput_1.ConditionalOutput) {
used.push(placeholder);
todo = [...todo, ...placeholder.declarationSiteCode.childNodes];
}
else if (placeholder instanceof Node_1.Node) {
todo = [...todo, ...placeholder.childNodes];
}
else if (Array.isArray(placeholder)) {
todo = [...todo, ...placeholder];
}
}
return used;
}
deepReplaceNamedImports(forceDefaultImport, forceModuleImport) {
// Keep a map of module name --> symbol we're importing, i.e. protobufjs/simple is _m1
const assignedNames = {};
function getName(source) {
let name = assignedNames[source];
if (!name) {
name = `_m${Object.values(assignedNames).length}`;
assignedNames[source] = name;
}
return name;
}
let todo = [this];
while (todo.length > 0) {
const placeholder = todo.shift();
if (placeholder instanceof Node_1.Node) {
const array = placeholder.childNodes;
for (let i = 0; i < array.length; i++) {
const maybeImp = array[i];
if (maybeImp instanceof Import_1.ImportsName && forceDefaultImport.includes(maybeImp.source)) {
const name = getName(maybeImp.source);
array[i] = index_1.code `${new Import_1.ImportsDefault(name, maybeImp.source)}.${maybeImp.sourceSymbol || maybeImp.symbol}`;
}
else if (maybeImp instanceof Import_1.ImportsName && forceModuleImport.includes(maybeImp.source)) {
const name = getName(maybeImp.source);
array[i] = index_1.code `${new Import_1.ImportsAll(name, maybeImp.source)}.${maybeImp.sourceSymbol || maybeImp.symbol}`;
}
}
todo = [...todo, ...placeholder.childNodes];
}
else if (Array.isArray(placeholder)) {
todo = [...todo, ...placeholder];
}
}
}
generateCode() {
const { literals, placeholders } = this;
let result = '';
// interleave the literals with the placeholders
for (let i = 0; i < placeholders.length; i++) {
result += literals[i] + deepGenerate(placeholders[i]);
}
// add the last literal
result += literals[literals.length - 1];
if (this.trim) {
result = result.trim();
}
if (this.oneline) {
result = result.replace(/\n/g, '');
}
return result;
}
}
exports.Code = Code;
function deepGenerate(object) {
let result = '';
let todo = [object];
while (todo.length > 0) {
const current = todo.shift();
if (Array.isArray(current)) {
todo = [...todo, ...current];
}
else if (current instanceof Node_1.Node) {
result += current.toCodeString();
}
else if (current instanceof ConditionalOutput_1.MaybeOutput) {
if (usedConditionals.includes(current.parent)) {
result += current.code.toCodeString();
}
}
else if (current === null) {
result += 'null';
}
else if (current !== undefined) {
if (is_plain_object_1.isPlainObject(current)) {
result += JSON.stringify(current);
}
else {
result += current.toString();
}
}
else {
result += 'undefined';
}
}
return result;
}
exports.deepGenerate = deepGenerate;
// Use an optional call here in case we are using standalone prettier. This can happen when loaded through a CDN from
// a browser (or Deno), because prettier has `"browser": "./standalone.js"` in it's package.json.
const configPromise = prettier_1.resolveConfig === null || prettier_1.resolveConfig === void 0 ? void 0 : prettier_1.resolveConfig('./');
async function maybePrettyWithConfig(input, options) {
try {
const config = await configPromise;
return prettier_1.default.format(input.trim(), { parser: 'typescript', plugins: [parser_typescript_1.default], ...config, ...options });
}
catch (e) {
return input; // assume it's invalid syntax and ignore
}
}
/** Finds any namespace collisions of a named import colliding with def and assigns the import an alias it. */
function assignAliasesIfNeeded(defs, imports, ourModulePath) {
// Keep track of used (whether declared or imported) symbols
const usedSymbols = new Set();
// Mark all locally-defined symbols as used
defs.forEach((def) => usedSymbols.add(def.symbol));
// A mapping of original to assigned alias, i.e. Foo@foo --> Foo2
const assignedAliases = {};
let j = 1;
imports.forEach((i) => {
if (i instanceof Import_1.ImportsName &&
// Don't both aliasing imports from our own module
!(Import_1.sameModule(i.source, ourModulePath) || (i.definedIn && Import_1.sameModule(i.definedIn, ourModulePath)))) {
const key = `${i.symbol}@${i.source}`;
if (usedSymbols.has(i.symbol)) {
let alias = assignedAliases[key];
if (!alias) {
alias = `${i.symbol}${j++}`;
assignedAliases[key] = alias;
}
// Move the original symbol over
if (alias !== i.symbol) {
i.sourceSymbol = i.symbol;
}
i.symbol = alias;
}
else {
usedSymbols.add(i.symbol);
assignedAliases[key] = i.symbol;
}
}
});
}
function maybePretty(input) {
try {
return prettier_1.default.format(input.trim(), { parser: 'typescript', plugins: [parser_typescript_1.default] });
}
catch (e) {
return input; // assume it's invalid syntax and ignore
}
}
/**
* Represents a symbol defined in the current file.
*
* We use this to know if a symbol imported from a different file is going to
* have a namespace collision.
*/
class Def extends Node_1.Node {
constructor(symbol) {
super();
this.symbol = symbol;
}
toCodeString() {
return this.symbol;
}
/** Any potentially string/SymbolSpec/Code nested nodes within us. */
get childNodes() {
return [];
}
}
exports.Def = Def;