package apet.absunit; import static abs.backend.tests.AbsASTBuilderUtil.createMethodSig; import static abs.backend.tests.AbsASTBuilderUtil.getUnit; import static abs.backend.tests.AbsASTBuilderUtil.getVAssign; import static apet.absunit.ABSUnitTestCaseTranslatorConstants.RUN_METHOD; import java.util.Map; import java.util.Set; import abs.frontend.ast.Access; import abs.frontend.ast.AddInterfaceModifier; import abs.frontend.ast.AddMethodModifier; import abs.frontend.ast.Annotation; import abs.frontend.ast.Block; import abs.frontend.ast.ClassDecl; import abs.frontend.ast.DeltaAccess; import abs.frontend.ast.DeltaDecl; import abs.frontend.ast.Exp; import abs.frontend.ast.FieldDecl; import abs.frontend.ast.FieldUse; import abs.frontend.ast.InterfaceDecl; import abs.frontend.ast.InterfaceTypeUse; import abs.frontend.ast.MethodImpl; import abs.frontend.ast.MethodSig; import abs.frontend.ast.ModifyClassModifier; import abs.frontend.ast.ParamDecl; import abs.frontend.ast.RemoveMethodModifier; import abs.frontend.ast.ReturnStmt; import abs.frontend.ast.VarUse; final class DeltaForGetSetFieldsBuilder { private final TestCaseNamesBuilder testCaseNameBuilder = new TestCaseNamesBuilder(); private final Set<DeltaWrapper> deltas; static class DeltaWrapper { private final DeltaDecl delta; private final boolean last; DeltaWrapper(DeltaDecl delta, boolean last) { this.delta = delta; this.last = last; } boolean isLast() { return last; } DeltaDecl getDelta() { return delta; } } DeltaForGetSetFieldsBuilder(Set<DeltaWrapper> deltas) { this.deltas = deltas; } DeltaDecl getDelta(String deltaName) { for (DeltaWrapper d : deltas) { DeltaDecl dd = d.getDelta(); if (deltaName.equals(dd.getName())) { return dd; } } return null; } DeltaDecl getDeltaFor(String testClassName) { String deltaName = testCaseNameBuilder.deltaOnClass(testClassName); return getDelta(deltaName); } DeltaDecl createDeltaFor(ClassDecl testClass) { String deltaName = testCaseNameBuilder.deltaOnClass(testClass.getName()); DeltaDecl delta = new DeltaDecl(); delta.setName(deltaName); delta.addDeltaAccess(new DeltaAccess(testClass.getModuleDecl().getName())); deltas.add(new DeltaWrapper(delta, true)); return delta; } RemoveMethodModifier removeRun() { RemoveMethodModifier modifier = new RemoveMethodModifier(new abs.frontend.ast.List<>(createMethodSig(RUN_METHOD, getUnit()))); return modifier; } /** * Add an add method modifier * @param fieldName * @param exp * @param decl * @return */ AddMethodModifier addSetter( String fieldName, Access type) { MethodSig sig = new MethodSig(testCaseNameBuilder.setterMethodName(fieldName), new abs.frontend.ast.List<Annotation>(), getUnit(), new abs.frontend.ast.List<ParamDecl>()); sig.addParam(new ParamDecl("v", type, new abs.frontend.ast.List<Annotation>())); Block block = new Block(); block.addStmtNoTransform(getVAssign(new FieldUse(fieldName), new VarUse("v"))); MethodImpl method = new MethodImpl(sig, block, false); AddMethodModifier modifier = new AddMethodModifier(method); return modifier; } AddMethodModifier addGetter(String fieldName, Access returnType) { Exp returnExp = new FieldUse(fieldName); return addGetter(returnExp, fieldName, returnType); } AddMethodModifier addGetter(Exp returnValue, String fieldName, Access returnType) { MethodSig sig = new MethodSig(testCaseNameBuilder.getterMethodName(fieldName), new abs.frontend.ast.List<Annotation>(), returnType, new abs.frontend.ast.List<ParamDecl>()); Block block = new Block(); ReturnStmt rs = new ReturnStmt(); rs.setRetExp(new FieldUse(fieldName)); block.addStmtNoTransform(rs); MethodImpl method = new MethodImpl(sig, block, false); AddMethodModifier modifier = new AddMethodModifier(method); return modifier; } /** * Add a delta that adds Getters and Setters for clazz. * * @param extensions * @param interf * @param clazz * */ void updateDelta(Map<String, String> typeHierarchy, InterfaceTypeUse interf, ClassDecl clazz) { String className = clazz.getName(); String deltaOnClassName = testCaseNameBuilder.deltaOnClass(className); String interfaceForModifyingClassFieldName = testCaseNameBuilder.interfaceForModifyingFieldOfClass(className); DeltaDecl dd = getDelta(deltaOnClassName); if (dd != null) { typeHierarchy.put(interf.getName(), interfaceForModifyingClassFieldName); return; } dd = new DeltaDecl(); dd.setName(deltaOnClassName); dd.addDeltaAccess(new DeltaAccess(clazz.getModuleDecl().getName())); //add Setters and Getters ModifyClassModifier mcm = new ModifyClassModifier(); mcm.setName(className); InterfaceDecl ai = new InterfaceDecl(); ai.setName(interfaceForModifyingClassFieldName); //extends the existing interface InterfaceTypeUse inf = interf.treeCopyNoTransform(); ai.addExtendedInterfaceUse(inf.treeCopyNoTransform()); mcm.addAddedInterface(new InterfaceTypeUse(ai.getName(), new abs.frontend.ast.List<abs.frontend.ast.Annotation>())); typeHierarchy.put(inf.getName(), interfaceForModifyingClassFieldName); for (MethodImpl m : clazz.getMethodList()) { if (RUN_METHOD.equals(m.getMethodSig().getName())) { mcm.addModifier(removeRun()); break; } } for (FieldDecl fd : clazz.getFieldList()) { AddMethodModifier smm = addSetter(fd.getName(), fd.getAccess().treeCopyNoTransform()); AddMethodModifier gmm = addGetter(fd.getName(), fd.getAccess().treeCopyNoTransform()); mcm.addModifier(smm); mcm.addModifier(gmm); ai.addBody(smm.getMethodImpl().getMethodSig()); ai.addBody(gmm.getMethodImpl().getMethodSig()); } dd.addModuleModifier(new AddInterfaceModifier(ai)); dd.addModuleModifier(mcm); deltas.add(new DeltaWrapper(dd, false)); } }