All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cfml.parsing.cfscript.CFAssignmentExpression Maven / Gradle / Ivy

There is a newer version: 2.11.0
Show newest version
package cfml.parsing.cfscript;

import java.util.ArrayList;
import java.util.List;

import org.antlr.v4.runtime.Token;

import cfml.parsing.cfscript.script.CFScriptStatement;
import cfml.parsing.util.ArrayBuilder;

public class CFAssignmentExpression extends CFExpression {
	
	private static final long serialVersionUID = 1L;
	
	private CFExpression left;
	private CFExpression right;
	
	List otherIds = new ArrayList();
	
	public List getOtherIds() {
		return otherIds;
	}
	
	public CFAssignmentExpression(Token t, CFExpression _left, CFExpression _right) {
		super(t);
		left = _left;
		right = _right;
		if (left != null)
			left.setParent(this);
		if (right != null)
			right.setParent(this);
	}
	
	@Override
	public byte getType() {
		return CFExpression.ASSIGNMENT;
	}
	
	public void checkIndirect(String expr) {
		if (left instanceof CFVarExpression) {
			String lhs = expr.substring(0, expr.indexOf('=')).trim();
			// check for special case of "#foo#"="bar" or '#foo#'='bar'
			if ((lhs.startsWith("\"#") && lhs.endsWith("#\"")) || (lhs.startsWith("'#") && lhs.endsWith("#'"))) {
				((CFVarExpression) left).setIndirect(true);
			}
		}
	}
	
	@Override
	public void checkIndirectAssignments(String[] scriptSource) {
		if (left instanceof CFVarExpression) {
			/*
			 * We know this is a valid assignment expression but is the LHS expression a # expression e.g. "#foo#" =
			 * "bar" Since the poundSignFilter removes the #'s for the parser we need to look at the original source. We
			 * can get the line from this CFExpression but the column isn't accurate enough for CFFullVarExpressions
			 * especially as more than one expression may occur on the same line.
			 * 
			 * We look backwards from the '=' skipping any whitespace and looking for #", #' or # on it's own.
			 */
			
			// find the original expression in the script source code
			String expr = scriptSource[left.getLine() - 1];
			int lhsEnd = expr.indexOf("=", left.getColumn());
			if (lhsEnd == -1) {
				// if the expression is split over 2 lines
				// e.g. "#foo#"
				// = "bar"
				lhsEnd = expr.length();
			}
			
			char[] exprChars = expr.substring(0, lhsEnd).toCharArray();
			int i = exprChars.length - 1;
			// skip over whitespace
			while (i >= 0 && (Character.isWhitespace(exprChars[i]))) {
				i--;
			}
			
			// does LHS expression end in #" or #'?
			if (i >= 0 && (exprChars[i] == '\"' || exprChars[i] == '\'')) {
				i--;
				if (i >= 0 && exprChars[i] == '#') {
					((CFVarExpression) left).setIndirect(true);
				}
			}
		}
	}
	
	@Override
	public String Decompile(int indent) {
		StringBuilder sb = new StringBuilder();
		if (left != null) {
			sb.append(left.Decompile(indent));
		}
		sb.append(" = ");
		for (CFIdentifier id : otherIds) {
			sb.append(id.Decompile(indent));
			sb.append(" = ");
		}
		if (right != null) {
			sb.append(right.Decompile(indent));
		}
		return sb.toString();
	}
	
	public CFExpression getLeft() {
		return left;
	}
	
	public CFExpression getRight() {
		return right;
	}
	
	@Override
	public List decomposeExpression() {
		List retval = ArrayBuilder.createCFExpression(left, right);
		retval.addAll(otherIds);
		return retval;
	}
	
	@Override
	public List decomposeScript() {
		return ArrayBuilder.createCFScriptStatement();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy