/* * #%~ * VDM Code Generator * %% * Copyright (C) 2008 - 2014 Overture * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #~% */ package org.overture.codegen.trans.assistants; import java.util.LinkedList; import java.util.List; import org.overture.codegen.ir.INode; import org.overture.codegen.ir.SStmIR; import org.overture.codegen.ir.analysis.AnalysisException; import org.overture.codegen.ir.analysis.DepthFirstAnalysisAdaptor; import org.overture.codegen.ir.declarations.AVarDeclIR; import org.overture.codegen.ir.expressions.AAnonymousClassExpIR; import org.overture.codegen.ir.statements.ABlockStmIR; import org.overture.codegen.ir.statements.AElseIfStmIR; import org.overture.codegen.ir.statements.AIfStmIR; public class BaseTransformationAssistant { public void replaceNodeWith(INode original, INode replacement) { if (original != replacement) { replace(original, replacement); } } public void replaceNodeWithRecursively(INode original, INode replacement, DepthFirstAnalysisAdaptor analysis) throws AnalysisException { if (original != replacement) { replaceNodeWith(original, replacement); replacement.apply(analysis); } } private void replace(INode original, INode replacement) { INode parent = original.parent(); if (parent != null) { parent.replaceChild(original, replacement); } original.parent(null); } public SStmIR findEnclosingStm(INode node) throws AnalysisException { if (node.getAncestor(AAnonymousClassExpIR.class) == null) { AVarDeclIR localDecl = node.getAncestor(AVarDeclIR.class); if (localDecl != null && localDecl.parent() instanceof ABlockStmIR) { ABlockStmIR block = (ABlockStmIR) localDecl.parent(); if (block.getLocalDefs().size() <= 1) { return block; } List<AVarDeclIR> defsToLift = new LinkedList<AVarDeclIR>(); int i = 0; for (; i < block.getLocalDefs().size(); i++) { AVarDeclIR currentDef = block.getLocalDefs().get(i); if (currentDef == localDecl) { defsToLift.add(currentDef); i++; for (; i < block.getLocalDefs().size(); i++) { currentDef = block.getLocalDefs().get(i); defsToLift.add(currentDef); } } } block.getLocalDefs().removeAll(defsToLift); LinkedList<SStmIR> statementsToLift = block.getStatements(); ABlockStmIR liftedBlock = new ABlockStmIR(); liftedBlock.setLocalDefs(defsToLift); liftedBlock.setStatements(statementsToLift); block.getStatements().clear(); block.getStatements().add(liftedBlock); return liftedBlock; } } SStmIR enclosingStm = node.getAncestor(SStmIR.class); if (enclosingStm == null) { return null; } if (enclosingStm instanceof AElseIfStmIR) { AElseIfStmIR elseIf = (AElseIfStmIR) enclosingStm; AIfStmIR enclosingIf = elseIf.getAncestor(AIfStmIR.class); LinkedList<AElseIfStmIR> elseIfList = new LinkedList<AElseIfStmIR>(enclosingIf.getElseIf()); for (int i = 0; i < elseIfList.size(); i++) { AElseIfStmIR currentElseIf = elseIfList.get(i); if (elseIf == currentElseIf) { enclosingIf.getElseIf().remove(currentElseIf); AIfStmIR elsePart = new AIfStmIR(); elsePart.setIfExp(currentElseIf.getElseIf()); elsePart.setThenStm(currentElseIf.getThenStm()); for (int j = i + 1; j < elseIfList.size(); j++) { enclosingIf.getElseIf().remove(elseIfList.get(j)); elsePart.getElseIf().add(elseIfList.get(j)); } ABlockStmIR block = new ABlockStmIR(); block.getStatements().add(elsePart); elsePart.setElseStm(enclosingIf.getElseStm()); enclosingIf.setElseStm(block); return elsePart; } } } return enclosingStm; } public SStmIR getEnclosingStm(INode node, String nodeStr) throws AnalysisException { SStmIR enclosingStm = findEnclosingStm(node); if (enclosingStm == null) { new AnalysisException(String.format("Could not find enclosing statement for %s", node)); } return enclosingStm; } }