Skip to content

Commit

Permalink
fix: Cannot read property of null for bgTokenizer after session is de…
Browse files Browse the repository at this point in the history
…stroyed (#4713)

* fix: Cannot read property of null for bgTokenizer after session is destroyed

* fixed lint issues

* added bgTokenizer.cleanup method
  • Loading branch information
andrewnester committed May 30, 2022
1 parent cd30f59 commit d604f52
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 20 deletions.
8 changes: 8 additions & 0 deletions lib/ace/background_tokenizer.js
Expand Up @@ -245,6 +245,14 @@ var BackgroundTokenizer = function(tokenizer, editor) {
return this.lines[row] = data.tokens;
};

this.cleanup = function() {
this.running = false;
this.lines = [];
this.states = [];
this.currentLine = 0;
this.removeAllListeners();
};

}).call(BackgroundTokenizer.prototype);

exports.BackgroundTokenizer = BackgroundTokenizer;
Expand Down
34 changes: 18 additions & 16 deletions lib/ace/edit_session.js
Expand Up @@ -153,6 +153,15 @@ var EditSession = function(text, mode) {
this.$foldData.toString = function() {
return this.join("\n");
};

// Set default background tokenizer with Text mode until editor session mode is set
this.bgTokenizer = new BackgroundTokenizer((new TextMode()).getTokenizer(), this);

var _self = this;
this.bgTokenizer.on("update", function(e) {
_self._signal("tokenizerUpdate", e);
});

this.on("changeFold", this.onChangeFold.bind(this));
this.$onChange = this.onChange.bind(this);

Expand All @@ -166,6 +175,8 @@ var EditSession = function(text, mode) {
config.resetOptions(this);
this.setMode(mode);
config._signal("session", this);

this.destroyed = false;
};


Expand All @@ -188,8 +199,7 @@ EditSession.$uid = 0;
this.doc = doc;
doc.on("change", this.$onChange);

if (this.bgTokenizer)
this.bgTokenizer.setDocument(this.getDocument());
this.bgTokenizer.setDocument(this.getDocument());

this.resetCaches();
};
Expand Down Expand Up @@ -244,7 +254,7 @@ EditSession.$uid = 0;
this.$wrapData = [];
this.$rowLengthCache = [];
this.$resetRowCache(0);
if (this.bgTokenizer)
if (!this.destroyed)
this.bgTokenizer.start(0);
};

Expand Down Expand Up @@ -273,7 +283,7 @@ EditSession.$uid = 0;
this.$informUndoManager.schedule();
}

this.bgTokenizer && this.bgTokenizer.$updateOnChange(delta);
this.bgTokenizer.$updateOnChange(delta);
this._signal("change", delta);
};

Expand Down Expand Up @@ -914,16 +924,7 @@ EditSession.$uid = 0;
tokenizer.on("update", onReloadTokenizer);
}

if (!this.bgTokenizer) {
this.bgTokenizer = new BackgroundTokenizer(tokenizer);
var _self = this;
this.bgTokenizer.on("update", function(e) {
_self._signal("tokenizerUpdate", e);
});
} else {
this.bgTokenizer.setTokenizer(tokenizer);
}

this.bgTokenizer.setTokenizer(tokenizer);
this.bgTokenizer.setDocument(this.getDocument());

this.tokenRe = mode.tokenRe;
Expand Down Expand Up @@ -2398,9 +2399,10 @@ EditSession.$uid = 0;
};

this.destroy = function() {
if (this.bgTokenizer) {
if (!this.destroyed) {
this.bgTokenizer.setDocument(null);
this.bgTokenizer = null;
this.bgTokenizer.cleanup();
this.destroyed = true;
}
this.$stopWorker();
this.removeAllListeners();
Expand Down
10 changes: 10 additions & 0 deletions lib/ace/edit_session_test.js
Expand Up @@ -1143,6 +1143,16 @@ module.exports = {
next();
});
}, 0);
},

"test: sets destroyed flag when destroy called and tokenizer is never null": function() {
var session = new EditSession(["foo bar foo bar"]);
assert.notEqual(session.bgTokenizer, null);
assert.equal(session.destroyed, false);

session.destroy();
assert.equal(session.destroyed, true);
assert.notEqual(session.bgTokenizer, null);
}
};
});
Expand Down
8 changes: 4 additions & 4 deletions lib/ace/editor.js
Expand Up @@ -99,7 +99,7 @@ var Editor = function(renderer, session, options) {

this._$emitInputEvent = lang.delayedCall(function() {
this._signal("input", {});
if (this.session && this.session.bgTokenizer)
if (this.session && !this.session.destroyed)
this.session.bgTokenizer.scheduleStart();
}.bind(this));

Expand Down Expand Up @@ -402,7 +402,7 @@ Editor.$uid = 0;
oldSession && oldSession._signal("changeEditor", {oldEditor: this});
session && session._signal("changeEditor", {editor: this});

if (session && session.bgTokenizer)
if (session && !session.destroyed)
session.bgTokenizer.scheduleStart();
};

Expand Down Expand Up @@ -532,7 +532,7 @@ Editor.$uid = 0;
setTimeout(function () {
self.$highlightPending = false;
var session = self.session;
if (!session || !session.bgTokenizer) return;
if (!session || session.destroyed) return;
if (session.$bracketHighlight) {
session.$bracketHighlight.markerIds.forEach(function(id) {
session.removeMarker(id);
Expand Down Expand Up @@ -581,7 +581,7 @@ Editor.$uid = 0;
self.$highlightTagPending = false;

var session = self.session;
if (!session || !session.bgTokenizer) return;
if (!session || session.destroyed) return;

var pos = self.getCursorPosition();
var iterator = new TokenIterator(self.session, pos.row, pos.column);
Expand Down

0 comments on commit d604f52

Please sign in to comment.