/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (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.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is HTML Parser C++ Translator code. * * The Initial Developer of the Original Code is * Mozilla Foundation. * Portions created by the Initial Developer are Copyright (C) 2008 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Henri Sivonen <hsivonen@iki.fi> * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ package nu.validator.htmlparser.cpptranslate; import java.util.LinkedList; import java.util.List; import japa.parser.ast.body.FieldDeclaration; import japa.parser.ast.body.MethodDeclaration; import japa.parser.ast.body.ModifierSet; import japa.parser.ast.body.Parameter; import japa.parser.ast.body.VariableDeclarator; import japa.parser.ast.expr.IntegerLiteralExpr; import japa.parser.ast.expr.MethodCallExpr; import japa.parser.ast.stmt.BlockStmt; import japa.parser.ast.type.PrimitiveType; import japa.parser.ast.type.ReferenceType; import japa.parser.ast.type.Type; public class HVisitor extends CppVisitor { private enum Visibility { NONE, PRIVATE, PUBLIC, PROTECTED, } private Visibility previousVisibility = Visibility.NONE; private List<String> defines = new LinkedList<String>(); /** * @see nu.validator.htmlparser.cpptranslate.CppVisitor#printMethodNamespace() */ @Override protected void printMethodNamespace() { } public HVisitor(CppTypes cppTypes, SymbolTable symbolTable) { super(cppTypes, symbolTable); } /** * @see nu.validator.htmlparser.cpptranslate.CppVisitor#startClassDeclaration() */ @Override protected void startClassDeclaration() { printer.print("#ifndef "); printer.print(className); printer.printLn("_h"); printer.print("#define "); printer.print(className); printer.printLn("_h"); printer.printLn(); String[] incs = cppTypes.boilerplateIncludes(javaClassName); for (int i = 0; i < incs.length; i++) { String inc = incs[i]; if (className.equals(inc)) { continue; } printer.print("#include \""); printer.print(inc); printer.printLn(".h\""); } printer.printLn(); String[] forwDecls = cppTypes.boilerplateForwardDeclarations(); for (int i = 0; i < forwDecls.length; i++) { String decl = forwDecls[i]; printer.print("class "); printer.print(decl); printer.printLn(";"); } printer.printLn(); for (int i = 0; i < Main.H_LIST.length; i++) { String klazz = Main.H_LIST[i]; if (!(klazz.equals(javaClassName) || klazz.equals("StackNode"))) { printer.print("class "); printer.print(cppTypes.classPrefix()); printer.print(klazz); printer.printLn(";"); } } printer.printLn(); String[] otherDecls = cppTypes.boilerplateDeclarations(javaClassName); for (int i = 0; i < otherDecls.length; i++) { String decl = otherDecls[i]; printer.printLn(decl); } printer.printLn(); printer.print("class "); printer.print(className); if ("StateSnapshot".equals(javaClassName) || "TreeBuilder".equals(javaClassName)) { printer.print(" : public "); printer.print(cppTypes.treeBuilderStateInterface()); } printer.printLn(); printer.printLn("{"); printer.indent(); printer.indent(); } /** * @see nu.validator.htmlparser.cpptranslate.CppVisitor#endClassDeclaration() */ @Override protected void endClassDeclaration() { printModifiers(ModifierSet.PUBLIC | ModifierSet.STATIC); printer.printLn("void initializeStatics();"); printModifiers(ModifierSet.PUBLIC | ModifierSet.STATIC); printer.printLn("void releaseStatics();"); printer.unindent(); printer.unindent(); if (cppTypes.hasSupplement(javaClassName)) { printer.printLn(); printer.print("#include \""); printer.print(className); printer.printLn("HSupplement.h\""); } printer.printLn("};"); printer.printLn(); for (String define : defines) { printer.printLn(define); } printer.printLn(); printer.printLn(); printer.printLn("#endif"); } /** * @see nu.validator.htmlparser.cpptranslate.CppVisitor#printModifiers(int) */ @Override protected void printModifiers(int modifiers) { if (ModifierSet.isPrivate(modifiers)) { if (previousVisibility != Visibility.PRIVATE) { printer.unindent(); printer.printLn("private:"); printer.indent(); previousVisibility = Visibility.PRIVATE; } } else if (ModifierSet.isProtected(modifiers)) { if (previousVisibility != Visibility.PROTECTED) { printer.unindent(); printer.printLn("protected:"); printer.indent(); previousVisibility = Visibility.PROTECTED; } } else { if (previousVisibility != Visibility.PUBLIC) { printer.unindent(); printer.printLn("public:"); printer.indent(); previousVisibility = Visibility.PUBLIC; } } if (inline()) { printer.print("inline "); } if (virtual()) { printer.print("virtual "); } if (ModifierSet.isStatic(modifiers)) { printer.print("static "); } } /** * @see nu.validator.htmlparser.cpptranslate.CppVisitor#fieldDeclaration(japa.parser.ast.body.FieldDeclaration, java.lang.LocalSymbolTable) */ @Override protected void fieldDeclaration(FieldDeclaration n, LocalSymbolTable arg) { int modifiers = n.getModifiers(); List<VariableDeclarator> variables = n.getVariables(); VariableDeclarator declarator = variables.get(0); if (ModifierSet.isStatic(modifiers) && ModifierSet.isFinal(modifiers) && n.getType() instanceof PrimitiveType) { PrimitiveType type = (PrimitiveType) n.getType(); if (type.getType() != PrimitiveType.Primitive.Int) { throw new IllegalStateException( "Only int constant #defines supported."); } if (variables.size() != 1) { throw new IllegalStateException( "More than one variable declared by one declarator."); } String name = javaClassName + "." + declarator.getId().getName(); String value = declarator.getInit().toString(); if ("Integer.MAX_VALUE".equals(value)) { value = cppTypes.maxInteger(); } String longName = definePrefix + declarator.getId().getName(); if (symbolTable.cppDefinesByJavaNames.containsKey(name)) { throw new IllegalStateException( "Duplicate #define constant local name: " + name); } symbolTable.cppDefinesByJavaNames.put(name, longName); defines.add("#define " + longName + " " + value); } else { if (n.getType() instanceof ReferenceType) { ReferenceType rt = (ReferenceType) n.getType(); currentArrayCount = rt.getArrayCount(); if (currentArrayCount > 0 && (rt.getType() instanceof PrimitiveType) && declarator.getInit() != null) { if (!ModifierSet.isStatic(modifiers)) { throw new IllegalStateException( "Non-static array case not supported here." + declarator); } if (noLength()) { inPrimitiveNoLengthFieldDeclarator = true; } } } printModifiers(modifiers); inStatic = ModifierSet.isStatic(modifiers); n.getType().accept(this, arg); printer.print(" "); if (ModifierSet.isStatic(modifiers)) { if ("AttributeName".equals(n.getType().toString())) { printer.print("ATTR_"); } else if ("ElementName".equals(n.getType().toString())) { printer.print("ELT_"); } } declarator.getId().accept(this, arg); printer.printLn(";"); currentArrayCount = 0; inStatic = false; inPrimitiveNoLengthFieldDeclarator = false; } } /** * @see nu.validator.htmlparser.cpptranslate.CppVisitor#printConstructorExplicit(java.util.List<japa.parser.ast.body.Parameter>) */ @Override protected void printConstructorExplicit(List<Parameter> params) { if (params != null && params.size() == 1) { printer.print("explicit "); } } /** * @see nu.validator.htmlparser.cpptranslate.CppVisitor#printConstructorBody(japa.parser.ast.stmt.BlockStmt, java.lang.LocalSymbolTable) */ @Override protected void printConstructorBody(BlockStmt block, LocalSymbolTable arg) { printer.printLn(";"); } /** * @see nu.validator.htmlparser.cpptranslate.CppVisitor#visit(japa.parser.ast.body.MethodDeclaration, java.lang.LocalSymbolTable) */ @Override public void visit(MethodDeclaration n, LocalSymbolTable arg) { arg = new LocalSymbolTable(javaClassName, symbolTable); printMethodDeclaration(n, arg); } /** * @see nu.validator.htmlparser.cpptranslate.CppVisitor#inHeader() */ @Override protected boolean inHeader() { return true; } }