Skip to content
This repository has been archived by the owner on Feb 27, 2024. It is now read-only.

Commit

Permalink
All existing test decoupled and passing
Browse files Browse the repository at this point in the history
  • Loading branch information
jhm-ciberman committed Mar 6, 2018
1 parent 17d945a commit 9957e95
Show file tree
Hide file tree
Showing 26 changed files with 349 additions and 364 deletions.
72 changes: 0 additions & 72 deletions inversify.config.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/docs_gm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
* This file is the entry point for the command line interface (CLI)
*/

import container from "../inversify.config";
import Cli from "./cli/Cli";
import container from "./inversify.config";

// CLI Composition root
const cli = container.get(Cli);
Expand Down
34 changes: 6 additions & 28 deletions src/generator/DocProjectGenerator.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
import { inject, injectable } from "inversify";
import { TYPES } from "../../types";

import * as fse from "fs-extra";
import * as path from "path";

import IProjectConfig from "../config/interfaces/IProjectConfig";
import DocFolder from "../doc_models/DocFolder";
import DocProject from "../doc_models/DocProject";
import DocResource from "../doc_models/DocResource";
import DocScript from "../doc_models/DocScript";
import IGMFolder from "../gm_project/interfaces/IGMFolder";
import IGMProject from "../gm_project/interfaces/IGMProject";
import IGMResource from "../gm_project/interfaces/IGMResource";
import IGMScript from "../gm_project/interfaces/IGMScript";
import IDocProjectGenerator from "./interfaces/IDocProjectGenerator";
import IDocumentationExtractor from "./interfaces/IDocumentationExtractor";
import IScriptLoader from "./interfaces/IScriptLoader";

/**
* This class generates a DocProject
Expand All @@ -23,10 +19,10 @@ import IDocumentationExtractor from "./interfaces/IDocumentationExtractor";
export default class DocProjectGenerator implements IDocProjectGenerator {

/**
* The documentationExtractor used to extract the documentation of the GMScripts
* The script loader
*/
@inject(TYPES.IDocumentationExtractor)
private _extractor: IDocumentationExtractor;
@inject(TYPES.IScriptLoader)
private _scriptLoader: IScriptLoader;

/**
* Generates the DocProject for a given GMProject
Expand Down Expand Up @@ -77,7 +73,7 @@ export default class DocProjectGenerator implements IDocProjectGenerator {
* Returns true if the resource is a GMScript
*/
private _isScript(res: IGMResource): res is IGMScript {
return (res as IGMScript).loadFromString !== undefined;
return (res as IGMScript).subScripts !== undefined;
}

/**
Expand All @@ -90,28 +86,10 @@ export default class DocProjectGenerator implements IDocProjectGenerator {
if (this._isFolder(res)) {
return [await this._loadFolder(res, config, gmProject)];
} else if (this._isScript(res)) {
return this._loadScript(res, config, gmProject);
return this._scriptLoader.load(res, config, gmProject);
} else {
throw new Error(`Unrecognized resource type for resource "${res.name}"`);
}
}

/**
* Loads a single GMScript with all the subscripts from disk and extracts
* the documentation from it.
*/
private async _loadScript(gmScript: IGMScript, config: IProjectConfig, gmProject: IGMProject): Promise<DocScript[]> {
if (!gmScript.match(config.output.pattern)) {
return [];
}
const pathStr = path.resolve(gmProject.path, gmScript.filepath);
try {
const str = await fse.readFile(pathStr, "utf8");
gmScript.loadFromString(str);
} catch (e) {
throw new Error(`Error loading file ${pathStr}`);
}
return this._extractor.extractDocScripts(gmScript, config.scripts, config.warnUnrecognizedTags);
}

}
10 changes: 5 additions & 5 deletions src/generator/DocumentationExtractor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { TYPES } from "../../types";

import IScriptValidationRules from "../config/interfaces/IScriptValidationRules";
import DocScript from "../doc_models/DocScript";
import IGMScript from "../gm_project/interfaces/IGMScript";
import GMSubscript from "../gm_project/GMSubscript";
import JSDocParser from "../parser/JSDocParser";
import IScriptValidator from "../validation/interfaces/IScriptValidator";
import ValidableScript from "../validation/ValidableScript";
Expand Down Expand Up @@ -34,16 +34,16 @@ export default class DocumentationExtractor implements IDocumentationExtractor {
* @param script An array with DocScript objects
*/
public extractDocScripts(
script: IGMScript,
subscriptsIterator: IterableIterator<GMSubscript>,
rules: IScriptValidationRules,
warnUnrecognizedTags: boolean,
): DocScript[] {
const arr = [];

this._jsDocParser.warnUnrecognizedTags = warnUnrecognizedTags;
for (const [name, gmlText] of script.subScripts()) {
const docScript = this._jsDocParser.parse(name, gmlText);
const validable = new ValidableScript(docScript, gmlText);
for (const subScript of subscriptsIterator) {
const docScript = this._jsDocParser.parse(subScript.name, subScript.text);
const validable = new ValidableScript(docScript, subScript.text);
if (this._scriptValidator.validate(validable, rules)) {
arr.push(docScript);
}
Expand Down
45 changes: 45 additions & 0 deletions src/generator/ScriptLoader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { inject, injectable } from "inversify";
import { TYPES } from "../../types";

import * as fse from "fs-extra";
import * as path from "path";

import IProjectConfig from "../config/interfaces/IProjectConfig";
import DocScript from "../doc_models/DocScript";
import IGMProject from "../gm_project/interfaces/IGMProject";
import IGMScript from "../gm_project/interfaces/IGMScript";
import IDocumentationExtractor from "./interfaces/IDocumentationExtractor";
import IScriptLoader from "./interfaces/IScriptLoader";

/**
* This class loads a GMScript and extracts the documentation for it
*/
@injectable()
export default class ScriptLoader implements IScriptLoader {

/**
* The documentationExtractor used to extract the documentation of the GMScripts
*/
@inject(TYPES.IDocumentationExtractor)
private _extractor: IDocumentationExtractor;

/**
* Loads a single GMScript with all the subscripts from disk and extracts
* the documentation from it. It can return an empty array if the gmScript is not included in the
* glob pattern inside the project config.
*/
public async load(gmScript: IGMScript, config: IProjectConfig, gmProject: IGMProject): Promise<DocScript[]> {
if (!gmScript.match(config.output.pattern)) {
return [];
}
const pathStr = path.resolve(gmProject.path, gmScript.filepath);
let str;
try {
str = await fse.readFile(pathStr, "utf8");
} catch (e) {
throw new Error(`Error loading file ${pathStr}`);
}
const it = gmScript.subScripts(str);
return this._extractor.extractDocScripts(it, config.scripts, config.warnUnrecognizedTags);
}
}
3 changes: 2 additions & 1 deletion src/generator/interfaces/IDocumentationExtractor.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import DocScript from "../../doc_models/DocScript";
import IProjectConfig from "../../config/interfaces/IProjectConfig";
import IScriptValidationRules from "../../config/interfaces/IScriptValidationRules";
import IGMScript from "../../gm_project/interfaces/IGMScript";
import GMSubscript from "../../gm_project/GMSubscript";

export default interface IDocumentationExtractor {
extractDocScripts(script: IGMScript, rules: IScriptValidationRules, warnUnrecognizedTags: boolean): DocScript[];
extractDocScripts(subscriptsIterator: IterableIterator<GMSubscript>, rules: IScriptValidationRules, warnUnrecognizedTags: boolean): DocScript[];
}
8 changes: 8 additions & 0 deletions src/generator/interfaces/IScriptLoader.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import IGMScript from "../../gm_project/interfaces/IGMScript";
import IProjectConfig from "../../config/interfaces/IProjectConfig";
import IGMProject from "../../gm_project/interfaces/IGMProject";
import DocScript from "../../doc_models/DocScript";

export default interface IScriptLoader {
load(gmScript: IGMScript, config: IProjectConfig, gmProject: IGMProject): Promise<DocScript[]>;
}
2 changes: 1 addition & 1 deletion src/gm_project/GMFolder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export default class GMFolder extends GMResource implements IGMFolder {
* Returns true if the resource is a GMScript
*/
private _isScript(res: IGMResource): res is IGMScript {
return (res as IGMScript).loadFromString !== undefined;
return (res as IGMScript).subScripts !== undefined;
}

/**
Expand Down
25 changes: 25 additions & 0 deletions src/gm_project/GMSubscript.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* This class represents a subscript
*/
export default class GMSubscript {
/**
* The subscript name
*/
public readonly name: string;

/**
* The subscript gml text
*/
public readonly text: string;

/**
* Creates an instance of GMSubscript.
* @param {string} name The subscript name
* @param {string} text The subscript gml text
* @memberof GMSubscript
*/
constructor(name: string, text: string) {
this.name = name;
this.text = text;
}
}
69 changes: 31 additions & 38 deletions src/gm_project/gms1/GMS1Script.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
import * as path from "path";

import GMResource from "../GMResource";
import GMSubscript from "../GMSubscript";
import IGMScript from "../interfaces/IGMScript";

/**
* Represents a GMS1 Script. Can contain subscripts.
*/
export default class GMS1Script extends GMResource {
export default class GMS1Script extends GMResource implements IGMScript {

/**
* The filename of the script
*/
private _path: string;

/**
* A map with each subscript.
* Key: subscript name.
* value: gml of the subscript
*/
private _subScripts: Map<string, string> = new Map();

/**
* This regex captures the script name in the capture group 1, and
* the content of the script in the capture group 2.
Expand All @@ -34,30 +29,6 @@ export default class GMS1Script extends GMResource {
this._path = file;
}

/**
* Loads and parses the script with subscripts
* from a string.
* @param str The content of the *.gml file
* @returns A promise
*/
public async loadFromString(str: string): Promise<this> {
this._subScripts.clear();
// Normalize new lines (to use the next regex)
str = str.replace(/\r\n/g, "\n").replace(/\r/g, "\n");

let m = this._captureSubscriptsRegex.exec(str);
if (m === null) {
this._subScripts.set(this.name, str);
} else {
while (m) {
this._subScripts.set(m[1], m[2]);
m = this._captureSubscriptsRegex.exec(str);
}
}

return this;
}

/**
* The relative file path of the *.gml file.
*/
Expand All @@ -69,16 +40,38 @@ export default class GMS1Script extends GMResource {
* Returns an iterable with a pair of [name, text] for each
* subscript in this script object
*/
public * subScripts(): IterableIterator<[string, string]> {
if (this._subScripts.size === 0) {
throw new Error("Must call loadFromString() before accesing the subScripts() function");
}
for (let [name, content] of this._subScripts.entries()) {
public * subScripts(gmlText: string): IterableIterator<GMSubscript> {

for (let [name, content] of this._parseSubscripts(gmlText).entries()) {
// This lines converts the triple slash comments ( ///comment)
// to a @function JSDoc comments
content = content.replace(/\/\/\/ ?(.*)\n/g, "/**\n * @function $1 \n */\n");
yield [name, content];
yield new GMSubscript(name, content);
}
}

/**
* Parses the gml file contents and returns a map were each key is the name of
* one subscript and each value is the gml content of that subscript
* @private
* @returns {Map<string, string>}
* @memberof GMS1Script
*/
private _parseSubscripts(gmlText: string): Map<string, string> {
// Key: subscript name, value: gmlText of the subscript
const subScripts: Map<string, string> = new Map();
// Normalize new lines (to use the next regex)
gmlText = gmlText.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
let m = this._captureSubscriptsRegex.exec(gmlText);
if (m === null) {
subScripts.set(this.name, gmlText);
} else {
while (m) {
subScripts.set(m[1], m[2]);
m = this._captureSubscriptsRegex.exec(gmlText);
}
}
return subScripts;
}

}
Loading

0 comments on commit 9957e95

Please sign in to comment.