All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.textmapper.tool.templates.java_ast.ltp Maven / Gradle / Ivy

There is a newer version: 0.10.0
Show newest version
${template unit-}
${if ast.classifiers.select(it|it->kind() != 'enum').size() > 0-}
${call astBaseInterface-}
${call astBaseClass-}
${call astVisitor-}
${end-}
${foreach cl in ast.classifiers-}
${self->ast_classifier(cl)}
${end-}
${if opts.genastdef && self.ast-}
${file opts.prefix+'Ast.last'}${call ast_text.unit}${end-}
${end-}
${end}


${template ast_classifier(cl)-}
${file self->astPath() + cl->className() + '.java'-}
${call java.header-}
package ${self->astPackage()};

${self->('ast_'+cl->kind())(cl)-}
${end-}
${end}


${query kind() =
	self is LiAstEnum ? 'enum' : self.isInterface() ? 'interface' : 'class' }

${cached query className() =
	prefix = (self is LiAstClass && self.isInterface() ? 'I' : '') + context.opts.astprefix,
	util.uniqueId(prefix + util.toCamelCase(self.name, true)->java.escapeJavaReserved(), '__classes__#' + (self.containingClass ? self.containingClass->classInnerName() : '/'))}

${cached query classInnerName() =
	(self.containingClass ? self.containingClass->classInnerName() + '.' : '' ) + self->className()}

${cached query enumMemberName() =
	util.uniqueId(self.name.toUpperCase()->java.escapeJavaReserved(), '__classes__#' + self.containingEnum->classInnerName())}

${cached query propertyName() =
	util.uniqueId(util.toCamelCase(self.name, false)->java.escapeJavaReserved(), '__prop__#' + self.containingClass->classInnerName())}

${query type() =
	context->convertType(self.type)}

${query fieldType() =
	type is PrimitiveType ? (value = type.toString(), value == 'string' ? 'String' : value == 'any' ? 'Object' : value) :
	context->convertType(self.type)
}

${query convertType(asttype) =
	asttype is LiAstList ? 'java.util.@List<' + self->convertType(asttype.inner) + '>' :
	asttype is PrimitiveType ? (
		val = asttype.toString(),
		val == 'boolean' ? 'Boolean':
		val == 'int' ? 'Integer' : 'String') :
	asttype is LiRawAstType ? asttype.rawType :
	asttype is VoidType ? null :
	self->astPackage() + '.@' + asttype->classInnerName()
}

${template implementedInterfaces(cl, prefix)-}
${if cl.super.length > 0-}
 ${prefix} ${foreach impl in cl.super separator ', '}${impl->classInnerName()}${end-}
${else if prefix == 'extends'-}
 extends I${opts.astprefix}Node${end-}
${end}





${template ast_interface(cl)-}
public interface ${cl->className()}${call implementedInterfaces(cl,'extends')} {
}
${end}


${cached query propertyGetter() =
	isBool = type is PrimitiveType && type.toString() == 'boolean',
	noPrefix = isBool && (
		upper_und = util.toUpperWithUnderscores(self->propertyName()),
		upper_und.startsWith('HAS_') || upper_und.startsWith('IS_')),
	suffix = util.toCamelCase(self->propertyName(), !noPrefix),
	prefix = isBool ? (noPrefix ? '' : 'is') : 'get',
	prefix + suffix }

${template ast_class_fields(cl)}${end}

${template ast_class_methods(cl)}${end}

${template ast_class(cl)-}
public class ${cl->className()} extends ${opts.astprefix}Node${call implementedInterfaces(cl,'implements')} {
${if cl.fields}
${end-}
${foreach prop in cl.fields-}
	private final ${prop->fieldType()} ${prop->propertyName()};
${end-}
${call ast_class_fields(cl)-}

	public ${cl->className()}(${foreach prop in cl.fields}${prop->fieldType()} ${prop->propertyName()}, ${end}${call java.package}.${opts.prefix}Tree.@TextSource source${self->util.location(', int ', '', '')}) {
		super(source${self->util.location(', ', '', '')});
${foreach prop in cl.fields-}
		this.${prop->propertyName()} = ${prop->propertyName()};
${end-}
	}
${foreach prop in cl.fields}
	public ${prop->fieldType()} ${prop->propertyGetter()}() {
		return ${prop->propertyName()};
	}
${end-}
${call ast_class_methods(cl)-}
${if true}
	@Override
	public void accept(${opts.astprefix}Visitor v) {
${if cl.fields.select(f|f.type->acceptsVisitor()).size() == 0-}
		v.visit(this);
${else-}
		if (!v.visit(this)) {
			return;
		}
${foreach prop in cl.fields.select(f|f.type->acceptsVisitor())-}
${if prop.type is LiAstList && prop.type.inner is LiAstClass -}
		if (${prop->propertyName()} != null) {
			for (${self->convertType(prop.type.inner)} it : ${prop->propertyName()}) {
				it.accept(v);
			}
		}
${else if prop.type is LiAstClass -}
		if (${prop->propertyName()} != null) {
			${prop->propertyName()}.accept(v);
		}
${else-}
		// TODO for ${prop->propertyName()}
${end-}
${end-}
${end-}
	}
${end-}
${foreach inner in cl.inner}
${util.shiftRight(self->('ast_'+inner->kind())(inner),1)-}
${end-}
}
${end}


${query acceptsVisitor() = self is LiAstClass || self is LiAstList && self.inner->acceptsVisitor()}

${template ast_enum(cl)-}
public enum ${cl->className()} {
${foreach const in cl.members-}
	${const->enumMemberName()},
${end-}
}
${end}



${template astBaseInterface-}
${file self->astPath() + 'I' + opts.astprefix + 'Node.java'-}
${call java.header-}
package ${self->astPackage()};

public interface I${opts.astprefix}Node${call astNodeExtends} {
${if opts.gentree-}
	String getLocation();
${end-}
${foreach l in self->util.locationList()-}
	int get${util.toFirstUpper(l)}();
${end-}
	${call java.package}.${opts.prefix}Tree.@TextSource getSource();
${if opts.gentree-}
	String getResourceName();
	String getText();
${end-}
	void accept(${opts.astprefix}Visitor v);
}
${end-}
${end}


${template astVisitor-}
${file self->astPath() + opts.astprefix + 'Visitor.java'-}
${call java.header-}
package ${self->astPackage()};

public abstract class ${opts.astprefix}Visitor {
${foreach cl in self.ast.classifiers.select(x|x is LiAstClass && !x.isInterface())}
	protected boolean visit(${cl->classInnerName()} n) {
		return true;
	}
${end-}
}
${end-}
${end}


${template astBaseClass-}
${file self->astPath() + opts.astprefix + 'Node.java'-}
${call java.header-}
package ${self->astPackage()};

public abstract class ${opts.astprefix}Node implements I${opts.astprefix}Node {

	protected ${call java.package}.${opts.prefix}Tree.@TextSource source;
${self->util.location('\tprotected int ', ';\n', '')-}

	public ${opts.astprefix}Node(${call java.package}.${opts.prefix}Tree.@TextSource source${self->util.location(', int ', '', '')}) {
		this.source = source;
${foreach l in self->util.locationList()-}
		this.${l} = ${l};
${end-}
	}
${if opts.gentree}
	@Override
	public String getLocation() {
		return source.getLocation(offset);
	}
${end-}
${foreach l in self->util.locationList()}
	@Override
	public int get${util.toFirstUpper(l)}() {
		return this.${l};
	}
${end}
	@Override
	public ${call java.package}.${opts.prefix}Tree.@TextSource getSource() {
		return source;
	}
${if opts.gentree}
	@Override
	public String getResourceName() {
		return source.getFile();
	}

	@Override
	public String getText() {
		return source.getText(offset, endoffset);
	}
${end-}
${if self->util.hasOffsets()}
	@Override
	public String toString() {
		return source == null ? "" : source.getText(offset, endoffset);
	}
${end-}
}
${end-}
${end}

${cached query astcode(rule) =
	nontermType = rule.getLeft().type,
	def = rule.getLeft().definition,
	nontermType is VoidType || nontermType is LiRawAstType ? null :
	def is LiRhsList && nontermType is LiAstList ? rule->codeForList(def) :
	rule->codeForClass()
}

${query codeForList(list) =
    recursive = self.getRight().select(rs|rs.target == list.getLeft()).length != 0,
    prefix = recursive ? (list.isRightRecursive() ? '$$ = $'+(self.getRight().size()-1)+';\n' : '') : '$$ = new java.util.@ArrayList();\n',
	expr = self->asExpression(self.getSource(), self.getLeft().type.inner, true),
    expr == 'null' ? prefix :
    prefix + '${left()}.add(' + expr + ');\n'
}

${query codeForClass() =
	expr = self->asExpression(self.getSource(), self.getLeft().type, false),
	expr == '$0' ? null :
	expr == 'null' && self.getRight().size() == 0 ? null :
    '$$ = ' + expr + ';\n'
}

${query isThisMapping(addOnly) = !mapping.field && mapping.isAddition() == addOnly}

${query asExpression(seq,contextType,addOnly) =
	mapped = self.mappedSymbols(seq),
	mapped.length == 1 && mapped.first() is LiRhsSymbol && mapped.first()->isThisMapping(addOnly) ? self->simpleMapping(mapped.first()) :
	mapped.length == 1 && mapped.first() is LiRhsSequence && mapped.first()->isThisMapping(addOnly) ? self->asExpression(mapped.first(), contextType, addOnly) :
	(type = seq.type ? seq.type : contextType,

	mapped.length == 0 && type is PrimitiveType ? (type.toString() == 'boolean' ? 'false' : type.toString() == 'int' ? '0' : 'null') :
	!self.isMatched(seq) ? 'null' :
	!(type is LiAstClass) ? '/* ERR: unknown type ' + type + ' */' :
	'new ' + self->astPackage() + '.@' + type->classInnerName() + self->ctorArguments(type, mapped))
}

${query simpleMapping(rhsSym) =
	value = rhsSym.mapping.value,
	value || value is Boolean || value is String ? (
        value is LiAstEnumMember ? self->astPackage() + '.@' + value.containingEnum->classInnerName() + '.' + value->enumMemberName() :
		value
	) :
	(
		index = self.sourceSymbols().indexOf(rhsSym),
		index < 0 ? 'null/*ERR: no index*/' : '$' + index
	)
}

${template ctorArguments(cl, mapped)-}
(
${foreach field in cl.fields-}
		${self->fieldValue(field, mapped.select(t|t.mapping.field && t.mapping.field == field))} /* ${field->propertyName()} */,
${end-}
		${call astSource()}${foreach l in self->util.locationList()-}
, ${'$'}{${if getRight().length == 0}left()${else if l.startsWith('end')}last()${else}first()${end}.${l}}${end-}
)${end}

${query fieldValue(field, mapped) =
	mapped.length == 1 && mapped.first() is LiRhsSymbol && !mapped.first().mapping.isAddition() ? self->simpleMapping(mapped.first()) :
	mapped.length > 0
		? '('+mapped.length+') /* ERR: TODO */'
		: (field.type is PrimitiveType ? (field.type.toString() == 'int' ? '0' : 'false') : 'null')
}

${query astPackage() = context->java.package() + (context.opts.astsubpackage ? '.' + context.opts.astsubpackage : '')}

${query astPath() = context.opts.astsubpackage ? context.opts.astsubpackage.replaceAll('\\.','/') + '/' : ''}

${query astSource() = 'null /* input */'}

${query astNodeExtends() = ''}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy