UNPKG

@syntest/analysis-javascript

Version:

SynTest CFG JavaScript is a library for generating control flow graphs for the JavaScript language

203 lines 8.8 kB
"use strict"; /* * Copyright 2020-2023 Delft University of Technology and SynTest contributors * * This file is part of SynTest Framework - SynTest Javascript. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.RootContext = void 0; const node_fs_1 = require("node:fs"); const analysis_1 = require("@syntest/analysis"); const logging_1 = require("@syntest/logging"); const ConstantPool_1 = require("./constant/ConstantPool"); const ConstantPoolManager_1 = require("./constant/ConstantPoolManager"); const TypePool_1 = require("./type/resolving/TypePool"); const fileSystem_1 = require("./utils/fileSystem"); class RootContext extends analysis_1.RootContext { constructor(rootPath, targetFiles, analysisFiles, abstractSyntaxTreeFactory, controlFlowGraphFactory, targetFactory, dependencyFactory, exportFactory, typeExtractor, typeResolver, constantPoolFactory) { super(rootPath, undefined, abstractSyntaxTreeFactory, controlFlowGraphFactory, targetFactory, dependencyFactory); RootContext.LOGGER = (0, logging_1.getLogger)("RootContext"); this._targetFiles = targetFiles; this._analysisFiles = analysisFiles; this._exportFactory = exportFactory; this._typeExtractor = typeExtractor; this._typeResolver = typeResolver; this._constantPoolFactory = constantPoolFactory; } get rootPath() { return this._rootPath; } getSource(filePath) { let absoluteTargetPath = this.resolvePath(filePath); if (!this._sources.has(absoluteTargetPath)) { if (!(0, node_fs_1.existsSync)(absoluteTargetPath)) { if ((0, node_fs_1.existsSync)(absoluteTargetPath + ".js")) { absoluteTargetPath += ".js"; } else if ((0, node_fs_1.existsSync)(absoluteTargetPath + ".ts")) { absoluteTargetPath += ".ts"; } else { throw new Error("Cannot find source: " + absoluteTargetPath); } } const stats = (0, node_fs_1.lstatSync)(absoluteTargetPath); if (stats.isDirectory()) { if ((0, node_fs_1.existsSync)(absoluteTargetPath + "/index.js")) { absoluteTargetPath += "/index.js"; } else if ((0, node_fs_1.existsSync)(absoluteTargetPath + "/index.ts")) { absoluteTargetPath += "/index.ts"; } else { throw new Error("Cannot find source: " + absoluteTargetPath); } } this._sources.set(absoluteTargetPath, (0, fileSystem_1.readFile)(absoluteTargetPath)); } return this._sources.get(absoluteTargetPath); } getExports(filePath) { const absolutePath = this.resolvePath(filePath); if (!this._exportMap.has(absolutePath)) { process.emit("exportExtractionStart", this, absolutePath); this._exportMap.set(absolutePath, this._exportFactory.extract(absolutePath, this.getAbstractSyntaxTree(absolutePath))); process.emit("exportExtractionComplete", this, absolutePath); } return this._exportMap.get(absolutePath); } getAllExports() { if (!this._exportMap) { this._exportMap = new Map(); for (const filepath of this._analysisFiles) { this._exportMap.set(filepath, this.getExports(filepath)); } } return this._exportMap; } getElements(filepath) { const absolutePath = this.resolvePath(filepath); if (!this._elementMap.has(absolutePath)) { process.emit("elementExtractionStart", this, absolutePath); const elementMap = this._typeExtractor.extractElements(absolutePath, this.getAbstractSyntaxTree(absolutePath)); this._elementMap.set(absolutePath, elementMap); process.emit("elementExtractionComplete", this, absolutePath); } return this._elementMap.get(absolutePath); } getAllElements() { if (!this._elementMap) { this._elementMap = new Map(); for (const filepath of this._analysisFiles) { this._elementMap.set(filepath, this.getElements(filepath)); } } return this._elementMap; } getRelations(filepath) { const absolutePath = this.resolvePath(filepath); if (!this._relationMap.has(absolutePath)) { process.emit("relationExtractionStart", this, absolutePath); const relationsMap = this._typeExtractor.extractRelations(absolutePath, this.getAbstractSyntaxTree(absolutePath)); this._relationMap.set(absolutePath, relationsMap); process.emit("relationExtractionComplete", this, absolutePath); } return this._relationMap.get(absolutePath); } getAllRelations() { if (!this._relationMap) { this._relationMap = new Map(); for (const filepath of this._analysisFiles) { this._relationMap.set(filepath, this.getRelations(filepath)); } } return this._relationMap; } getObjectTypes(filepath) { const absolutePath = this.resolvePath(filepath); if (!this._objectMap.has(absolutePath)) { process.emit("objectTypeExtractionStart", this, absolutePath); const objectsMap = this._typeExtractor.extractObjectTypes(absolutePath, this.getAbstractSyntaxTree(absolutePath)); this._objectMap.set(absolutePath, objectsMap); process.emit("objectTypeExtractionComplete", this, absolutePath); } return this._objectMap.get(absolutePath); } getAllObjectTypes() { if (!this._objectMap) { this._objectMap = new Map(); for (const filepath of this._analysisFiles) { this._objectMap.set(filepath, this.getObjectTypes(filepath)); } } return this._objectMap; } resolveTypes() { // TODO allow sub selections of files (do not consider entire context) if (!this._elementMap) { this.getAllElements(); } if (!this._relationMap) { this.getAllRelations(); } if (!this._objectMap) { this.getAllObjectTypes(); } if (!this._exportMap) { this.getAllExports(); } if (!this._typeModel) { process.emit("typeResolvingStart", this); this._typeModel = this._typeResolver.resolveTypes(this._elementMap, this._relationMap); this._typePool = new TypePool_1.TypePool(this._objectMap, this._exportMap); process.emit("typeResolvingComplete", this); } } getTypeModel() { if (!this._typeModel) { this.resolveTypes(); } return this._typeModel; } getTypePool() { if (!this._typePool) { this.resolveTypes(); } return this._typePool; } // TODO cache _getContextConstantPool() { const constantPool = new ConstantPool_1.ConstantPool(); for (const filepath of this._analysisFiles) { const ast = this.getAbstractSyntaxTree(filepath); this._constantPoolFactory.extract(filepath, ast, constantPool); } return constantPool; } // TODO cache getConstantPoolManager(filepath) { const absolutePath = this.resolvePath(filepath); RootContext.LOGGER.info("Extracting constants"); const ast = this.getAbstractSyntaxTree(absolutePath); const targetConstantPool = this._constantPoolFactory.extract(absolutePath, ast); const contextConstantPool = this._getContextConstantPool(); const dynamicConstantPool = new ConstantPool_1.ConstantPool(); const constantPoolManager = new ConstantPoolManager_1.ConstantPoolManager(targetConstantPool, contextConstantPool, dynamicConstantPool); RootContext.LOGGER.info("Extracting constants done"); return constantPoolManager; } } exports.RootContext = RootContext; //# sourceMappingURL=RootContext.js.map