##// END OF EJS Templates
Added childContainer service to container services, ServiceContaier is destroyable, fixed browser Uuid version
Added childContainer service to container services, ServiceContaier is destroyable, fixed browser Uuid version

File last commit:

r115:691199f665e0 ioc ts support
r146:f3f5c56d3b3e v1.4.0-rc5 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}`);
}
}