/* Copyright (c) 2008 Arno Haase, Andr� Arnold. All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html Contributors: Arno Haase - initial API and implementation Andr� Arnold */ package org.eclipse.xtend.backend.expr; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.eclipse.xtend.backend.common.ExecutionContext; import org.eclipse.xtend.backend.common.ExpressionBase; import org.eclipse.xtend.backend.common.QualifiedName; import org.eclipse.xtend.backend.common.SourcePos; import org.eclipse.xtend.backend.common.SyntaxConstants; import org.eclipse.xtend.backend.syslib.CollectionOperations; //TODO refactor: middle ends only use this, and a subsequent step differentiates / optimizes to the other two /** * This expression invokes a function on the first argument, deciding at runtime whether to do the "collection magic" of * invoking the function on every member of the collection that is the first argument and returning the collection of * all the arguments.<br> * * This expression does *not* do implicit "this" resolution - it is the responsibility of the initializing code, e.g. in the * middle end, to statically resolve that. * * @author Arno Haase (http://www.haase-consulting.com) * @author Andr� Arnold */ public final class InvocationOnWhateverExpression extends ExpressionBase { private final QualifiedName _functionName; private final List<? extends ExpressionBase> _params; private final boolean _nullIfFirstParamIsNull; public InvocationOnWhateverExpression (QualifiedName functionName, List<? extends ExpressionBase> params, boolean nullIfFirstParamIsNull, SourcePos sourcePos) { super (sourcePos); _functionName = functionName; _params = params; _nullIfFirstParamIsNull = nullIfFirstParamIsNull; } public QualifiedName getFunctionName() { return _functionName; } public List<? extends ExpressionBase> getParams() { return _params; } public boolean isNullIfFirstParamIsNull() { return _nullIfFirstParamIsNull; } @Override protected Object evaluateInternal(ExecutionContext ctx) { final List<Object> params = new ArrayList<Object> (); boolean firstParamIsThis = false; if (_params.size() > 0 && _params.get(0) instanceof LocalVarEvalExpression) if (((LocalVarEvalExpression)_params.get(0)).getLocalVarName().equals(SyntaxConstants.THIS)) firstParamIsThis = true; for (ExpressionBase expr: _params) params.add (expr.evaluate(ctx)); if (_nullIfFirstParamIsNull && params.get(0) == null) { ctx.logNullDeRef (getPos()); return null; } if (params.get (0) instanceof Collection<?>) { // check if this is a function on Collection itself if (ctx.getFunctionDefContext().hasMatch (ctx, _functionName, params)) return ctx.getFunctionDefContext().invoke (ctx, _functionName, params, firstParamIsThis); final Collection<?> coll = (Collection<?>) params.get (0); final Collection<Object> result = CollectionOperations.createMatchingCollection (coll); for (Object o: coll) { params.set (0, o); CollectionOperations.addFlattened (result, ctx.getFunctionDefContext().invoke (ctx, _functionName, params, firstParamIsThis)); } return result; } else return ctx.getFunctionDefContext().invoke (ctx, _functionName, params, firstParamIsThis); } }