@yuebai008/cli
Version:
Command line interface for rapid qg-minigame development
1 lines • 3.74 kB
JavaScript
import*as Bindings from"../../models/bindings/bindings.js";import*as Platform from"../../core/platform/platform.js";import*as TextUtils from"../../models/text_utils/text_utils.js";import*as Workspace from"../../models/workspace/workspace.js";export const decoratorType="coverage";export class CoverageDecorationManager{coverageModel;textByProvider;uiSourceCodeByContentProvider;constructor(e){this.coverageModel=e,this.textByProvider=new Map,this.uiSourceCodeByContentProvider=new Platform.MapUtilities.Multimap;for(const e of Workspace.Workspace.WorkspaceImpl.instance().uiSourceCodes())e.setDecorationData("coverage",this);Workspace.Workspace.WorkspaceImpl.instance().addEventListener(Workspace.Workspace.Events.UISourceCodeAdded,this.onUISourceCodeAdded,this)}reset(){for(const e of Workspace.Workspace.WorkspaceImpl.instance().uiSourceCodes())e.setDecorationData("coverage",void 0)}dispose(){this.reset(),Workspace.Workspace.WorkspaceImpl.instance().removeEventListener(Workspace.Workspace.Events.UISourceCodeAdded,this.onUISourceCodeAdded,this)}update(e){for(const o of e)for(const e of this.uiSourceCodeByContentProvider.get(o.getContentProvider()))e.setDecorationData("coverage",this)}async usageByLine(e){const o=[],{content:t}=await e.requestContent();if(!t)return[];const n=new TextUtils.Text.Text(t);await this.updateTexts(e,n);const r=n.lineEndings();for(let t=0;t<n.lineCount();++t){const n=r[t]-(t?r[t-1]:0)-1;if(!n){o.push(void 0);continue}const i=this.rawLocationsForSourceLocation(e,t,0),s=this.rawLocationsForSourceLocation(e,t,n),[c,a]=await Promise.all([i,s]);let d;for(let e=0,o=0;e<c.length;++e){const t=c[e];for(;o<a.length&&CoverageDecorationManager.compareLocations(t,a[o])>=0;)++o;if(o>=a.length||a[o].id!==t.id)continue;const n=a[o++],r=this.textByProvider.get(n.contentProvider);if(!r)continue;const i=r.value();let s=Math.min(r.offsetFromPosition(t.line,t.column),i.length-1),u=Math.min(r.offsetFromPosition(n.line,n.column),i.length-1);for(;s<=u&&/\s/.test(i[s]);)++s;for(;s<=u&&/\s/.test(i[u]);)--u;if(s<=u&&(d=this.coverageModel.usageForRange(n.contentProvider,s,u)),d)break}o.push(d)}return o}async updateTexts(e,o){const t=[];for(let n=0;n<o.lineCount();++n)for(const o of await this.rawLocationsForSourceLocation(e,n,0))this.textByProvider.has(o.contentProvider)||(this.textByProvider.set(o.contentProvider,null),this.uiSourceCodeByContentProvider.set(o.contentProvider,e),t.push(this.updateTextForProvider(o.contentProvider)));await Promise.all(t)}async updateTextForProvider(e){const{content:o}=await e.requestContent();this.textByProvider.set(e,new TextUtils.Text.Text(o||""))}async rawLocationsForSourceLocation(e,o,t){const n=[],r=e.contentType();if(r.hasScripts()){let i=await Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance().uiLocationToRawLocations(e,o,t);i=i.filter((e=>Boolean(e.script())));for(const e of i){const o=e.script();o&&(o.isInlineScript()&&r.isDocument()&&(e.lineNumber-=o.lineOffset,e.lineNumber||(e.columnNumber-=o.columnOffset)),n.push({id:`js:${e.scriptId}`,contentProvider:o,line:e.lineNumber,column:e.columnNumber}))}}if(r.isStyleSheet()||r.isDocument()){const i=Bindings.CSSWorkspaceBinding.CSSWorkspaceBinding.instance().uiLocationToRawLocations(new Workspace.UISourceCode.UILocation(e,o,t));for(const e of i){const o=e.header();o&&(o.isInline&&r.isDocument()&&(e.lineNumber-=o.startLine,e.lineNumber||(e.columnNumber-=o.startColumn)),n.push({id:`css:${e.styleSheetId}`,contentProvider:o,line:e.lineNumber,column:e.columnNumber}))}}return n.sort(CoverageDecorationManager.compareLocations)}static compareLocations(e,o){return e.id.localeCompare(o.id)||e.line-o.line||e.column-o.column}onUISourceCodeAdded(e){e.data.setDecorationData("coverage",this)}}