// Copyright (c) 2018, Compiler Explorer Authors // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // * Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. export class ClientStateCompilerOptions { constructor(jsondata) { this.binary = false; this.commentOnly = true; this.demangle = true; this.directives = true; this.execute = false; this.intel = true; this.labels = true; this.trim = false; if (jsondata) this.fromJsonData(jsondata); } fromJsonData(jsondata) { if (typeof jsondata.binary !== 'undefined') this.binary = jsondata.binary; if (typeof jsondata.commentOnly !== 'undefined') this.commentOnly = jsondata.commentOnly; if (typeof jsondata.demangle !== 'undefined') this.demangle = jsondata.demangle; if (typeof jsondata.directives !== 'undefined') this.directives = jsondata.directives; if (typeof jsondata.execute !== 'undefined') this.execute = jsondata.execute; if (typeof jsondata.intel !== 'undefined') this.intel = jsondata.intel; if (typeof jsondata.labels !== 'undefined') this.labels = jsondata.labels; if (typeof jsondata.trim !== 'undefined') this.trim = jsondata.trim; } } export class ClientStateCompiler { constructor(jsondata) { this._internalid = undefined; if (jsondata) { this.fromJsonData(jsondata); } else { this.id = ''; this.options = ''; this.filters = new ClientStateCompilerOptions(); this.libs = []; this.specialoutputs = []; this.tools = []; } } fromJsonData(jsondata) { if (typeof jsondata._internalid !== undefined) { this._internalid = jsondata._internalid; } if (typeof jsondata.id !== 'undefined') { this.id = jsondata.id; } else if (typeof jsondata.compilerId !== 'undefined') { this.id = jsondata.compilerId; } else { this.id = ''; } this.options = jsondata.options; this.filters = new ClientStateCompilerOptions(jsondata.filters); if (typeof jsondata.libs !== 'undefined') { this.libs = jsondata.libs; } else { this.libs = []; } if (typeof jsondata.specialoutputs !== 'undefined') { this.specialoutputs = jsondata.specialoutputs; } else { this.specialoutputs = []; } if (typeof jsondata.tools !== 'undefined') { this.tools = jsondata.tools; } else { this.tools = []; } } } export class ClientStateExecutor { constructor(jsondata) { this.compilerVisible = false; this.compilerOutputVisible = false; this.arguments = []; this.argumentsVisible = false; this.stdin = ''; this.stdinVisible = false; if (jsondata) { this.fromJsonData(jsondata); } else { this.compiler = new ClientStateCompiler(); this.wrap = false; } delete this.compiler._internalid; } fromJsonData(jsondata) { if (typeof jsondata.compilerVisible !== 'undefined') this.compilerVisible = jsondata.compilerVisible; if (typeof jsondata.compilerOutputVisible !== 'undefined') this.compilerOutputVisible = jsondata.compilerOutputVisible; if (typeof jsondata.arguments !== 'undefined') this.arguments = jsondata.arguments; if (typeof jsondata.argumentsVisible !== 'undefined') this.argumentsVisible = jsondata.argumentsVisible; if (typeof jsondata.stdin !== 'undefined') this.stdin = jsondata.stdin; if (typeof jsondata.stdinVisible !== 'undefined') this.stdinVisible = jsondata.stdinVisible; if (typeof jsondata.wrap !== 'undefined') this.wrap = jsondata.wrap; this.compiler = new ClientStateCompiler(jsondata.compiler); } } export class ClientStateConformanceView { constructor(jsondata) { this.libs = []; this.compilers = []; if (jsondata) this.fromJsonData(jsondata); } fromJsonData(jsondata) { this.libs = jsondata.libs; if (jsondata.compilers) { for (const compilerdata of jsondata.compilers) { const compiler = new ClientStateCompiler(compilerdata); delete compiler._internalid; this.compilers.push(compiler); } } } } export class MultifileFile { constructor(jsondata) { this.fileId = 0; this.isIncluded = false; this.isOpen = false; this.isMainSource = false; this.filename = ''; this.content = ''; this.editorId = -1; this.langId = 'c++'; if (jsondata) this.fromJsonData(jsondata); } fromJsonData(jsondata) { this.fileId = jsondata.fileId; this.isIncluded = jsondata.isIncluded; this.isOpen = jsondata.isOpen; this.isMainSource = jsondata.isMainSource; this.filename = jsondata.filename; this.content = jsondata.content; this.editorId = jsondata.editorId; this.langId = jsondata.langId; } } export class ClientStateTree { constructor(jsondata) { this.id = 1; this.cmakeArgs = ''; this.customOutputFilename = ''; this.isCMakeProject = false; this.compilerLanguageId = 'c++'; this.files = []; this.newFileId = 1; this.compilers = []; this.executors = []; if (jsondata) this.fromJsonData(jsondata); } fromJsonData(jsondata) { this.id = jsondata.id; this.cmakeArgs = jsondata.cmakeArgs; this.customOutputFilename = jsondata.customOutputFilename; this.isCMakeProject = jsondata.isCMakeProject; this.compilerLanguageId = jsondata.compilerLanguageId; let requiresFix = typeof jsondata.newFileId === 'undefined'; for (const file of jsondata.files) { const newFile = new MultifileFile(file); this.files.push(newFile); if (this.newFileId <= newFile.id) { requiresFix = true; } } if (requiresFix) { this.newFileId = 1; for (const file of this.files) { if (file.id > this.newFileId) { this.newFileId = file.id + 1; } } } else { this.newFileId = jsondata.newFileId; } if (typeof jsondata.compilers !== 'undefined') { for (const compilerdata of jsondata.compilers) { const compiler = new ClientStateCompiler(compilerdata); if (compiler.id) { this.compilers.push(compiler); } } } if (typeof jsondata.executors !== 'undefined') { for (const executor of jsondata.executors) { this.executors.push(new ClientStateExecutor(executor)); } } } findOrCreateCompiler(id) { let foundCompiler; for (let compiler of this.compilers) { if (compiler._internalid === id) { foundCompiler = compiler; } } if (!foundCompiler) { foundCompiler = new ClientStateCompiler(); foundCompiler._internalid = id; this.compilers.push(foundCompiler); } return foundCompiler; } } export class ClientStateSession { constructor(jsondata) { this.id = false; this.language = ''; this.source = ''; this.conformanceview = false; this.compilers = []; this.executors = []; this.filename = undefined; if (jsondata) this.fromJsonData(jsondata); } fromJsonData(jsondata) { if (typeof jsondata.id !== 'undefined') this.id = jsondata.id; this.language = jsondata.language; this.source = jsondata.source; if (typeof jsondata.conformanceview !== 'undefined') { if (jsondata.conformanceview) { this.conformanceview = new ClientStateConformanceView(jsondata.conformanceview); } else { this.conformanceview = false; } } for (const compilerdata of jsondata.compilers) { const compiler = new ClientStateCompiler(compilerdata); if (compiler.id) { this.compilers.push(compiler); } } if (typeof jsondata.executors !== 'undefined') { for (const executor of jsondata.executors) { this.executors.push(new ClientStateExecutor(executor)); } } if (typeof jsondata.filename !== 'undefined') { this.filename = jsondata.filename; } } findOrCreateCompiler(id) { let foundCompiler; for (let compiler of this.compilers) { if (compiler._internalid === id) { foundCompiler = compiler; } } if (!foundCompiler) { foundCompiler = new ClientStateCompiler(); foundCompiler._internalid = id; this.compilers.push(foundCompiler); } return foundCompiler; } countNumberOfSpecialOutputsAndTools() { let count = 0; if (this.conformanceview) count++; for (const compiler of this.compilers) { count += compiler.specialoutputs.length; if (compiler.tools) count += compiler.tools.length; } return count; } } export class ClientState { constructor(jsondata) { this.sessions = []; this.trees = []; if (jsondata) this.fromJsonData(jsondata); } fromJsonData(jsondata) { for (const sessiondata of jsondata.sessions) { const session = new ClientStateSession(sessiondata); this.numberCompilersIfNeeded(session); this.sessions.push(session); } if (jsondata.trees) { for (const treedata of jsondata.trees) { this.trees.push(new ClientStateTree(treedata)); } } } getNextCompilerId() { let nextId = 1; for (const session of this.sessions) { for (const compiler of session.compilers) { if (compiler._internalid && compiler._internalid >= nextId) { nextId = compiler._internalid + 1; } } } return nextId; } numberCompilersIfNeeded(session, startAt) { let id = startAt; let someIdsNeedNumbering = false; for (const compiler of session.compilers) { if (compiler._internalid) { if (compiler._internalid >= id) { id = compiler._internalid + 1; } } else { someIdsNeedNumbering = true; } } if (someIdsNeedNumbering) { for (const compiler of session.compilers) { if (!compiler._internalid) { compiler._internalid = id; id++; } } } } findSessionById(id) { for (const session of this.sessions) { if (session.id === id) { return session; } } return false; } findTreeById(id) { let tree = null; for (let idxTree = 0; idxTree < this.trees.length; idxTree++) { tree = this.trees[idxTree]; if (tree.id === id) { return tree; } } return false; } findOrCreateSession(id) { let session = this.findSessionById(id); if (session) return session; session = new ClientStateSession(); session.id = id; this.sessions.push(session); return session; } findOrCreateTree(id) { let tree = this.findTreeById(id); if (tree) return tree; tree = new ClientStateTree(); tree.id = id; this.trees.push(tree); return tree; } }