/* * This file is part of the X10 project (http://x10-lang.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.opensource.org/licenses/eclipse-1.0.php * * (C) Copyright IBM Corporation 2006-2010. */ package x10.util.synthesizer; import java.util.ArrayList; import java.util.List; import polyglot.ast.Expr; import polyglot.ast.NodeFactory; import polyglot.ast.Receiver; import polyglot.ast.Stmt; import polyglot.ast.TypeNode; import polyglot.types.Name; import polyglot.types.SemanticException; import polyglot.types.Type; import polyglot.util.Position; import polyglot.types.Context; import polyglot.types.TypeSystem; import x10.types.MethodInstance; /** * A simple synthesizer to create a instance call. */ public class InstanceCallSynth extends AbstractStateSynth implements IStmtSynth, IExprSynth { Receiver insRef; //the reference to the instance Name methodName; //Default value for other needed information; Type methodLocationType; // the type of the method List<TypeNode> typeNodes; // typeNodes for the method List<Type> argTypes; //arguments' type --> If we could reason the args' type from args, the list could be eliminated List<Expr> args; //arguments Type returnType; public InstanceCallSynth(NodeFactory xnf, Context xct, Position pos, Receiver insRef, Name methodName){ super(xnf, xct, pos); this.insRef = insRef; this.methodName = methodName; methodLocationType = insRef.type(); typeNodes = new ArrayList<TypeNode>(); argTypes = new ArrayList<Type>(); args = new ArrayList<Expr>(); returnType = null; //default null, refer from expression } public InstanceCallSynth(NodeFactory xnf, Context xct, Position pos, Receiver insRef, String methodName){ this(xnf, xct, pos, insRef, Name.make(methodName)); } public InstanceCallSynth(NodeFactory xnf, Context xct, Receiver insRef, String methodName){ this(xnf, xct, compilerPos, insRef, Name.make(methodName)); } public void setMethodLocationType(Type type){ methodLocationType = type; } public void addTypeNode(TypeNode tNode){ typeNodes.add(tNode); } public void setReturnType(Type type){ returnType = type; } public void addArgument(Type argType, Expr arg){ argTypes.add(argType); args.add(arg); } public void addArguments(List<Type> argTypes, List<Expr> args){ assert(argTypes.size() == args.size()); for(int i = 0; i < argTypes.size(); i++){ addArgument(argTypes.get(i), args.get(i)); } } public Expr genExpr() throws SemanticException { TypeSystem xts = (TypeSystem) xct.typeSystem(); List<Type> typeArgs = new ArrayList<Type>(); for (TypeNode t : typeNodes){ typeArgs.add(t.type()); } MethodInstance mi = xts.findMethod(methodLocationType, xts.MethodMatcher(methodLocationType, methodName, typeArgs, argTypes, xct)); //handle return type if(returnType == null){ //not set returnType = mi.returnType(); } Expr result = xnf.X10Call(pos, insRef, xnf.Id(pos, methodName), typeNodes, args).methodInstance(mi) .type(returnType); return result; } public Stmt genStmt() throws SemanticException { return xnf.Eval(pos, genExpr()); } }