/*******************************************************************************
* Copyright (c) 2005, 2006 committers of openArchitectureWare 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:
* committers of openArchitectureWare - initial API and implementation
*******************************************************************************/
package org.eclipse.gmf.internal.xpand.xtend.ast;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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.expression.ast.DeclaredParameter;
import org.eclipse.gmf.internal.xpand.expression.ast.Expression;
import org.eclipse.gmf.internal.xpand.expression.ast.Identifier;
public class CreateExtensionStatement extends Extension {
private final Expression expression;
private final String returnVarName;
public CreateExtensionStatement(final int start, final int end, final int line, final int startOffset, final int endOffset, final Identifier name,
final Identifier returnType, final Identifier rtName, final List<DeclaredParameter> params, final Expression expr,
final boolean isPrivate) {
super(start, end, line, startOffset, endOffset, name, returnType, params, true, isPrivate);
expression = expr;
returnVarName = rtName!=null ? rtName.getValue() : "this";
}
@Override
protected EClassifier internalGetReturnType(final EClassifier[] parameters, final ExecutionContext ctx, final Set<AnalysationIssue> issues) {
return ctx.getTypeForName(getReturnTypeIdentifier().getValue());
}
@Override
public void analyzeInternal(ExecutionContext ctx, final Set<AnalysationIssue> issues) {
final EClassifier t = ctx.getTypeForName(returnType.getValue());
if (t == null) {
issues.add(new AnalysationIssue(AnalysationIssue.Type.TYPE_NOT_FOUND, "Couldn't resolve type " + returnType
+ "!", returnType));
return;
}
ctx = ctx.cloneWithVariable(new Variable(returnVarName, t));
expression.analyze(ctx, issues);
}
private final Map<List<Object>, Object> cache = new HashMap<List<Object>, Object>();
@Override
public Object evaluate(final Object[] parameters, ExecutionContext ctx) {
final List<Object> l = Arrays.asList(parameters);
if (cache.containsKey(l)) {
return cache.get(l);
}
ctx = ctx.cloneWithResource(getExtensionFile());
final EClassifier t = ctx.getTypeForName(returnType.getValue());
if (t == null) {
throw new EvaluationException("Couldn't resolve type " + returnType, returnType);
}
final Object inst = BuiltinMetaModel.newInstance(t);
cache.put(l, inst);
ctx = ctx.cloneWithVariable(new Variable(returnVarName, inst));
for (int i = 0; i < parameters.length; i++) {
final Object object = parameters[i];
ctx = ctx.cloneWithVariable(new Variable(getParameterNames().get(i), object));
}
expression.evaluate(ctx);
return inst;
}
@Override
protected Object evaluateInternal(final Object[] parameters, final ExecutionContext ctx) {
throw new UnsupportedOperationException();
}
}