package sharpen.xobotos.generator; import org.eclipse.jdt.core.dom.ASTNode; import sharpen.core.CSharpBuilder; import sharpen.core.csharp.ast.*; import sharpen.core.framework.CSharpDriver.IBuilderDelegate; import sharpen.xobotos.api.templates.AbstractMemberTemplate; import sharpen.xobotos.output.OutputMode; import sharpen.xobotos.output.OutputType; import java.util.HashMap; import java.util.Map; public abstract class MemberBuilder<T extends ASTNode, U extends CSNode, V extends AbstractMemberTemplate<T, U>> { private final V _template; private final Class<U> _memberType; private final OutputType _outputType; private final T _node; private final Map<ASTNode, MemberBuilder<?, ?, ?>> _members; private U _member; protected MemberBuilder(V template, Class<U> memberType, OutputType output, T node) { this._template = template; this._memberType = memberType; this._outputType = output; this._node = node; _members = new HashMap<ASTNode, MemberBuilder<?, ?, ?>>(); } public V getTemplate() { return _template; } public OutputType getOutputType() { return _outputType; } public OutputMode getOutputMode() { return _outputType.getMode(); } public T getASTNode() { return _node; } public U getMember() { return _member; } public abstract String getNodeName(); public <W extends CSNode> U build(CSharpBuilder builder, IBuilderDelegate<W> delegate) { _member = _template.createCustomMember(_node); if (_member != null) return _member; W member = delegate.create(); if (member == null) return null; this._member = _memberType.cast(member); if (CSMember.class.isInstance(member) && _outputType.removeDocs()) ((CSMember) member).removeDocs(); delegate.map(member); if (!buildInternal(builder, delegate, _member)) { _member = null; return null; } delegate.document(member); delegate.fixup(member); if (!applyActions(_member)) { _member = null; return null; } return _member; } protected abstract boolean buildInternal(CSharpBuilder builder, IBuilderDelegate<?> delegate, U member); protected abstract boolean applyActions(U member); public <X extends ASTNode> void registerMember(X body, MemberBuilder<X, ?, ?> builder) { _members.put(body, builder); } public <X extends ASTNode, Y extends CSNode, Z extends MemberBuilder<X, Y, ?>> Z getMemberBuilder( X body, Class<Z> klass) { MemberBuilder<?, ?, ?> member = _members.get(body); if ((member == null) || !klass.isInstance(member)) return null; return klass.cast(member); } protected void stubBlock(CSBlock block) { block.clearBlock(); CSTypeReference tref = new CSTypeReference("System.NotImplementedException"); CSExpression ctor = new CSConstructorInvocationExpression(tref); CSThrowStatement stm = new CSThrowStatement(block.startPosition(), ctor); block.addStatement(stm); block.setImmutable(); } @Override public String toString() { return String.format("%s(%s:%s)", getClass().getSimpleName(), getNodeName(), _template); } }