/**
* Copyright 2004-2016 Riccardo Solmi. All rights reserved.
* This file is part of the Whole Platform.
*
* The Whole Platform is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Whole Platform is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the Whole Platform. If not, see <http://www.gnu.org/licenses/>.
*/
package org.whole.gen;
import java.util.Iterator;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.IfStatement;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.SuperMethodInvocation;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword;
import org.whole.lang.util.StringUtils;
/**
* @author Riccardo Solmi
*/
public class JavaStoreGeneratorVisitorBuilder extends CompilationUnitBuilder {
public JavaStoreGeneratorVisitorBuilder(JavaModelGenerator generator, String packageSuffix, String entityInterfaceName, CompilationUnit visitorCU, TypeDeclaration languageFactoryType) {
super(generator, packageSuffix);
MethodInvocation callExp;
MethodInvocation callExp2;
FieldDeclaration fieldDec;
addImplementationType(generator.javaStoreVisitorName(), visitorCU);
setSuperclass(generator.identityVisitorName());
noImportPackage("org.eclipse.jdt.core.dom");
Iterator i = typeDec.bodyDeclarations().iterator();
while (i.hasNext()) {
Object declaration = i.next();
if (declaration instanceof MethodDeclaration) {
MethodDeclaration visitMethod = (MethodDeclaration)declaration;
SingleVariableDeclaration paramDec = (SingleVariableDeclaration)visitMethod.parameters().get(0);
String visitType = paramDec.getType().toString();
String visitName = paramDec.getName().getIdentifier();
if (visitType.endsWith(StringUtils.toSimpleName(generator.adapterFragmentName()))) {
//super.visit(fragment);
SuperMethodInvocation superCall = newSuperMethodInvocation("visit");
superCall.arguments().add(ast.newSimpleName("entity"));
//builder.addSubtree(this, fragment, fragmentAdapterName);
callExp2 = newMethodInvocation("builder", "addSubtree");
callExp2.arguments().add(ast.newThisExpression());
callExp2.arguments().add(ast.newSimpleName("entity"));
callExp2.arguments().add(newLiteral(StringUtils.toSimpleName(generator.adapterFragmentName())));
IfStatement ifStm = newIfStatement(
ast.newSimpleName("isCompiling"),
newExpressionStatement(superCall),
newExpressionStatement(callExp2));
visitMethod.getBody().statements().add(ifStm);
continue;
} else if (visitType.endsWith(StringUtils.toSimpleName(generator.baseFragmentName()))) {
//super.visit(fragment);
SuperMethodInvocation superCall = newSuperMethodInvocation("visit");
superCall.arguments().add(ast.newSimpleName("entity"));
//builder.addSubtree(this, fragment, baseFragmentName);
callExp2 = newMethodInvocation("builder", "addSubtree");
callExp2.arguments().add(ast.newThisExpression());
callExp2.arguments().add(ast.newSimpleName("entity"));
callExp2.arguments().add(newLiteral(StringUtils.toSimpleName(generator.baseFragmentName())));
IfStatement ifStm = newIfStatement(
ast.newSimpleName("isCompiling"),
newExpressionStatement(superCall),
newExpressionStatement(callExp2));
visitMethod.getBody().statements().add(ifStm);
continue;
} else if (visitType.endsWith(StringUtils.toSimpleName(generator.metaFragmentName()))) {
//builder.addSubtree(this, fragment, metaFragmentName);
callExp = newMethodInvocation("builder", "addSubtree");
callExp.arguments().add(ast.newThisExpression());
callExp.arguments().add(ast.newSimpleName("entity"));
callExp.arguments().add(newLiteral(StringUtils.toSimpleName(generator.metaFragmentName())));
visitMethod.getBody().statements().add(newExpressionStatement(callExp));
continue;
}
String factoryName = "create"+visitType;
MethodDeclaration factoryMethod;
try {
factoryMethod = findMethodDeclaration(factoryName, languageFactoryType.bodyDeclarations());
} catch (MethodNotFoundException e) {
continue;
}
String componentType = generator.getComponentType(visitType);
boolean isComposite = componentType != null;
//int parentNestingSize = builder.initNestingSize();
visitMethod.getBody().statements().add(newVariableDeclarationStatement("int", "parentNestingSize", newMethodInvocation("builder", "initNestingSize")));
//MethodInvocation callExp = builder.newFactoryInvocation(this, factoryName);
callExp = newMethodInvocation("builder", "newFactoryInvocation");
callExp.arguments().add(ast.newThisExpression());
callExp.arguments().add(newLiteral(factoryName));
visitMethod.getBody().statements().add(newVariableDeclarationStatement("org.eclipse.jdt.core.dom.MethodInvocation", "callExp", callExp));
Iterator j = factoryMethod.parameters().iterator();
while (j.hasNext()) {
SingleVariableDeclaration paramDec2 = (SingleVariableDeclaration)j.next();
String paramType = paramDec2.getType().toString();
String paramName = paramDec2.getName().getIdentifier();
if (isComposite) {
//ArrayInitializer initArrayExp = builder.newArrayInitializer();
visitMethod.getBody().statements().add(newVariableDeclarationStatement("org.eclipse.jdt.core.dom.ArrayInitializer", "initArrayExp", newMethodInvocation("builder", "newArrayInitializer")));
//builder.newArrayCreation(componentType, initArrayExp);
callExp = newMethodInvocation("builder", "newArrayCreation");
callExp.arguments().add(newLiteral(componentType));
callExp.arguments().add(ast.newSimpleName("initArrayExp"));
//callExp.arguments().add(callExp);
callExp2 = newMethodInvocation(newMethodInvocation("callExp", "arguments"), "add");
callExp2.arguments().add(callExp);
visitMethod.getBody().statements().add(ast.newExpressionStatement(callExp2));
//List list = initArrayExp.expressions();
VariableDeclarationStatement varDecStm = newVariableDeclarationStatement("java.util.List", "list", newMethodInvocation("initArrayExp", "expressions"));
visitMethod.getBody().statements().add(varDecStm);
//for (int i=0; i<entity.wSize(); i++)
// list.add(astOf((entityInterfaceName) entity.wGet(i)));
addStatement(visitMethod, newForStatement(
newVariableDeclarationExpression("int", "i", newLiteral(0)),
newInfixExpression(ast.newSimpleName("i"), "<", newMethodInvocation(visitName, "wSize")),
newPostfixExpression(ast.newSimpleName("i"), "++"),
newExpressionStatement(
newMethodInvocation("list", "add", newMethodInvocation("astOf", newCastExpression(generator.specificEntityInterfaceName(),
newMethodInvocation(visitName, "wGet", ast.newSimpleName("i"))))))));
} else {
//builder.newLiteral(entity.getField()) oppure astOf(entity.getField());
MethodInvocation callExp4 = (StringUtils.isPrimitiveOrString(paramType) || paramType.endsWith("Enum.Value")) ? newMethodInvocation("builder", "newLiteral") : newMethodInvocation("astOf");
callExp4.arguments().add(newMethodInvocation(visitName, StringUtils.getterName(paramType, paramName)));
//callExp.arguments().add(fieldExp);
callExp2 = newMethodInvocation(newMethodInvocation("callExp", "arguments"), "add");
callExp2.arguments().add(callExp4);
visitMethod.getBody().statements().add(ast.newExpressionStatement(callExp2));
};
}
//builder.addSubtree(parentNestingSize, visitType, callExp);
callExp = newMethodInvocation("builder", "addSubtree");
callExp.arguments().add(ast.newSimpleName("parentNestingSize"));
callExp.arguments().add(newLiteral(visitType));
callExp.arguments().add(ast.newSimpleName("callExp"));
visitMethod.getBody().statements().add(newExpressionStatement(callExp));
}
}
//add builder field
addBodyDeclaration(0, fieldDec = newFieldDeclaration(JavaStoreBuilder.class.getName(), "builder"));
fieldDec.modifiers().add(ast.newModifier(ModifierKeyword.FINAL_KEYWORD));
//add isCompiling field
addBodyDeclaration(1, fieldDec = newFieldDeclaration("boolean", "isCompiling"));
fieldDec.modifiers().add(ast.newModifier(ModifierKeyword.FINAL_KEYWORD));
//add astOf method
methodDec = newMethodDeclaration("org.eclipse.jdt.core.dom.Expression", "astOf");
methodDec.modifiers().remove(0);//assume ModifierKeyword.PUBLIC_KEYWORD
methodDec.modifiers().add(ast.newModifier(ModifierKeyword.PRIVATE_KEYWORD));
methodDec.modifiers().add(ast.newModifier(ModifierKeyword.FINAL_KEYWORD));
methodDec.parameters().add(newSingleVariableDeclaration(entityInterfaceName, "entity"));
addBodyDeclaration(2, methodDec);
//entity.accept(this);
callExp = newMethodInvocation("entity", "accept");
callExp.arguments().add(ast.newThisExpression());
methodDec.getBody().statements().add(ast.newExpressionStatement(callExp));
//return builder.getExpression();
methodDec.getBody().statements().add(newReturnStatement(newMethodInvocation("builder", "getExpression")));
//add astOf method
methodDec = newMethodDeclaration("org.eclipse.jdt.core.dom.Expression", "astOf");
methodDec.modifiers().remove(0);//assume ModifierKeyword.PUBLIC_KEYWORD
methodDec.modifiers().add(ast.newModifier(ModifierKeyword.PROTECTED_KEYWORD));
methodDec.parameters().add(newSingleVariableDeclaration("Object", "entity"));
addBodyDeclaration(3, methodDec);
//return builder.newNullLiteral();
methodDec.getBody().statements().add(newReturnStatement(newMethodInvocation("builder", "newNullLiteral")));
//add constructor
methodDec = newConstructorDeclaration(generator.javaStoreVisitorName());
methodDec.parameters().add(newSingleVariableDeclaration(JavaStoreBuilder.class.getName(), "builder"));
methodDec.parameters().add(newSingleVariableDeclaration("boolean", "isCompiling"));
addBodyDeclaration(2, methodDec);
//this.builder = builder
methodDec.getBody().statements().add(ast.newExpressionStatement(newAssignment(newFieldAccess(ast.newThisExpression(), "builder"), ast.newSimpleName("builder"))));
//this.builder = builder
methodDec.getBody().statements().add(ast.newExpressionStatement(newAssignment(newFieldAccess(ast.newThisExpression(), "isCompiling"), ast.newSimpleName("isCompiling"))));
//builder.addLanguageFactory(factoryName);
String languageFactoryName = generator.packagePrefix+".model."+languageFactoryType.getName().getFullyQualifiedName();
callExp = newMethodInvocation("builder", "addLanguageFactory");
callExp.arguments().add(ast.newThisExpression());
callExp.arguments().add(newLiteral(languageFactoryName));
methodDec.getBody().statements().add(ast.newExpressionStatement(callExp));
}
}