UNPKG

plaxtony

Version:

Static code analysis of SC2 Galaxy Script

198 lines 7.35 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.unbindSourceFile = exports.bindSourceFile = exports.declareSymbol = exports.getDeclarationName = void 0; const utils_1 = require("./utils"); // import { SignatureMeta, TypeChecker } from './checker'; function getDeclarationName(node) { switch (node.kind) { case 127 /* SourceFile */: { return node.fileName; break; } case 141 /* VariableDeclaration */: case 142 /* FunctionDeclaration */: case 140 /* StructDeclaration */: case 143 /* ParameterDeclaration */: case 144 /* PropertyDeclaration */: case 145 /* TypedefDeclaration */: { return node.name.name; break; } case 120 /* PropertyAccessExpression */: { return '__prop__' + node.name.name; break; } case 121 /* CallExpression */: { const call = node; if (call.expression.kind === 113 /* Identifier */) { return call.expression.name; } else { // TODO: properly named call expressions such as: st.member_fns[12](); return '__()'; } break; } } } exports.getDeclarationName = getDeclarationName; function isDeclNodeDefined(node) { if ((node.kind === 142 /* FunctionDeclaration */ && node.body) || (node.kind === 141 /* VariableDeclaration */ && node.initializer)) { return true; } return false; } // function createSymbolTable(symbols?: ReadonlyArray<Symbol>): SymbolTable { // const result = new Map<string, Symbol>() as SymbolTable; // if (symbols) { // for (const symbol of symbols) { // result.set(symbol.escapedName, symbol); // } // } // return result; // } function declareSymbol(node, store, parentSymbol) { let scopedSymbolTable; let nodeSymbol; let name; name = getDeclarationName(node); if (!name) { name = '__anonymous'; } if (parentSymbol && parentSymbol.members.has(name)) { nodeSymbol = parentSymbol.members.get(name); } else { let isStatic = false; if (node.modifiers) { isStatic = node.modifiers.some((value) => value.kind === 52 /* StaticKeyword */); } if (parentSymbol && !isStatic && parentSymbol.declarations[0].kind === 127 /* SourceFile */) { nodeSymbol = store.resolveGlobalSymbol(name); } if (!nodeSymbol) { nodeSymbol = { escapedName: name, declarations: [], valueDeclaration: undefined, isAssigned: false, isReferenced: false, members: new Map(), parent: parentSymbol, }; switch (node.kind) { case 143 /* ParameterDeclaration */: nodeSymbol.flags = 4 /* FunctionParameter */; break; case 141 /* VariableDeclaration */: nodeSymbol.flags = ((parentSymbol && parentSymbol.declarations[0].kind === 127 /* SourceFile */) ? 8 /* GlobalVariable */ : 2 /* LocalVariable */); break; case 142 /* FunctionDeclaration */: nodeSymbol.flags = 32 /* Function */; break; case 140 /* StructDeclaration */: nodeSymbol.flags = 64 /* Struct */; break; case 144 /* PropertyDeclaration */: nodeSymbol.flags = 16 /* Property */; break; case 145 /* TypedefDeclaration */: nodeSymbol.flags = 128 /* Typedef */; break; } switch (node.kind) { case 141 /* VariableDeclaration */: case 142 /* FunctionDeclaration */: { if (isStatic) { nodeSymbol.flags |= 1024 /* Static */; } if (node.modifiers.some((value) => value.kind === 54 /* NativeKeyword */)) { nodeSymbol.flags |= 2048 /* Native */; } break; } } } if (parentSymbol) { parentSymbol.members.set(name, nodeSymbol); } } node.symbol = nodeSymbol; nodeSymbol.declarations.push(node); if (!node.symbol.valueDeclaration && isDeclNodeDefined(node)) { nodeSymbol.valueDeclaration = node; } return nodeSymbol; } exports.declareSymbol = declareSymbol; function bindSourceFile(sourceFile, store) { let currentScope; let currentContainer; bind(sourceFile); function bind(node) { let parentScope = currentScope; let parentContainer = currentContainer; if (utils_1.isDeclarationKind(node.kind)) { switch (node.kind) { case 127 /* SourceFile */: { declareSymbol(node, store, null); break; } default: { declareSymbol(node, store, currentContainer.symbol); break; } } } // if (node.kind === SyntaxKind.SourceFile || node.kind === SyntaxKind.FunctionDeclaration || node.kind === SyntaxKind.StructDeclaration) { if (utils_1.isContainerKind(node.kind)) { currentContainer = node; } if (utils_1.isDeclarationKind(node.kind)) { currentScope = node; } utils_1.forEachChild(node, child => bind(child)); currentScope = parentScope; currentContainer = parentContainer; } } exports.bindSourceFile = bindSourceFile; function unbindSourceFile(sourceFile, store) { function unbindSymbol(parentSymbol) { for (const symbol of parentSymbol.members.values()) { symbol.declarations = symbol.declarations.filter((decl) => { return utils_1.getSourceFileOfNode(decl) !== sourceFile; }); if (!symbol.declarations.find(x => x === symbol.valueDeclaration) && utils_1.getSourceFileOfNode(symbol.valueDeclaration) === sourceFile) { delete symbol.valueDeclaration; } if (symbol.declarations.length) { unbindSymbol(symbol); if (!symbol.valueDeclaration) { for (const childDecl of symbol.declarations) { if (!isDeclNodeDefined(childDecl)) continue; symbol.valueDeclaration = childDecl; break; } } } else { parentSymbol.members.delete(symbol.escapedName); } } } unbindSymbol(sourceFile.symbol); } exports.unbindSourceFile = unbindSourceFile; //# sourceMappingURL=binder.js.map