/* * <copyright> * * Copyright (c) 2005-2008 Sven Efftinge and others. * 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: * Sven Efftinge - Initial API and implementation * Alexander Shatalin (Borland) * * </copyright> */ package org.eclipse.gmf.internal.xpand.expression.ast; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.Set; import org.eclipse.emf.ecore.EClassifier; import org.eclipse.gmf.internal.xpand.BuiltinMetaModel; import org.eclipse.gmf.internal.xpand.expression.AnalysationIssue; import org.eclipse.gmf.internal.xpand.expression.EvaluationException; import org.eclipse.gmf.internal.xpand.expression.ExecutionContext; import org.eclipse.gmf.internal.xpand.expression.Variable; import org.eclipse.gmf.internal.xpand.migration.TypeSelectExpressionTrace; /** * @author Sven Efftinge * @author Arno Haase */ public class TypeSelectExpression extends FeatureCall { private Identifier typeLiteral; public TypeSelectExpression(final int end, final int endOffset, final Identifier opName, final Identifier typeLiteral, final Expression target) { super(opName.getStart(), end, opName.getLine(), opName.getStartOffset(), endOffset, opName, target); this.typeLiteral = typeLiteral; } @Override public String toString() { return super.toString() + "(" + typeLiteral + ")"; } @Override public Object evaluateInternal(final ExecutionContext ctx) { Object targetObj = null; if (getTarget() == null) { final Variable v = ctx.getVariable(ExecutionContext.IMPLICIT_VARIABLE); if (v != null) { targetObj = v.getValue(); } } else { targetObj = getTarget().evaluate(ctx); } if (targetObj == null) { return null; } if (!(targetObj instanceof Collection)) { } return executeTypeSelect((Collection) targetObj, ctx); } private Object executeTypeSelect(final Collection collection, final ExecutionContext ctx) { final Collection<Object> resultCol = new ArrayList<Object>(); final EClassifier t = ctx.getTypeForName(typeLiteral.getValue()); if (t == null) { throw new EvaluationException("Unkown type '" + typeLiteral + "'", typeLiteral); } for (final Iterator iter = collection.iterator(); iter.hasNext();) { final Object ele = iter.next(); if ((ele!=null) && BuiltinMetaModel.isAssignableFrom(t, BuiltinMetaModel.getType(ele))) { resultCol.add(ele); } } return resultCol; } @Override public EClassifier analyze(final ExecutionContext ctx, final Set<AnalysationIssue> issues) { EClassifier targetType = null; if (getTarget() == null) { final Variable v = ctx.getVariable(ExecutionContext.IMPLICIT_VARIABLE); if (v != null) { targetType = (EClassifier) v.getValue(); } } else { targetType = getTarget().analyze(ctx, issues); } if (targetType == null) { return createAnalyzeTrace(ctx, new TypeSelectExpressionTrace(null, null)); } if (!BuiltinMetaModel.isParameterizedType(targetType)) { issues.add(new AnalysationIssue(AnalysationIssue.Type.INCOMPATIBLE_TYPES, "Collection type expected! was : " + targetType, getTarget())); return null; } final EClassifier closureEClassifier = ctx.getTypeForName(typeLiteral.getValue()); if (closureEClassifier == null) { issues.add(new AnalysationIssue(AnalysationIssue.Type.TYPE_NOT_FOUND, "Couldn't find type " + typeLiteral, typeLiteral)); return null; } return createAnalyzeTrace(ctx, new TypeSelectExpressionTrace(BuiltinMetaModel.getListType(closureEClassifier), targetType)); } public Identifier getTypeLiteral() { return typeLiteral; } }