@minecraft/creator-tools
Version:
Minecraft Creator Tools command line and libraries.
169 lines (168 loc) • 6.74 kB
JavaScript
;
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ScriptInfoGeneratorTest = exports.CommonTermsSet = exports.CommonTerms = void 0;
const ProjectInfoItem_1 = __importDefault(require("./ProjectInfoItem"));
const esprima_next_1 = __importDefault(require("esprima-next"));
const ProjectInfoUtilities_1 = __importDefault(require("./ProjectInfoUtilities"));
const IProjectItemData_1 = require("../app/IProjectItemData");
const Log_1 = __importDefault(require("../core/Log"));
const IInfoItemData_1 = require("./IInfoItemData");
const Database_1 = __importDefault(require("../minecraft/Database"));
exports.CommonTerms = [
"undefined",
"type",
"name",
"error",
"equals",
"value",
"length",
"index",
"String",
"number",
"width",
"height",
"count",
"event",
"string",
"text",
"object",
];
exports.CommonTermsSet = new Set(exports.CommonTerms);
var ScriptInfoGeneratorTest;
(function (ScriptInfoGeneratorTest) {
ScriptInfoGeneratorTest[ScriptInfoGeneratorTest["apisUsed"] = 101] = "apisUsed";
})(ScriptInfoGeneratorTest || (exports.ScriptInfoGeneratorTest = ScriptInfoGeneratorTest = {}));
/**
* Analyzes and aggregates information about script API usage.
*
* @see {@link ../../public/data/forms/mctoolsval/script.form.json} for topic definitions
*/
class ScriptInfoGenerator {
id = "SCRIPT";
title = "Script";
canAlwaysProcess = true;
minecraftTokens = {};
generatedTokens = false;
async _generateTokens() {
await Database_1.default.loadStable20ScriptTypes();
const typeDefs = Database_1.default.stable20TypeDefs;
if (typeDefs) {
for (const typeDef of typeDefs.typeDefs) {
const typeDefContent = typeDef.content.join("\n");
let name = typeDef.name;
this.minecraftTokens[name] = {
typeDef: typeDef,
};
const slashIndex = name.indexOf("/");
if (slashIndex >= 0) {
this.minecraftTokens[name.substring(0, slashIndex)] = {
typeDef: typeDef,
};
this.minecraftTokens[name.substring(slashIndex + 1)] = {
typeDef: typeDef,
};
}
const tokens = this.getAllTokens(typeDefContent);
for (const tok of tokens) {
this.minecraftTokens[tok] = {
typeDef: typeDef,
};
}
}
}
}
async generate(project, contentIndex) {
const items = [];
const scriptTokensPi = new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.featureAggregate, this.id, ScriptInfoGeneratorTest.apisUsed, ProjectInfoUtilities_1.default.getTitleFromEnum(ScriptInfoGeneratorTest, ScriptInfoGeneratorTest.apisUsed));
items.push(scriptTokensPi);
if (!this.generatedTokens) {
await this._generateTokens();
}
await Database_1.default.loadStable20ScriptTypes();
const itemsCopy = project.getItemsCopy();
for (let i = 0; i < itemsCopy.length; i++) {
const pi = itemsCopy[i];
if (pi.itemType === IProjectItemData_1.ProjectItemType.js) {
if (!pi.isContentLoaded) {
await pi.loadContent();
}
if (pi.primaryFile) {
if (!pi.primaryFile.isContentLoaded) {
await pi.primaryFile.loadContent();
}
const content = pi.primaryFile.content;
if (content && typeof content === "string") {
this.parseJsContent(scriptTokensPi, content);
}
}
}
}
return items;
}
getAllTokens(content) {
const tokens = [];
const tokensSet = new Set();
try {
const results = esprima_next_1.default.tokenize(content);
if (results) {
for (const token of results) {
if ((token.type === "Identifier" || token.type === "String") && token.value && token.value.length > 3) {
let tok = token.value.trim();
if (tok.startsWith("'") && tok.endsWith("'")) {
tok = tok.substring(1, tok.length - 1);
}
else if (tok.startsWith("'") && tok.endsWith("'")) {
tok = tok.substring(1, tok.length - 1);
}
if (token.type === "Identifier" && tok !== "from" && !tokensSet.has(tok) && !exports.CommonTermsSet.has(tok)) {
tokens.push(tok);
tokensSet.add(tok);
}
else if (token.type === "String" &&
!exports.CommonTermsSet.has(tok) &&
(tok.startsWith("minecraft:") || tok.startsWith("@minecraft")) &&
!tokensSet.has(tok)) {
tokens.push(tok);
tokensSet.add(tok);
}
}
}
}
}
catch (e) {
Log_1.default.debugAlert("JS parsing error:" + e);
}
return tokens;
}
parseJsContent(scriptTokensPi, content) {
let tokens = this.getAllTokens(content);
for (const token of tokens) {
if (this.minecraftTokens[token] !== undefined) {
scriptTokensPi.incrementFeature(token);
}
}
}
summarize(info, infoSet) {
const scriptItems = infoSet.getItems(this.id, ScriptInfoGeneratorTest.apisUsed);
info.apisUsed = [];
const apisUsedSet = new Set();
for (const scriptItem of scriptItems) {
let scriptTokens = scriptItem.featureSets;
if (scriptTokens) {
for (const scriptToken in scriptTokens) {
if (!apisUsedSet.has(scriptToken) && !exports.CommonTermsSet.has(scriptToken)) {
info.apisUsed.push(scriptToken);
apisUsedSet.add(scriptToken);
}
}
}
}
info.apisUsed.sort();
}
}
exports.default = ScriptInfoGenerator;