001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019package lucee.transformer.bytecode.expression.var;
020
021import java.util.ArrayList;
022import java.util.Iterator;
023import java.util.List;
024
025import lucee.runtime.type.scope.Scope;
026import lucee.runtime.type.scope.ScopeFactory;
027import lucee.transformer.bytecode.BytecodeContext;
028import lucee.transformer.bytecode.BytecodeException;
029import lucee.transformer.bytecode.Literal;
030import lucee.transformer.bytecode.expression.ExprString;
031import lucee.transformer.bytecode.expression.Expression;
032import lucee.transformer.bytecode.expression.ExpressionBase;
033import lucee.transformer.bytecode.literal.Identifier;
034import lucee.transformer.bytecode.literal.LitString;
035
036import org.objectweb.asm.Type;
037
038public final class VariableString extends ExpressionBase implements ExprString {
039
040        private Expression expr;
041
042        public VariableString(Expression expr) {
043                super(expr.getStart(),expr.getEnd());
044                this.expr=expr;
045        }
046 
047        public Type _writeOut(BytecodeContext bc, int mode) throws BytecodeException {
048                return translateVariableToExprString(expr,false).writeOut(bc, mode);
049        }
050
051        public static ExprString toExprString(Expression expr) {
052                if(expr instanceof ExprString) return (ExprString) expr;
053                return new VariableString(expr);
054        }
055        
056        public static ExprString translateVariableToExprString(Expression expr, boolean rawIfPossible) throws BytecodeException {
057                if(expr instanceof ExprString) return (ExprString) expr;
058                return LitString.toExprString(translateVariableToString(expr,rawIfPossible), expr.getStart(),expr.getEnd());
059        }
060        
061        private static String translateVariableToString(Expression expr, boolean rawIfPossible) throws BytecodeException {
062                if(!(expr instanceof Variable)) throw new BytecodeException("can't translate value to a string",expr.getStart());
063                return variableToString((Variable) expr,rawIfPossible);
064        }
065                
066
067        public static String variableToString(Variable var, boolean rawIfPossible) throws BytecodeException {
068                return lucee.runtime.type.util.ListUtil.arrayToList(variableToStringArray(var,rawIfPossible),".");
069        }
070        public static String[] variableToStringArray(Variable var, boolean rawIfPossible) throws BytecodeException {
071                List members = var.getMembers();
072                        
073                List<String> arr=new ArrayList<String>();
074                if(var.getScope()!=Scope.SCOPE_UNDEFINED)arr.add(ScopeFactory.toStringScope(var.getScope(),"undefined"));
075                Iterator it = members.iterator();
076                DataMember dm;
077                Expression n;
078                while(it.hasNext()) {
079                        Object o = it.next();
080                        if(!(o instanceof DataMember)) throw new BytecodeException("can't translate Variable to a String",var.getStart());
081                        dm=(DataMember) o;
082                        n=dm.getName();
083                        if(n instanceof Literal) {
084                                if(rawIfPossible && n instanceof Identifier) {
085                                        arr.add(((Identifier) n).getRaw());
086                                }
087                                else {
088                                        arr.add(((Literal) n).getString());
089                                }
090                        }
091                        else throw new BytecodeException("argument name must be a constant value",var.getStart());
092                }
093                return arr.toArray(new String[arr.size()]);
094        }
095        
096        public String castToString() throws BytecodeException{
097                return translateVariableToString(expr,false);
098        }
099}