/* * Copyright (C) 2010-2016 JPEXS, All rights reserved. * * This library 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.0 of the License, or (at your option) any later version. * * This library 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 this library. */ package com.jpexs.decompiler.graph.model; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.graph.GraphPart; import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphSourceItemPos; import com.jpexs.decompiler.graph.GraphTargetItem; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Set; /** * * @author JPEXS */ public abstract class BinaryOpItem extends GraphTargetItem implements BinaryOp { public GraphTargetItem leftSide; public GraphTargetItem rightSide; protected final String operator; protected String coerceLeft; protected String coerceRight; @Override public GraphPart getFirstPart() { GraphPart fp = leftSide.getFirstPart(); if (fp == null) { return super.getFirstPart(); } return fp; } public BinaryOpItem(GraphSourceItem instruction, GraphSourceItem lineStartItem, int precedence, GraphTargetItem leftSide, GraphTargetItem rightSide, String operator, String coerceLeft, String coerceRight) { super(instruction, lineStartItem, precedence); this.leftSide = leftSide; this.rightSide = rightSide; this.operator = operator; this.coerceLeft = coerceLeft; this.coerceRight = coerceRight; } @Override public GraphTargetItem simplify(String implicitCoerce) { BinaryOpItem r = (BinaryOpItem) clone(); r.leftSide = r.leftSide.simplify(coerceLeft); r.rightSide = r.rightSide.simplify(coerceRight); return simplifySomething(r, implicitCoerce); } @Override public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException { int leftPrecedence = leftSide.getPrecedence(); if (leftPrecedence > precedence && leftPrecedence != GraphTargetItem.NOPRECEDENCE) { writer.append("("); leftSide.toString(writer, localData, coerceLeft); writer.append(")"); } else { leftSide.toString(writer, localData, coerceLeft); } writer.append(" "); writer.append(operator); writer.append(" "); int rightPrecedence = rightSide.getPrecedence(); if (rightPrecedence >= precedence && rightPrecedence != GraphTargetItem.NOPRECEDENCE) { writer.append("("); rightSide.toString(writer, localData, coerceRight); writer.append(")"); } else { rightSide.toString(writer, localData, coerceRight); } return writer; } @Override public List<GraphSourceItemPos> getNeededSources() { List<GraphSourceItemPos> ret = super.getNeededSources(); ret.addAll(leftSide.getNeededSources()); ret.addAll(rightSide.getNeededSources()); return ret; } @Override public boolean isCompileTime(Set<GraphTargetItem> dependencies) { if (dependencies.contains(leftSide)) { return false; } dependencies.add(leftSide); if (leftSide != rightSide && dependencies.contains(rightSide)) { return false; } dependencies.add(rightSide); return leftSide.isConvertedCompileTime(dependencies) && rightSide.isConvertedCompileTime(dependencies); } @Override public boolean isVariableComputed() { return leftSide.isVariableComputed() || rightSide.isVariableComputed(); } @Override public boolean hasSideEffect() { return leftSide.hasSideEffect() || rightSide.hasSideEffect(); } @Override public int hashCode() { int hash = 7; hash = 71 * hash + Objects.hashCode(leftSide); hash = 71 * hash + Objects.hashCode(rightSide); hash = 71 * hash + Objects.hashCode(operator); return hash; } public GraphTargetItem getLeftMostItem(GraphTargetItem item) { GraphTargetItem ret = item; if (ret instanceof BinaryOpItem) { ret = ((BinaryOpItem) ret).getLeftMostItem(); } return ret; } public GraphTargetItem getLeftMostItem() { GraphTargetItem ret = leftSide; if (ret instanceof BinaryOpItem) { ret = ((BinaryOpItem) ret).getLeftMostItem(); } return ret; } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final BinaryOpItem other = (BinaryOpItem) obj; if (!Objects.equals(leftSide, other.leftSide)) { return false; } if (!Objects.equals(rightSide, other.rightSide)) { return false; } return (Objects.equals(operator, other.operator)); } /*@Override public boolean toBoolean() { double val=toNumber(); if(Double.isNaN(val)){ return false; } if(Double.compare(val, 0)==0){ return false; } return true; }*/ @Override public GraphTargetItem getLeftSide() { return leftSide; } @Override public GraphTargetItem getRightSide() { return rightSide; } @Override public void setLeftSide(GraphTargetItem value) { leftSide = value; } @Override public void setRightSide(GraphTargetItem value) { rightSide = value; } @Override public int getPrecedence() { return precedence; } @Override public boolean hasReturnValue() { return true; } @Override public List<GraphTargetItem> getAllSubItems() { List<GraphTargetItem> ret = new ArrayList<>(); ret.add(getLeftSide()); ret.add(getRightSide()); return ret; } }