Skip to content

Instantly share code, notes, and snippets.

@eutkin
Created October 26, 2018 12:33
Show Gist options
  • Save eutkin/3c305b3f3026eeedfb5c6d13050c0466 to your computer and use it in GitHub Desktop.
Save eutkin/3c305b3f3026eeedfb5c6d13050c0466 to your computer and use it in GitHub Desktop.
reworked common.templ
@includeNamed{'/vertx-java/template/common-lib.templ'}
@code{
/**
* Render a tag link to an html link, this function is used as parameter of the
* renderDocToHtml function when it needs to render tag links.
*/
def renderLinkToHtml(link) {
var rawType = link.targetType.raw;
if (rawType.module != null) {
var label = link.label.trim();
if (rawType.kind == CLASS_DATA_OBJECT) {
return "{@link " + rawType.name + "}";
} else {
if (type.kind == CLASS_API) {
var elt = link.targetElement;
var eltKind = elt.getKind().name();
var ret = "{@link " + rawType.translateName(rxid);
if (eltKind == "METHOD") {
/* todo find a way for translating the complete signature */
ret += "#" + elt.getSimpleName().toString();
}
if (label.length() > 0) {
ret += " " + label;
}
ret += "}";
return ret;
}
}
}
return "{@link " + rawType.name + "}";
}
function genInvokeDelegate(method) {
var ret = '';
if (method.staticMethod) {
ret = helper.getNonGenericType(ifaceFQCN);
if (method.companionMethod) {
ret += '.' + method.companion;
}
} else {
ret = 'delegate';
}
ret += '.' + method.name + '(';
var index = 0;
for (param : method.params) {
if (index > 0) {
ret += ', ';
}
if (param.type.parameterized && param.type.raw.name == 'rx.Observable') {
var adapterFunction = '';
if (param.type.args[0].variable) {
adapterFunction = 'java.util.function.Function.identity()';
} else {
adapterFunction = 'obj -> (' + param.type.args[0].raw.name + ')obj.getDelegate()';
}
ret += 'io.vertx.rx.java.ReadStreamSubscriber.asReadStream(' + param.name + ',' + adapterFunction + ').resume()';
} else if (param.type.parameterized && (param.type.raw.name == 'io.reactivex.Flowable' || param.type.raw.name == 'io.reactivex.Observable')) {
var adapterFunction = '';
if (param.type.args[0].variable) {
adapterFunction = 'java.util.function.Function.identity()';
} else {
adapterFunction = 'obj -> (' + param.type.args[0].raw.name + ')obj.getDelegate()';
}
ret += 'io.vertx.reactivex.core.impl.ReadStreamSubscriber.asReadStream(' + param.name + ',' + adapterFunction + ').resume()';
} else {
ret += genConvParam(param.type, param.name);
}
index = index + 1;
}
ret += ')';
return ret;
}
function isSameType(type) {
var kind = type.kind;
if (kind.basic || kind.json || (kind == CLASS_OBJECT && !type.variable) || kind == CLASS_DATA_OBJECT || kind == CLASS_ENUM || kind == CLASS_OTHER || kind == CLASS_THROWABLE || kind == CLASS_VOID) {
return true;
} else if (kind == CLASS_LIST || kind == CLASS_SET || kind == CLASS_ASYNC_RESULT) {
return isSameType(type.args[0]);
} else if (kind == CLASS_MAP) {
return isSameType(type.args[1]);
}
return false;
}
function genConvParam(type, expr) {
var kind = type.kind;
if (isSameType(type)) {
return expr;
} else if (kind == CLASS_OBJECT) {
if (type.variable) {
var typeArg = genTypeArg(type);
if (typeArg != null) {
return typeArg + '.unwrap(' + expr + ')';
}
}
return expr;
} else if (kind == CLASS_HANDLER) {
var eventType = type.args[0];
if (isSameType(eventType)) {
return expr;
}
var eventKind = eventType.kind;
if (eventKind == CLASS_ASYNC_RESULT) {
var resultType = eventType.args[0];
return 'new Handler<AsyncResult<' + resultType.name + '>>() {\n' +
' public void handle(AsyncResult<' + resultType.name + '> ar) {\n' +
' if (ar.succeeded()) {\n' +
' ' + expr + '.handle(io.vertx.core.Future.succeededFuture(' + genConvReturn(resultType, 'ar.result()') + '));\n' +
' } else {\n' +
' ' + expr + '.handle(io.vertx.core.Future.failedFuture(ar.cause()));\n' +
' }\n' +
' }\n' +
' }';
} else {
return 'new Handler<' + eventType.name + '>() {\n' +
' public void handle(' + eventType.name + ' event) {\n' +
' ' + expr + '.handle(' + genConvReturn(eventType, 'event') + ');\n' +
' }\n' +
' }';
}
} else if (kind == CLASS_FUNCTION) {
var argType = type.args[0];
var retType = type.args[1];
return 'new java.util.function.Function<' + argType.name + ',' + retType.name + '>() {\n' +
' public ' + retType.name + ' apply(' + argType.name + ' arg) {\n' +
' ' + retType.simpleName + ' ret = ' + expr + '.apply(' + genConvReturn(argType, 'arg') + ');\n' +
' return ' + genConvParam(retType, 'ret') + ';\n' +
' }\n' +
' }';
} else if (kind == CLASS_API) {
return expr + '.getDelegate()';
} else if (kind == CLASS_LIST || kind == CLASS_SET) {
return expr + '.stream().map(elt -> ' + genConvParam(type.args[0], 'elt') + ').collect(java.util.stream.Collectors.to' + type.raw.simpleName + '())';
} else if (kind == CLASS_MAP) {
return expr + '.entrySet().stream().collect(java.util.stream.Collectors.toMap(e -> e.getKey(), e -> ' + genConvParam(type.args[1], 'e.getValue()') + '))';
} else if (kind == CLASS_CLASS_TYPE) {
return 'io.vertx.lang.' + rxid + '.Helper.unwrap(' + expr + ')';
}
return expr;
}
function genTypeArg(typeVar) {
if (typeVar.classParam) {
return '__typeArg_' + typeVar.param.index + '';
} else {
var typeArg = method.resolveTypeArg(typeVar);
if (typeArg != null) {
if (typeArg.classType) {
return 'io.vertx.lang.' + rxid + '.TypeArg.of(' + typeArg.param.name + ')';
} else {
return typeArg.param.name + '.__typeArg_' + typeArg.index;
}
}
}
return null;
}
function genConvReturn(type, expr) {
if (type.kind == CLASS_OBJECT) {
if (type.variable) {
var typeArg = genTypeArg(type);
if (typeArg != null) {
return '(' + type.name + ')' + typeArg + '.wrap(' + expr + ')';
}
}
return '(' + type.simpleName + ') ' + expr;
} else if (isSameType(type)) {
return expr;
} else if (type.kind == CLASS_API) {
var tmp = new StringBuilder(type.raw.simpleName);
tmp.append('.newInstance(');
tmp.append(expr);
if (type.parameterized) {
for (arg : type.args) {
tmp.append(', ');
if (arg.kind == CLASS_API) {
tmp.append(arg.translateName(rxid)).append('.__TYPE_ARG');
} else {
var typeArg = 'io.vertx.lang.' + rxid + '.TypeArg.unknown()';
if (arg.kind == CLASS_OBJECT && arg.variable) {
var resolved = genTypeArg(arg);
if (resolved != null) {
typeArg = resolved;
}
}
tmp.append(typeArg);
}
}
}
tmp.append(')');
return tmp.toString();
} else if (type.kind == CLASS_HANDLER) {
var abc = type.args[0];
if (abc.kind == CLASS_ASYNC_RESULT) {
var tutu = abc.args[0];
return 'new Handler<AsyncResult<' + tutu.simpleName + '>>() {\n' +
' public void handle(AsyncResult<' + tutu.simpleName + '> ar) {\n' +
' if (ar.succeeded()) {\n' +
' ' + expr + '.handle(io.vertx.core.Future.succeededFuture(' + genConvParam(tutu, 'ar.result()') + '));\n' +
' } else {\n' +
' ' + expr + '.handle(io.vertx.core.Future.failedFuture(ar.cause()));\n' +
' }\n' +
' }\n' +
' }';
} else {
return 'new Handler<' + abc.simpleName + '>() {\n' +
' public void handle(' + abc.simpleName + ' event) {\n' +
' ' + expr + '.handle(' + genConvParam(abc, 'event') + ');\n' +
' }\n' +
' }';
}
} else if (type.kind == CLASS_LIST || type.kind == CLASS_SET) {
return expr + '.stream().map(elt -> ' + genConvReturn(type.args[0], 'elt') + ').collect(java.util.stream.Collectors.to' + type.raw.simpleName + '())';
}
return expr;
}
def hasReadStream(method) {
for (param : method.params) {
if (param.type.parameterized && param.type.raw.name == 'io.vertx.core.streams.ReadStream') {
return true;
}
}
return false;
}
def genOptTypeParamsDecl(type, deflt) {
if (type.params.size() > 0) {
var s = new java.lang.StringBuilder();
var sep = '<';
for (param : type.params) {
s.append(sep);
s.append(param.name);
sep = ',';
}
s.append('>');
return s.toString();
} else {
return deflt;
}
}
def hasToString(methods) {
for (method : methods) {
if (method.name == 'toString' && method.params.isEmpty()) {
return true;
}
}
return false;
}
}
@declare{'startMethodTemplate'}
@if{meth.doc != null}
/**\n
@{renderDocToHtml(" *", meth.doc, renderLinkToHtml)}
@foreach{param: meth.params}
* @param @{param.name} @if{param.description != null}@{renderTokensToHtml("", param.description.tokens, renderLinkToHtml, "")}@end{}\n
@end{}
@if{!meth.returnType.name.equals("void")}
* @return @if{meth.returnDescription != null}@{renderTokensToHtml("", meth.returnDescription.tokens, renderLinkToHtml, "")}@end{}\n
@end{}
@if{deprecated != null && deprecated.length() > 0}
* @deprecated @{deprecated}\n
@end{}
*/\n
@end{}
@if{deprecated != null && deprecated.length() > 0}
@Deprecated()\n
@end{}
public @if{meth.staticMethod}static @end{}@if{meth.typeParams.size() > 0}<@foreach{typeParam:meth.typeParams}@{typeParam.name}@end{', '}> @end{}@{meth.returnType.simpleName} @{meth.name}(@foreach{param: meth.params}@{param.type.simpleName} @{param.name}@end{', '})
@end{}
@declare{'genSimpleMethod'}
@includeNamed{'startMethodTemplate';meth=method;deprecated=''} { \n
@if{method.fluent}
@{genInvokeDelegate(method)};\n
@if{method.returnType.variable}
return (@{method.returnType.name}) this;\n
@else{}
return this;\n
@end{}
@else{method.returnType.name.equals('void')}
@{genInvokeDelegate(method)};\n
@else{}
@if{method.cacheReturn}
if (cached_@{cacheDecls.size()} != null) {\n
return cached_@{cacheDecls.size()};\n
}\n
@end{}
@if{method.returnType.kind == CLASS_PRIMITIVE}
@code{cachedType=method.returnType.boxed.name}
@else{}
@code{cachedType=method.returnType.simpleName}
@end{}
@{method.returnType.simpleName} ret = @{genConvReturn(method.returnType, genInvokeDelegate(method))};\n
@if{method.cacheReturn}
cached_@{cacheDecls.size()} = ret;\n
@code{cacheDecls.add('private' + (method.staticMethod ? ' static' : '') + ' ' + cachedType + ' cached_' + cacheDecls.size())}
@end{}
return ret;\n
@end{}
}\n\n
@end{}
@declare{'genMethod'}
@includeNamed{'genSimpleMethod'}
@if{method.kind == METHOD_FUTURE}
@includeNamed{'genRxMethod'}
@end{}
@end{}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment