|
const fs = require("fs"); |
|
const jsTokens = require("js-tokens"); |
|
|
|
const projectPrefix = "$author$project$"; |
|
|
|
const code = fs.readFileSync(process.stdin.fd, "utf8"); |
|
|
|
const fields = new Map(); |
|
const usedFields = new Set(); |
|
|
|
let prevPrevPrevToken = { type: "LineTerminatorSequence", value: "\n" }; |
|
let prevPrevToken = { type: "LineTerminatorSequence", value: "\n" }; |
|
let prevToken = { type: "LineTerminatorSequence", value: "\n" }; |
|
let currentProjectFunction = undefined; |
|
|
|
for (const token of jsTokens(code)) { |
|
if ( |
|
prevPrevPrevToken.type === "LineTerminatorSequence" && |
|
prevPrevToken.value === "var" && |
|
prevToken.type === "WhiteSpace" |
|
) { |
|
if (token.value.startsWith(projectPrefix)) { |
|
currentProjectFunction = token.value |
|
.slice(projectPrefix.length) |
|
.replace(/\$/g, "."); |
|
} else { |
|
currentProjectFunction = undefined; |
|
} |
|
} else if ( |
|
currentProjectFunction !== undefined && |
|
prevPrevToken.type === "IdentifierName" && |
|
!prevPrevToken.value.startsWith("_") && |
|
prevToken.value === ":" && |
|
token.type !== "LineTerminatorSequence" |
|
) { |
|
const name = prevPrevToken.value; |
|
const previous = fields.get(name); |
|
if (previous === undefined) { |
|
fields.set(name, new Set([currentProjectFunction])); |
|
} else { |
|
previous.add(currentProjectFunction); |
|
} |
|
} else if (prevToken.value === "." && token.type === "IdentifierName") { |
|
usedFields.add(token.value); |
|
} |
|
prevPrevPrevToken = prevPrevToken; |
|
prevPrevToken = prevToken; |
|
prevToken = token; |
|
} |
|
|
|
for (const [field, functionNames] of fields) { |
|
if (!usedFields.has(field)) { |
|
console.log(`${field} in ${Array.from(functionNames).join(", ")}`); |
|
} |
|
} |