Java tutorial
/* * Copyright (C) 2008 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.gxp.compiler.cpp; import com.google.common.base.Function; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.gxp.compiler.alerts.AlertSink; import com.google.gxp.compiler.alerts.SourcePosition; import com.google.gxp.compiler.base.Callable; import com.google.gxp.compiler.base.Constructor; import com.google.gxp.compiler.base.Parameter; import com.google.gxp.compiler.base.Interface; import com.google.gxp.compiler.base.Template; import com.google.gxp.compiler.base.TemplateName; import com.google.gxp.compiler.msgextract.MessageExtractedTree; import java.util.List; import java.util.Set; /** * C++ Header {@code CodeGenerator}. */ public class CppHeaderCodeGenerator extends BaseCppCodeGenerator<MessageExtractedTree> { private final ImmutableSet<TemplateName> extraIncludess; public CppHeaderCodeGenerator(MessageExtractedTree tree, Set<Callable> requirements) { super(tree); // unlike java, you have to include the header file for anything you depend on, // you can't just fully qualify the class name, so build up a list of extra includes this.extraIncludess = ImmutableSet .copyOf(Iterables.transform(requirements, new Function<Callable, TemplateName>() { public TemplateName apply(Callable requirement) { return requirement.getName(); } })); } protected InterfaceWorker createInterfaceWorker(Appendable out, AlertSink alertSink, Interface iface) { return new InterfaceWorker(out, alertSink, iface, extraIncludess); } private static class InterfaceWorker extends BaseCppCodeGenerator.InterfaceWorker { private final ImmutableSet<TemplateName> extraIncludess; public InterfaceWorker(Appendable out, AlertSink alertSink, Interface iface, Set<TemplateName> extraIncludess) { super(out, alertSink, iface); this.extraIncludess = ImmutableSet.copyOf(extraIncludess); } protected void appendClass() { TemplateName ifaceName = iface.getName(); appendIfdefGuardStart(iface); appendLine(); appendLine("#include \"gxp/base/base.h\""); appendImports(iface, extraIncludess); appendLine(); appendNamespacesOpen(ifaceName); formatLine(iface.getSourcePosition(), "class %s {", getClassName(ifaceName)); appendLine("public:"); appendLine("};"); appendNamespacesClose(ifaceName); appendLine(); appendIfdefGuardEnd(iface); } } protected TemplateWorker createTemplateWorker(Appendable out, AlertSink alertSink, Template template) { return new TemplateWorker(out, alertSink, template, extraIncludess); } private static class TemplateWorker extends BaseCppCodeGenerator.TemplateWorker { private final ImmutableSet<TemplateName> extraIncludess; public TemplateWorker(Appendable out, AlertSink alertSink, Template template, Set<TemplateName> extraIncludess) { super(out, alertSink, template); this.extraIncludess = ImmutableSet.copyOf(extraIncludess); } protected void appendClass() { SourcePosition pos = template.getSourcePosition(); TemplateName templateName = template.getName(); appendIfdefGuardStart(template); appendLine(); appendLine("#include \"gxp/base/base.h\""); appendImports(template, extraIncludess); appendLine(); appendNamespacesOpen(templateName); formatLine(pos, "class %s : public GxpTemplate {", getClassName(templateName)); appendLine("public:"); appendLine(pos, getWriteMethodSignature(false, true) + ";"); appendLine(); appendLine(pos, getGetGxpClosureMethodSignature(false, true) + ";"); appendLine(); appendExtraWriteMethods(true); appendLine(); appendInterface(); appendLine(); appendInstance(); appendLine("};"); appendNamespacesClose(templateName); appendLine(); appendIfdefGuardEnd(template); } protected void appendExtraWriteMethods(boolean isStatic) { SourcePosition pos = template.getSourcePosition(); Iterable<Parameter> params = isStatic ? template.getAllParameters() : template.getParameters(); for (ExtraOutType extraOutType : extraOutTypes) { appendLine(pos, getWriteMethodSignature(extraOutType.getOutType(), false, isStatic) + " {"); formatLine(pos, "%s gxp_wrapper(%s);", extraOutType.getOutWrapper(), GXP_OUT_VAR); StringBuilder sb = new StringBuilder("Write("); COMMA_JOINER.appendTo(sb, Iterables.concat(ImmutableSet.of("&gxp_wrapper, " + GXP_CONTEXT_VAR), Iterables.transform(params, paramToCallName))); sb.append(");"); appendLine(pos, sb); appendLine("}"); } } protected void appendInterface() { SourcePosition pos = template.getSourcePosition(); appendLine("//"); appendLine("// Interface that defines a strategy for writing this GXP"); appendLine("//"); appendCppFormalTypeParameters(true, template.getFormalTypeParameters()); appendLine("class Interface {"); appendLine("public:"); appendLine(pos, "virtual ~Interface() {}"); appendLine(pos, "virtual " + getWriteMethodSignature(false, false) + " = 0;"); appendLine(pos, "virtual " + getGetGxpClosureMethodSignature(false, false) + " = 0;"); appendLine(); appendExtraWriteMethods(false); appendLine("};"); } protected void appendInstance() { StringBuilder sb; Constructor constructor = template.getConstructor(); List<Parameter> cParams = constructor.getParameters(); SourcePosition pos = constructor.getSourcePosition(); appendLine("//"); appendLine("// Instantiable instance of this GXP"); appendLine("//"); appendCppFormalTypeParameters(true, template.getFormalTypeParameters()); sb = new StringBuilder("class Instance : public Interface"); appendCppFormalTypeParameters(sb, false, template.getFormalTypeParameters()); sb.append(" {"); appendLine(pos, sb); appendLine("public:"); sb = new StringBuilder("Instance("); COMMA_JOINER.appendTo(sb, Iterables.transform(cParams, parameterToCallName)); sb.append(")"); if (!cParams.isEmpty()) { sb.append("\n : "); COMMA_JOINER.appendTo(sb, Iterables.transform(cParams, parameterToInitializer)); } sb.append(" {"); appendLine(sb); appendLine("}"); appendLine(); appendLine(getWriteMethodSignature(false, false) + " {"); sb = new StringBuilder(getClassName(template.getName())); sb.append("::Write("); COMMA_JOINER.appendTo(sb, Iterables.concat(ImmutableSet.of(GXP_OUT_VAR + ", " + GXP_CONTEXT_VAR), Iterables.transform(template.getAllParameters(), paramToCallName))); sb.append(");"); appendLine(pos, sb); appendLine("}"); appendLine(); appendLine(null, getGetGxpClosureMethodSignature(false, false) + " {"); sb = new StringBuilder("return "); sb.append(getClassName(template.getName())); sb.append("::GetGxpClosure("); COMMA_JOINER.appendTo(sb, Iterables.transform(template.getAllParameters(), paramToCallName)); sb.append(");"); appendLine(pos, sb); appendLine("}"); if (!cParams.isEmpty()) { appendLine("private:"); for (Parameter param : cParams) { formatLine(param.getSourcePosition(), "%s %s;", toCppType(param.getType()), param.getPrimaryName()); } } appendLine("};"); } } }