##// END OF EJS Templates
added provided and configure methods to the fluent container configuration, added applyConfig method to the container
added provided and configure methods to the fluent container configuration, added applyConfig method to the container

File last commit:

r115:691199f665e0 ioc ts support
r142:be7edf08a115 v1.4.0-rc3 default
Show More
FormatCompiler.ts
134 lines | 4.0 KiB | video/mp2t | TypeScriptLexer
/ src / main / ts / text / FormatCompiler.ts
import { FormatScanner, TokeType } from "./FormatScanner";
import { isNullOrEmptyString, isPrimitive, get } from "../safe";
import { TextWriter, MapOf } from "../interfaces";
type CompiledPattern = (writer: TextWriter, args: any) => void;
export class FormatCompiler {
_scanner: FormatScanner;
static _cache: MapOf<CompiledPattern> = {};
_parts: Array<string | { name: string; format?: string; }>;
constructor(scanner: FormatScanner) {
this._scanner = scanner;
this._parts = [];
}
compile() {
this.visitText();
const parts = this._parts;
return (writer: TextWriter, args: any) => {
parts.forEach(x => {
if (isPrimitive(x))
writer.writeValue(x);
else
writer.writeValue(get(x.name, args), x.format);
});
};
}
static compile(pattern: string) {
let compiledPattern = this._cache && this._cache[pattern];
if (!compiledPattern) {
const compiler = new this(new FormatScanner(pattern));
compiledPattern = compiler.compile();
this._cache[pattern] = compiledPattern;
}
return compiledPattern;
}
visitText() {
while (this._scanner.next()) {
// console.log(this._scanner.getTokenType(), this._scanner.getTokenValue());
switch (this._scanner.getTokenType()) {
case TokeType.CurlOpen:
this.visitCurlOpen();
break;
case TokeType.CurlClose:
this.visitCurlClose();
break;
default:
this.pushText(this._scanner.getTokenValue());
}
}
}
visitCurlClose() {
if (!this._scanner.next())
this.dieUnexpectedEnd("}");
if (this._scanner.getTokenType() !== TokeType.CurlClose)
this.dieUnexpectedToken("}");
this.pushText("}");
}
visitCurlOpen() {
if (!this._scanner.next())
this.dieUnexpectedEnd("{ | TEXT");
if (this._scanner.getTokenType() === TokeType.CurlOpen)
this.pushText("{");
else
this.visitTemplateSubst();
}
visitTemplateSubst() {
if (this._scanner.getTokenType() !== TokeType.Text)
this.dieUnexpectedToken("TEXT");
const fieldName = this._scanner.getTokenValue();
const filedFormat = this.readColon() ? this.readFieldFormat() : undefined;
if (this._scanner.getTokenType() !== TokeType.CurlClose)
this.dieUnexpectedToken("}");
this.pushSubst(fieldName, filedFormat);
}
readFieldFormat() {
const parts = new Array<string>();
do {
if (this._scanner.getTokenType() === TokeType.CurlClose) {
return parts.join("");
} else {
parts.push(this._scanner.getTokenValue());
}
} while (this._scanner.next());
this.dieUnexpectedEnd("}");
}
readColon() {
if (!this._scanner.next())
this.dieUnexpectedEnd();
if (this._scanner.getTokenType() !== TokeType.Colon)
return false;
if (!this._scanner.next())
this.dieUnexpectedEnd();
return true;
}
pushSubst(fieldName: string, filedFormat?: string) {
// console.log("pushSubst ", fieldName, filedFormat);
this._parts.push({ name: fieldName, format: filedFormat });
}
pushText(text: string) {
this._parts.push(text);
}
dieUnexpectedToken(expected?: string): never {
throw new Error(isNullOrEmptyString(expected) ?
`Unexpected token ${this._scanner.getTokenValue()}` :
`Unexpected token ${this._scanner.getTokenValue()}, expected ${expected}`
);
}
dieUnexpectedEnd(expected?: string): never {
throw new Error(isNullOrEmptyString(expected) ? "Unexpected end of the string" : `Unexpected end of the string, expected ${expected}`);
}
}