removing crowed source run, crashes, coverage, profiling and associated debugger analysis

This commit is contained in:
Peli de Halleux 2015-02-24 16:53:18 -08:00
Родитель 94db69c47c
Коммит 6a5c6f4a35
9 изменённых файлов: 13 добавлений и 1840 удалений

Просмотреть файл

@ -153,24 +153,6 @@ module TDev {
data: string; // groupid for group invitation codes
}
export interface JsonStoreApp
{
kind: string; // 'storeapp'
time: number; // seconds since 1970 of last activity on this app (most likely: increase of users / launches)
url:string;
scriptid: string;
storeid: string;
title: string;
publisher: string;
iconurl: string;
languages: string[];
users: number;
launches: number;
userid: string; // creator of scriptid
username: string;
userscore: number;
userhaspicture: boolean;
}
export interface JsonScript extends JsonPublication
{
@ -230,37 +212,6 @@ module TDev {
publicationkind:string; //
}
export interface JsonRunBucket extends JsonPubOnPub {
compilerversion: string; // the version of the compiler
publicationid: string; // script id
publicationname: string; // script name
publicationkind: string; // should be "script"
hash: string; // the hash of the bucket (probably not interesting to anyone)
runs: number; // the "weight" of the bucket #1, the total number of runs bound to it
cumulativeruns: number; // the "weight" of the bucket #2, the total number of encounters
error: string; // the error message
}
export interface JsonStackFrame {
id: string; // the id of the ast node
action: string; // the name of the action
}
export interface JsonStackTrace {
pack: JsonStackFrame[]; // the array of stack frames
path: number[]; // the trace in a form of indexes into pack
}
export interface JsonRun extends JsonPubOnPub {
bucketid: string; // id of the bucket
userplatform?: string[]; // platform
anonymous: boolean; // is this run anonymous?
error: string; // the error message
runmap: string[]; // the run map
stack: JsonStackTrace; // the stack trace
clientversion: string; // the long release version of the client
compilerversion: string; // the version of the compiler for this run
}
export interface JsonComment extends JsonPubOnPub
{

Просмотреть файл

@ -1,657 +0,0 @@
///<reference path='refs.ts'/>
module TDev {
export interface IStringSet {
[key: string]: boolean;
}
export function setClone(s: IStringSet):IStringSet {
if (!s) return {};
var res:IStringSet = {};
Object.keys(s).forEach(key => key && (res[key] = true));
return res;
}
export function setEmpty(s: IStringSet) {
if (!s) return true;
return Object.keys(s).length === 0;
}
export function setSize(s: IStringSet) {
if (!s) return 0;
return Object.keys(s).length;
}
export function mkSet(...vals: string[]): IStringSet {
var ret:IStringSet = {};
vals.forEach(k => ret[k] = true);
return ret;
}
export function setUnion(s0: IStringSet, s1: IStringSet) {
if (!s0) return setClone(s1);
if (!s1) return setClone(s0);
var res:IStringSet = {};
Object.keys(s0).forEach(key => key && (res[key] = true));
Object.keys(s1).forEach(key => key && (res[key] = true));
return res;
}
export function setIntersection(s0: IStringSet, s1: IStringSet):IStringSet {
if (!s0 || !s1) return {};
var res:IStringSet = {};
Object.keys(s0).forEach(key => key && s1[key] && (res[key] = true));
return res;
}
export function setDifference(s0: IStringSet, s1: IStringSet):IStringSet {
if (!s0) return {};
if (!s1) return setClone(s0);
var res:IStringSet = {};
Object.keys(s0).forEach(key => key && !s1[key] && (res[key] = true));
return res;
}
export function setToArray(s: IStringSet) {
if (!s) return [];
return Object.keys(s).filter(k => !!k);
}
export function setFromArray(s: string[]):IStringSet {
if (!s) return {};
var ret:IStringSet = {};
s.forEach(k => ret[k] = true);
return ret;
}
export class FullRunMapper
extends AST.NodeVisitor {
private fullRunMap: IStringSet = TDev.mkSet();
constructor(public runMap: RunBitMap, public stackTrace: IPackedStackTrace) {
super()
}
public visitAstNode(node: AST.AstNode) {
if (!this.runMap && !this.stackTrace) return;
if (!node) return;
return this.visitChildren(node);
}
public visitDecl(d: AST.Decl) {
return this.visitAstNode(d);
}
private definitelyVisitedCache = {};
private definitelyVisited(id: string): boolean {
if (!id) return;
if (this.definitelyVisitedCache[id] !== undefined) return this.definitelyVisitedCache[id];
var ret = (this.runMap && this.runMap.contains(id)) || (this.stackTrace && this.stackTrace.pack.some(node => node.id === id));
this.definitelyVisitedCache[id] = ret;
return ret;
}
private definitelyVisitedThisOrChildrenCache = {};
private definitelyVisitedThisOrChildren(s: AST.Stmt): boolean {
if (!s) return;
var id = s.stableId;
if (this.definitelyVisitedThisOrChildrenCache[id] !== undefined) return this.definitelyVisitedThisOrChildrenCache[id];
// the depth level is not big, so we can just use recursion
var ret = this.definitelyVisited(s.stableId) || s.children().some((child: AST.Stmt) => this.definitelyVisitedThisOrChildren(child));
this.definitelyVisitedThisOrChildrenCache[s.stableId] = ret;
return ret;
}
// three state return value: true if visited else false; undefined for "don't know"
private visitedCodeBlockStart(cb: AST.Block) {
if (this.runMap &&
cb &&
cb.children() &&
(cb.children().length > 0)) {
var firstNonComment = cb.children().filter(stmt => (stmt.nodeType() !== "comment") && !!stmt.stableId)[0];
if (!firstNonComment) return; // the bb contains only comments, not interested
Util.assert(!!firstNonComment.stableId); // these guys should be already jsonified
return (this.definitelyVisited(firstNonComment.stableId));
} else return;
}
private visitedCodeBlockEnd(cb: AST.Block) {
if (this.runMap &&
cb &&
cb.children() &&
(cb.children().length > 0)) {
var lastNonComment = cb.children().filter(stmt => stmt.nodeType() !== "comment" && !!stmt.stableId).peek();
if (!lastNonComment) return; // the bb contains only comments, not interested
Util.assert(!!lastNonComment.stableId); // these guys should be already jsonified
return (this.definitelyVisited(lastNonComment.stableId));
} else return;
}
private visitedCodeBlockMiddle(cb: AST.Block, stmt: AST.Stmt) {
if (this.runMap &&
cb &&
cb.children() &&
(cb.children().length > 0)) {
var stmtIndex = -1;
var lastVisitedIndex = -1;
cb.children().forEach((v, ix) => {
if (this.definitelyVisitedThisOrChildren(v)) lastVisitedIndex = ix;
if (v.stableId === stmt.stableId) stmtIndex = ix;
});
Util.assert(stmtIndex !== -1 && lastVisitedIndex !== -1);
return (stmtIndex <= lastVisitedIndex);
}
}
private visitedStmt(s: AST.Stmt) {
if (!this.runMap) return;
var visitedStart = this.visitedCodeBlockStart(s.parentBlock());
var visitedEnd = this.visitedCodeBlockEnd(s.parentBlock());
if (!visitedStart) {
return false;
}
if (visitedStart && visitedEnd) {
return true;
}
if (this.visitedCodeBlockMiddle(s.parentBlock(), s)) {
return true;
}
}
public visitStmt(s: AST.Stmt) {
super.visitStmt(s);
if (this.visitedStmt(s)) this.fullRunMap[s.stableId] = true;
}
public visitExprHolder(node: AST.ExprHolder) { // don't go below ExprHolder level
}
static doit(rm: RunBitMap, st: IPackedStackTrace, theScript: AST.App) {
var visitor = new FullRunMapper(rm, st);
visitor.dispatch(theScript);
return visitor.fullRunMap;
}
}
export class FullRunMapDebuggingAnnotator
extends AST.NodeVisitor {
constructor(public fullRunMap: IStringSet) { super(); }
public visitApp(script: AST.App) {
super.visitApp(script);
if (!this.fullRunMap) script.annotatedBy = AST.AnnotationMode.None;
else script.annotatedBy = AST.AnnotationMode.Coverage;
}
public visitExprStmt(s: AST.ExprStmt) {
if (!s || !s.stableId) return;
if (this.fullRunMap[s.stableId]) s.expr.debuggingData = { visited: true };
else s.expr.debuggingData = {};
}
public visitAnyIf(s: AST.If) {
if (!s) return;
var firstTrue = coalesce(s)(s => s.thenBody)(then_ => then_.firstNonComment())(fnc => fnc.stableId)();
var firstFalse = coalesce(s)(s => s.elseBody)(else_ => else_.firstNonComment())(fnc => fnc.stableId)();
var visitedTrue = this.fullRunMap[firstTrue];
var visitedFalse = this.fullRunMap[firstFalse];
if (visitedTrue && visitedFalse) s.rawCondition.debuggingData = { visited: true };
else if (visitedTrue) s.rawCondition.debuggingData = { alwaysTrue: true };
else if (visitedFalse) s.rawCondition.debuggingData = { alwaysFalse: true };
super.visitAnyIf(s);
}
public visitAstNode(node: AST.AstNode) {
if (!node) return;
return this.visitChildren(node);
}
public visitInlineActions(node: AST.InlineActions) {
if (!node) return;
return this.visitExprStmt(node);
}
}
export function getNormalCoverageAsync(scriptId: string, theScript: AST.App, compilerVersion: string) : Promise {
var unionPromise = Cloud.getCoverageDataAsync(scriptId, compilerVersion).then(a => a.length > 0 ? a[0] : null);
var intersectionPromise = Cloud.getCoverageDataAsync(scriptId, compilerVersion, true).then(a => a.length > 0 ? a[0] : null);
var unwrapCoverage = (c) => c && FullRunMapper.doit(RunBitMap.fromJSON(c.astnodes), null, theScript);
return unionPromise.then(union => {
var unwrappedU = unwrapCoverage(union);
return intersectionPromise.then(intersection => {
var unwrappedI = unwrapCoverage(intersection);
return { union: unwrappedU, intersection: unwrappedI };
});
});
}
export function accumulateRunMaps(runs: IRun[], theScript: AST.App, existingUAcc ?: IStringSet, existingIAcc ?: IStringSet) {
var uacc = existingUAcc;
var iacc = existingIAcc;
runs.forEach(run => {
var full = FullRunMapper.doit(run.runmap, run.stack, theScript);
uacc = setUnion(uacc, full);
iacc = (!iacc) ? full : setIntersection(iacc, full);
});
return { union: uacc, intersection: iacc };
}
export function accumulateStacks(runs: IRun[], theScript: AST.App, existingTops?: IStringSet, existingStacks?: IStringSet) {
var tops:IStringSet = existingTops ? existingTops : {};
var stacks = existingStacks;
runs.forEach(run => {
var stack = run.stack;
if (!stack || !stack.pack || !stack.path) return;
var full = setFromArray(stack.pack.map(node => node.id).filter(id => !!id));
var top = stack.pack[stack.path[0]].id;
stacks = setUnion(stacks, full);
tops[top] = true;
});
return { tops: tops, full: stacks };
}
export class ScriptDebuggingBugginessAnnotator extends AST.NodeVisitor {
private bugSkeleton: IStringSet;
private bugShell: IStringSet;
private bugInnerSkeleton: IStringSet;
public maxRating = 9;
public topRatedId: string;
public topRatedRate: number = 0;
public localTopRate: number = 0;
public topRateContainer = { critical: 0 };
constructor(
public normalPortrait: { union: IStringSet; intersection: IStringSet; },
public bugPortrait: { union: IStringSet; intersection: IStringSet; },
public stacky: { tops: IStringSet; full: IStringSet },
public additional: IStringSet = {},
public errorMessage: string = null)
{
super();
this.bugSkeleton = setEmpty(normalPortrait.intersection) ? {} : setDifference(bugPortrait.intersection, normalPortrait.intersection) || {};
this.bugInnerSkeleton = setEmpty(normalPortrait.union) ? {} : setDifference(this.bugSkeleton, normalPortrait.union);
this.bugShell = setEmpty(normalPortrait.union) ? {} : setDifference(bugPortrait.union, normalPortrait.union);
}
public rate(id: string): number {
var ret = 0;
var countSet = (s: IStringSet) => ret += (s[id] ? 1 : 0);
countSet(this.bugPortrait.union || {});
countSet(this.bugPortrait.intersection || {});
countSet(this.stacky.tops || {});
countSet(this.stacky.full || {});
countSet(this.bugShell);
countSet(this.bugSkeleton);
countSet(this.bugInnerSkeleton);
countSet(this.additional);
countSet(this.additional);
if (ret > this.maxRating) ret = this.maxRating;
if (ret > this.localTopRate) this.localTopRate = ret;
if (ret > this.topRatedRate) {
this.topRatedRate = ret;
this.topRatedId = id;
}
return ret;
}
public visitApp(script: AST.App) {
super.visitApp(script);
script.annotatedBy = AST.AnnotationMode.Crash;
this.topRateContainer.critical = this.topRatedRate;
}
public visitAction(node: AST.Action) {
this.localTopRate = 0;
super.visitAction(node);
if (!node || !this.localTopRate) return;
node.debuggingData = { critical: this.localTopRate, max: this.topRateContainer };
}
public visitAstNode(node: AST.AstNode) {
if (!node) return;
return this.visitChildren(node);
}
public updateRatingForGlobals(node: AST.AstNode, rate: number) {
var varFinder = new AST.VariableFinder();
varFinder.traverse(node, true);
varFinder.readGlobals.forEach((g: AST.GlobalDef) => {
var dd = g.debuggingData;
if (dd && dd.critical) (dd.critical < rate) && (dd.critical = rate);
else g.debuggingData = { critical: rate, max: this.topRateContainer };
});
}
public visitAnyIf(node: AST.If) {
if (!node) return;
super.visitAnyIf(node);
var rate = this.rate(node.stableId);
node.rawCondition.debuggingData = { critical: rate, max: this.topRateContainer };
this.updateRatingForGlobals(node.rawCondition, rate);
}
public visitFor(node: AST.For) {
if (!node) return;
super.visitFor(node);
var rate = this.rate(node.stableId);
node.upperBound.debuggingData = { critical: rate, max: this.topRateContainer };
this.updateRatingForGlobals(node.upperBound, rate);
}
public visitForeach(node: AST.Foreach) {
if (!node) return;
super.visitForeach(node);
var rate = this.rate(node.stableId);
node.collection.debuggingData = { critical: rate, max: this.topRateContainer };
this.updateRatingForGlobals(node.collection, rate);
}
public visitWhile(node: AST.While) {
if (!node) return;
super.visitWhile(node);
var rate = this.rate(node.stableId);
node.condition.debuggingData = { critical: rate, max: this.topRateContainer };
this.updateRatingForGlobals(node.condition, rate);
}
public visitInlineActions(node: AST.InlineActions) {
if (!node) return;
return this.visitExprStmt(node);
}
public visitExprStmt(s: AST.ExprStmt) {
if (!s || !s.stableId) return;
var rate = this.rate(s.stableId);
var message = this.stacky && this.stacky.tops && this.stacky.tops[s.stableId] ? this.errorMessage : undefined;
s.expr.debuggingData = { critical: rate, max: this.topRateContainer, errorMessage: message };
this.updateRatingForGlobals(s.expr, rate);
}
}
export class StmtHashTable extends Hashtable {
constructor() {
super((stmt: AST.Stmt) => Hashtable.stringHash(stmt.stableId), (lhv: AST.Stmt, rhv: AST.Stmt) => lhv.stableId === rhv.stableId);
}
public push(stmt: AST.Stmt) {
super.set(stmt, true);
}
}
export class SmallBackSlicer {
public slice: StmtHashTable = new StmtHashTable(); // really a hashset of Stmts
public visitedCFNodes: StmtHashTable = new StmtHashTable(); // really a hashset of Stmts
public relevants: StmtHashTable = new StmtHashTable(); // Stmt => IStringSet
public vars: StmtHashTable = new StmtHashTable() // Stmt => VariableFinder
private steps = 0;
constructor(public roots: AST.Stmt[], public universum: IStringSet) { }
static varsFrom(stmt: AST.AstNode) {
if (stmt instanceof AST.If) stmt = (<AST.If>stmt).rawCondition;
if (stmt instanceof AST.For) stmt = (<AST.For>stmt).upperBound;
if (stmt instanceof AST.While) stmt = (<AST.While>stmt).condition;
if (stmt instanceof AST.Foreach) stmt = (<AST.Foreach>stmt).conditions;
var ret = new AST.VariableFinder();
ret.traverse(stmt, true);
return ret;
}
private defs(stmt: AST.Stmt): IStringSet {
var vars: AST.VariableFinder = this.vars.get(stmt);
if (!vars) this.vars.set(stmt, vars = SmallBackSlicer.varsFrom(stmt));
return setFromArray(vars.writtenGlobals.map(v => v.getName()).concat(vars.writtenLocals.map(v => v.getName())));
}
private refs(stmt: AST.Stmt): IStringSet {
var vars: AST.VariableFinder = this.vars.get(stmt);
if (!vars) this.vars.set(stmt, vars = SmallBackSlicer.varsFrom(stmt));
return setFromArray(vars.readGlobals.map(v => v.getName()).concat(vars.readLocals.map(v => v.getName())));
}
private majorStepBack(from: AST.Stmt[]): AST.Stmt[]{
var retSet = new StmtHashTable();
from.forEach(stmt => this.stepBack(stmt).forEach(pred => (pred) && (retSet.push(pred))));
return retSet.keys();
}
static mayBeControlFlowDependency(from: AST.Stmt, stmt: AST.Stmt) {
var cf = stmt instanceof AST.If || stmt instanceof AST.For || stmt instanceof AST.Foreach || stmt instanceof AST.While;
return cf && AST.PredecessorsFinder.enclosingStmt(from) === stmt; // can use object equality here
}
private stepBack(from: AST.Stmt): AST.Stmt[]{
var total: AST.Stmt[];
total = [];
total = AST.PredecessorsFinder.find(from);
var refs = this.relevants.get(from);
var ignoreIxs: number[] = [];
total.forEach((stmt, ix) => {
var check = this.relevants.get(stmt);
var defs = this.defs(stmt);
var newRefs = this.refs(stmt);
var rel1 = setIntersection(refs, defs);
var rel2 = setDifference(refs, defs);
var rel3 = check || mkSet();
var cf = SmallBackSlicer.mayBeControlFlowDependency(from, stmt) && !(this.visitedCFNodes.get(stmt));
if (!setEmpty(rel1) || cf) {
if (cf) this.visitedCFNodes.set(stmt, true);
this.addToSlice(stmt);
rel3 = setUnion(rel3, newRefs);
}
var ret = setUnion(rel2, rel3);
this.relevants.set(stmt, ret);
if (setSize(check) === setSize(ret)) ignoreIxs.push(ix);
});
ignoreIxs.forEach(ix => delete total[ix]);
return total;
}
private addToSlice(stmt: AST.Stmt) {
if (stmt && this.universum && this.universum[stmt.stableId]) this.slice.set(stmt, true);
}
public doit() {
var current = this.roots;
this.roots.forEach(root => {
this.relevants.set(root, this.refs(root));
this.addToSlice(root);
});
var limitDepth = 100;
var i = 0;
while (current.length > 0 && i < limitDepth) {
++i;
current = current.filter(stmt => !!this.universum[stmt.stableId]);
current = this.majorStepBack(current);
}
return setFromArray(this.slice.keys().map((stmt:AST.Stmt) => stmt.stableId));
}
}
export class ScriptBugginessFeatureSurvey implements EditorSpy {
static surveyName = "BucketColours";
private manager: IEditorSurveyManager;
private eventCounter = 0;
public addTo(manager: IEditorSurveyManager) {
manager.addSpy(ScriptBugginessFeatureSurvey.surveyName, this);
}
/* override */
public onAddThisSpy(manager: IEditorSurveyManager) {
this.manager = manager;
}
/* override */
public onRemoveThisSpy() {
delete this.manager;
this.eventCounter = 0;
}
public removeSelf() {
if (this.manager) this.manager.removeSpy(ScriptBugginessFeatureSurvey.surveyName);
}
/* override */
public onRun(_) {
this.removeSelf();
}
/* override */
public onLeaveDebugMode() {
this.removeSelf();
}
/* override */
public onExit() {
this.removeSelf();
}
private scoreDD(debuggingData) {
if (debuggingData && debuggingData.critical && debuggingData.max) {
var scoreF = debuggingData.critical / debuggingData.max.critical;
return Math.ceil(scoreF * 5) * 20; // level to 20-40-60-80-100 %
} else return 0;
}
private check() {
if (this.eventCounter > 10) {
this.removeSelf();
tick(Ticks.coverageBucketSurveyExceededSuccessfully);
}
this.eventCounter++;
}
/* override */
public onEdit(node: AST.AstNode) {
if (node instanceof AST.ExprStmt) {
this.check();
var dd: any = (<AST.ExprStmt>node).expr.debuggingData;
if (!dd || !dd.max) return; // this is a new statement
var scorr = this.scoreDD(dd);
tickArg(Ticks.coverageBucketSurveyStatementEdit, scorr + "");
return;
}
}
/* override */
public onView(decl: AST.Decl) {
if (decl instanceof AST.Action) {
this.check();
var dd: any = (<AST.Action>decl).debuggingData;
if (!dd || !dd.max) return; // this is a new action
var scorr = this.scoreDD(dd);
tickArg(Ticks.coverageBucketSurveyActionEdit, scorr + "");
return;
}
}
/* override */
public onAddNear(node: AST.AstNode) {
if (node instanceof AST.ExprStmt) {
this.check();
var dd: any = (<AST.ExprStmt>node).expr.debuggingData;
if (!dd || !dd.max) return; // this is a new statement
var scorr = this.scoreDD(dd);
tickArg(Ticks.coverageBucketSurveyStatementEdit, scorr + "");
return;
}
}
/* override */
public onDelete(node: AST.Block) {
this.check();
node.stmts.forEach(stmt => {
if (stmt instanceof AST.ExprStmt) {
var dd: any = (<AST.ExprStmt>stmt).expr.debuggingData;
if (!dd || !dd.max) return; // this is a new statement
var scorr = this.scoreDD(dd);
tickArg(Ticks.coverageBucketSurveyStatementEdit, scorr + "");
}
});
}
/* override */
public onEnterDebugMode() {
this.check();
tick(Ticks.coverageBucketSurveyDebugger);
}
/* override */
public onAddBreakpoint(node: AST.Stmt) {
this.check();
if (node instanceof AST.ExprStmt) {
var dd: any = (<AST.ExprStmt>node).expr.debuggingData;
if (!dd || !dd.max) return; // this is a new statement
var scorr = this.scoreDD(dd);
tickArg(Ticks.coverageBucketSurveyBreakpoint, scorr + "");
return;
}
}
}
}

Просмотреть файл

@ -561,13 +561,6 @@ module TDev
return Meta.packageScriptAsync(this.currentRt, id, options);
}
static scriptProfiledCache: { [scriptId: string]: Promise/*of Profiled*/; } = {}
static getScriptProfiledAsync(scriptId: string): Promise { // of Profiled
var p = EditorHost.scriptProfiledCache[scriptId];
if (!p) EditorHost.scriptProfiledCache[scriptId] = p = Cloud.getProfiledAsync(scriptId, TDev.AST.Compiler.version);
return p;
}
resetAnnotators() {
new ProfilingResultsAnnotator(null).visitApp(Script);
new ScriptDebuggingAnnotator(null, null, null).visitApp(Script);
@ -584,14 +577,6 @@ module TDev
profilingData.maximumEps = this.currentRt.eventQ.maximumEps;
profilingData.averageEps = this.currentRt.eventQ.averageEps;
}
EditorHost.getScriptProfiledAsync(scriptId)
.then(profiled=> {
var p = profiled.count < 20 ? 1 - .90 * profiled.count / 20 : .1; // probability of uploading profiling information; this is after the probability of getting instrumented for profiling; the combined probability converges to 1%
if (Random.normalized() < p)
return Cloud.postProfilingDataAsync(scriptId, profilingData)
.then(() => profiled.count++);
})
.done(undefined, () => { }); // ignore network errors
}
if (profilingData.show) {
this.resetAnnotators();
@ -599,27 +584,9 @@ module TDev
}
}
static scriptCoveredCache: { [scriptId: string]: Promise/*of Covered*/; } = { }
static getScriptCoveredAsync(scriptId: string): Promise { // of Covered
var p = EditorHost.scriptCoveredCache[scriptId];
if (!p) EditorHost.scriptCoveredCache[scriptId] = p = Cloud.getCoveredAsync(scriptId, TDev.AST.Compiler.version);
return p;
}
public attachCoverageInfo(coverageData: CoverageData, showCoverage: boolean): void {
if (!coverageData) return;
var scriptId = this.currentRt.currentScriptId;
if (scriptId)
EditorHost.getScriptCoveredAsync(scriptId)
.then(covered => {
var p = covered.count < 90 ? .5 - .49 * covered.count / 90 : .01; // probability of uploading coverage information
if (Random.normalized() < p)
return Cloud.postCoverageDataAsync(scriptId, coverageData)
.then(() => covered.count++);
})
.done(undefined, () => { }); // ignore network errors
if (showCoverage) {
this.resetAnnotators();
this.attachDebuggingInfo(RunBitMap.fromJSON(coverageData.astnodes), null, null);
@ -1623,7 +1590,6 @@ module TDev
crashOnInvalid: /crashOnInvalid/.test(document.URL),
commonSubexprElim: /commonSubexprElim/.test(document.URL),
constantPropagation: /constantPropagation/.test(document.URL),
coverage: true,
azureSite: Azure.getDestinationAppUrl(app),
};
Object.keys(opts).forEach((k) => {

Просмотреть файл

@ -14,7 +14,6 @@
///<reference path='collab.ts'/>
///<reference path='declrender.ts'/>
///<reference path='debugger.ts'/>
///<reference path='debuggerAnalysis.ts'/>
///<reference path='libraryExtractor.ts'/>
///<reference path='editor.ts'/>
///<reference path='tutorial.ts'/>

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -92,7 +92,6 @@ module TDev.TestMgr
blockChaining: Browser.compilerBlockChaining || /blockChaining/.test(document.URL),
commonSubexprElim: /commonSubexprElim/.test(document.URL),
constantPropagation: /constantPropagation/.test(document.URL),
coverage: false,
crashOnInvalid: /crashOnInvalid/.test(document.URL),
};
}

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -1,8 +1,5 @@
///<reference path='refs.ts'/>
module TDev {
export module Cloud {
module TDev.Cloud {
export var lite = false;
@ -518,10 +515,6 @@ module TDev {
{
return Util.httpPostJsonAsync(getPrivateApiUrl("bug"), bug);
}
export function postRunReportAsync(id: string, run: any): Promise // of ???
{
return Util.httpPostJsonAsync(getPrivateApiUrl(id + "/runs"), run);
}
export function postTicksAsync(ticks:any) : Promise // of void
{
return Util.httpPostJsonAsync(getPrivateApiUrl("ticks"), ticks);
@ -608,41 +601,6 @@ module TDev {
client.send();
});
}
export function postProfilingDataAsync(id: string, body: any /*ProfilingData*/): Promise // of void
{
return Util.httpPostJsonAsync(getPrivateApiUrl(id + "/profile?v=1"), body);
}
export function postCoverageDataAsync(id: string, body: any /*CoverageData*/): Promise // of void
{
return Util.httpPostJsonAsync(getPrivateApiUrl(id + "/coverage"), body);
}
export function getCoverageDataAsync(id: string, compilerversion: string, intersection: boolean = false): Promise // of CoverageData[]
{
return Util.httpGetJsonAsync(getPrivateApiUrl(id + "/coverage?compilerversion=" + encodeURIComponent(compilerversion) + (intersection ? "&view=intersection" : "")));
}
export interface Covered {
count: number;
}
export function getCoveredAsync(id: string, compilerversion: string): Promise // of Covered
{
return Util.httpGetJsonAsync(getPrivateApiUrl("me/covered/" + id + "?compilerversion=" + encodeURIComponent(compilerversion)));
}
export function getProfileDataAsync(id: string, compilerversion: string): Promise // of ProfileData[]
{
return Util.httpGetJsonAsync(getPrivateApiUrl(id + "/profile?compilerversion=" + encodeURIComponent(compilerversion)));
}
export interface Profiled {
count: number;
}
export function getProfiledAsync(id: string, compilerversion: string): Promise // of Profiled
{
return Util.httpGetJsonAsync(getPrivateApiUrl("me/profiled/" + id + "?compilerversion=" + encodeURIComponent(compilerversion)));
}
export function postPendingProgressAsync() {
if (!getUserId() || !getAccessToken() || isOffline() || dbg) return Promise.as();
var data = loadPendingProgress();
@ -657,7 +615,4 @@ module TDev {
var req = { kind: "comment", text: text, userplatform: Browser.platformCaps };
return Cloud.postPrivateApiAsync(id + "/comments", req)
}
}
}

Просмотреть файл

@ -715,8 +715,6 @@ module TDev {
public attachScriptStackTrace(bug: BugReport): void { }
/* overriden in EditorHost */
public debugModeEnabled(): boolean { return false; }
/* overriden in EditorHost */
public publishRunHelpLink(title: string): any { return undefined; }
public exceptionHandler(e:any)
{
@ -731,10 +729,6 @@ module TDev {
var stack = PackedStackTrace.buildFrom(this.currentRt.getStackTrace());
TDev.RT.App.logException(e);
var askRunReport =
!!e.isUserError &&
!!Runtime.theRuntime.currentScriptId /* && this.currentRt.currentAuthorId != Cloud.getUserId() */; // the commented piece is questionable, put to remove by Nikolai
var actions = this.exceptionActions(e) || {}
var debugAction = actions.debug || Util.doNothing;
@ -747,70 +741,7 @@ module TDev {
d.addFirst(div("floatingFrown", ":("))
}
if (askRunReport) {
var futureModalDialog: ModalDialog;
var debugBtn: any = (this.debugModeEnabled() && debugAction) ? HTML.mkButton(lf("debug"), () => {
debugAction(); this.attachDebuggingInfo(runMap, stack, msg); futureModalDialog.dismiss()
}) : null;
var sendRunReport = (anonymous: boolean, comment?: string) => {
var run: IRun = {
clientfile: (<any>window).mainJsName,
compilerversion: this.currentRt.compiled._compilerVersion,
kind: "run",
publicationid: this.currentRt.currentScriptId,
error: error,
stack: stack,
runmap: runMap.isEmpty() ? undefined : runMap,
userplatform: Browser.platformCaps,
anonymous: anonymous
};
var rt = Runtime.theRuntime;
Cloud.postRunReportAsync(rt.currentScriptId, run).done(
json => {
HTML.showProgressNotification(dbg ? ("crash report submitted: /" + json.id) : "thank you for your run report");
if (!!comment) {
var jsonComment = {
kind: "comment",
text: comment,
userplatform: Browser.platformCaps
};
Util.httpPostJsonAsync(Cloud.getPrivateApiUrl(json.id + "/comments"), jsonComment).done();
}
},
e => HTML.showProgressNotification(dbg ? ("crash report send failed: " + e) : "thank you for your run report")
);
}
var hiddenContent = div(null);
var commentArea = HTML.mkAutoExpandingTextArea();
commentArea.textarea.placeholder = "describe how you crashed the script";
var defDS = hiddenContent.style.display;
hiddenContent.style.display = "none";
hiddenContent.setChildren([commentArea.div, debugBtn]);
var showHidden = (v: boolean) => hiddenContent.style.display = v ? defDS : "none";
var commentBox = HTML.mkCheckBox(
lf("show additional options"),
showHidden
);
futureModalDialog = ModalDialog.askManyWithAdditionalElts(
lf("the script crashed"), this.publishRunHelpLink("about posting crash"),
lf("Do you want to post some information to help improve the script? (The collected information include a stack trace, a coverage map, and a message.)"),
lf("error message"),
error,
{
"post": () => sendRunReport(false, commentArea.textarea.value || null),
"post anonymously": () => sendRunReport(true, commentArea.textarea.value || null),
cancel: () => { },
},
commentBox,
hiddenContent
);
futureModalDialog.fullYellow();
frown(futureModalDialog)
} else if(this.canEditCode() && !!e.syntaxErrorDeclName) {
if(this.canEditCode() && !!e.syntaxErrorDeclName) {
var dial = ModalDialog.buttons(
lf("errors in the code?"),
lf("the script appears to have some errors. fix each error marked with a red :( symbol and try to run again"),