package org.scribble.codegen.java.util; import java.util.Arrays; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.stream.Collectors; public class ClassBuilder extends TypeBuilder { protected String superclass; // null if none explicit protected final List<MethodBuilder> ctors = new LinkedList<>(); // No name par because so far useful to start constructing before setting the name public ClassBuilder() { } public ClassBuilder(String name) { super(name); } public void setSuperClass(String superc) { setterCheck(this.superclass); this.superclass = superc; } // Each par is the String: type + " " + name -- cf. MethodBuilder public ConstructorBuilder newConstructor(String... pars) // FIXME: ConstructorBuilder { ConstructorBuilder mb = new ConstructorBuilder(this.name); mb.addParameters(pars); this.ctors.add(mb); return mb; } public MethodBuilder newMethod() { MethodBuilder mb = new MethodBuilder(); this.methods.add(mb); return mb; } public final MethodBuilder newMethod(String name) { MethodBuilder mb = newMethod(); mb.setName(name); return mb; } public final boolean hasMethodSignature(String ret, String... params) { for (MethodBuilder mb : this.methods) { if (mb.getReturn().equals(ret) && equalParamSigs(Arrays.asList(params), mb.getParameters())) { return true; } } return false; } // FIXME: factor out with TypeBuilder //private static boolean equalParamSigs(MethodBuilder mb1, MethodBuilder mb2) private static boolean equalParamSigs(List<String> mb1, List<String> mb2) { if (mb1.size() == 0) { if (mb2.size() != 0) { return false; } } else { Iterator<String> params2 = mb2.iterator(); for (String param1 : mb1) { if (!params2.hasNext()) { return false; } String param2 = params2.next(); if (param2.contains("<")) { param2 = param2.substring(0, param2.indexOf("<")); } else { param2 = param2.substring(0, param2.indexOf(" ")); } if (param1.contains("<")) { param1 = param1.substring(0, param1.indexOf("<")); } else { param1 = param1.substring(0, param1.indexOf(" ")); } if (!param1.equals(param2)) { return false; } } } return true; } @Override protected String buildSignature(String clazz) { if (!this.mods.isEmpty()) { clazz += this.mods.stream().collect(Collectors.joining(" ")); clazz += " "; } clazz += "class " + this.name; if (!this.params.isEmpty()) { clazz += "<" + this.params.stream().collect(Collectors.joining(", ")) + ">"; } if (this.superclass != null) { clazz += " extends " + this.superclass; } if (!this.ifaces.isEmpty()) { clazz += " implements "; clazz += this.ifaces.stream().collect(Collectors.joining(", ")); } return clazz; } @Override public String buildBody(String clazz) { clazz += " {"; clazz = buildFields(clazz); clazz = buildConstructors(clazz); clazz = buildMethods(clazz); clazz = buildMemberTypes(clazz); clazz += "\n}"; return clazz; } protected String buildConstructors(String clazz) { if (!this.ctors.isEmpty()) { clazz += "\n\n"; clazz += this.ctors.stream().map((mb) -> mb.build()).collect(Collectors.joining("\n\n")); } return clazz; } }