How We Understand the Internal of Text Editor by Code Reading - part2

EditSession class

It was hard to infer a role of EditSession from its class name. The only fact we got about EditSession was the second largest file of the 14 core classes. It had 2,570 lines. The large amount of code implied the existance of a lot of functions. We had to search representative methods or symbolic properties in EditSession and resolve a role of this class.

Gather clues or hints

In order to get a comprehensive from test code, we opened edit_session_test.js, but this file had over 1k lines of code. Even the test file was not so easy to read all of its. Because we had few information or inference, it was almost impossible to select the test code we should read in the large amout of code. So, we changed direction to gather clues or hints from edit_session.js.

In the top of edit_session.js, BidiHandler, EventEmitter, Selection, TextMode, Range, Document, BackgroundTokenizer, SearchHighlight classes were required. We didn't know the roles of these classes except for Document. They were not clues or hints yet.

Stores all the data about [[Editor Editor]] state providing easy way to change editors state. EditSession can be attached to only one [[Document Document]]. Same Document can be attached to several EditSessions.

Next to the area of requiring other classes, the comment above explained a role of EditSession. Though we didn't have enough information to understand this comment, some questions arised from it. What was Editor state? How was the use case that the same Document was attached to several EditSessions? What properties stored such data?

Sets up a new EditSession and associates it with the given Document and TextMode.

After some explanations about events, the comment above said TextMode was associated to EditSession as well as Document was. What purpose was this association for?

As we have so far read the code of EditSession class, comments are very important source for code reading. The quality of them depends on the source code, but in our opinion if the quality of comments, variable names or method names seems bad, the quality of code is often worse. In that case, the way to read comments before code is not so bad.

Code Reading Tips: Comments are very important source for code reading.

While we paid attention to variable names or method names and scrolled down to the bottom of the file, new clues or hints were found. Some of the methods seemed to form a group which made up a function. EditSession had more complicated data structure than Document had. The methods to manipulate strings like insert or remove existed in EditSession as well as in Document.

Assemble some methods into a function

As a next step, we picked up one of these hints to understand EditSession. If some methods formed a group which made up a function, assembling some methods into a function might reduce complexity. We applied this idea to the test file. We assembled some tests related to a function into a group and then called the group the function. For example, test: duplicate lines, test: duplicate last line and test: duplicate first line were assembled and called 'duplicate line'.

The results were below.

  • bracket pairing
  • replace line/duplicate line
  • get the last line/row position
  • transform Document-related coordinates into display coordinates
  • transform display coordinates into Document-related coordinates
  • wrap
  • get display width
  • folding

This assembling and naming technique made it easy to understand features of EditSession. This approach abstracted functions from a lot of methods. According to these functions which were abstracted from the test code, EditSession could be inferred to play a role that it manipulated a bunch of text. The inference would be helpful to understand EditSession later.

We discover a new code reading tip now. Assemble related methods or tests into a function or a role, and then name it. This technique abstracts functional specs from the code which is based on technical specs. It is effective to understand a role of a class because functional specs are more comprehensive than technical specs.

Required classes by EditSession

To validate the inference that EditSession played a role to manipulate a bunch of text, we investigated each role of the 8 required classes in the top of edit_session.js.

Some of the required classes were easy to understand their roles from their class names.

class role
BidiHandler Supports Bi-Directional like Arabic or Hebrew
EventEmitter Emits an event
Range Indicates a region within the editor
Document Inserts or removes strings
SearchHighlight Highlights search results

The aim to understand roles of these classes was to get what functions they provided for EditSession. So the list above was good enough. The functions these classes provided were within the role of EditSession we inferred.

To understand the rest of the required classes, we referred the comments in their code or the official site. Of course, the source code, too.

Selection class

Contains the cursor position and the text selection of an edit session. The row/columns used in the selection are in document coordinates representing the coordinates as they appear in the document before applying soft wrap and folding.

According to the comments in selection.js, Selection was related to soft wrap and folding.

In edit_session.js, Selection was attached to EditSession as a property. And the property was called by both the methods 'undoChanges' and 'redoChanges'. So, the role of Selection also contained Redo/Undo functions.

TextMode class

TextMode was inferred to be a class related to syntax highlighting. This inference was based on our background knowledge that syntax highlighting used the word "mode" and "mode" recoginized a language's syntax. The official site said,

Defining a Mode Every language needs a mode. A mode contains the paths to a language's syntax highlighting rules, indentation rules, and code folding rules. Without defining a mode, Ace won't know anything about the finer aspects of your language.

Almost the same as our inference, "mode" meaned a basis of syntax highlighting. So, the role of TextMode turned out Syntax highlighting function. In EditSession class, TextMode was set to $mode property by the method setMode in the step of initializing an EditSession object.

BackgroundTokenizer class

BackgroundTokenizer was also inferred to be a part of syntax highlighting from the class name. As well as "mode", "tokenize" was used in the process of syntax highlighting. BackgroundTokenizer was called by the methods getTokens and getTokenAt in EditSession class. So, BackgroundTokenizer was considered to play a role of tokenizing in the background.

Summary of required classes

The summary of the 8 required classes was below. Each class was not out of range of our inference about EditSession.

class role
BidiHandler Supports Bi-Directional like Arabic or Hebrew
EventEmitter Emits an event
Range Indicates a region within the editor
Document Inserts or removes strings
SearchHighlight Highlights search results
Selection Contains the cursor position and the text selection for redo/undo
TextMode Contains the paths to a language's syntax highlighting rules
BackgroundTokenizer Tokenizes in the background for syntax highlighting

What was EditSession?

So far, we found various functions of EditSession by investigating the test code and the required classes.

  • bracket pairing
  • replace line/duplicate line
  • get the last line/row position
  • transform Document-related coordinates into display coordinates
  • transform display coordinates into Document-related coordinates
  • wrap
  • get display width
  • folding
  • bi-directional support
  • insert or remove text
  • highlight search results
  • redo/undo
  • syntax highlighting

If these functions were summarized into one, EditSession was considered to play a role of preprocessing to display text holded by Document. It took a long road from the start, at which we didn't have any critical information about EditSession. Now we understood its role in Ace editor.

At the end of investigating EditSession, we picked up doc, $docRowCache and $screenRowCache as representative properties. These properties were used to preprocess text or to transform coordinates.

Next was Editor class. Chances were that Editor was the very core of Ace.