root/trunk/ProjectFortress/src/com/sun/fortress/interpreter/evaluator/values/GenericMethod.java

Revision 4002, 8.1 KB (checked in by sukyoungryu, 4 months ago)

[copyright] Fixed copyright notices.

Line 
1/*******************************************************************************
2 Copyright 2009 Sun Microsystems, Inc.,
3 4150 Network Circle, Santa Clara, California 95054, U.S.A.
4 All rights reserved.
5
6 U.S. Government Rights - Commercial software.
7 Government users are subject to the Sun Microsystems, Inc. standard
8 license agreement and applicable provisions of the FAR and its supplements.
9
10 Use is subject to license terms.
11
12 This distribution may include materials developed by third parties.
13
14 Sun, Sun Microsystems, the Sun logo and Java are trademarks or registered
15 trademarks of Sun Microsystems, Inc. in the U.S. and other countries.
16 ******************************************************************************/
17
18package com.sun.fortress.interpreter.evaluator.values;
19
20import static com.sun.fortress.exceptions.ProgramError.error;
21import static com.sun.fortress.exceptions.ProgramError.errorMsg;
22import com.sun.fortress.interpreter.evaluator.Environment;
23import com.sun.fortress.interpreter.evaluator.EvalType;
24import com.sun.fortress.interpreter.evaluator.types.FType;
25import com.sun.fortress.interpreter.evaluator.types.FTypeTop;
26import com.sun.fortress.nodes.*;
27import com.sun.fortress.nodes_util.NodeComparator;
28import com.sun.fortress.nodes_util.NodeUtil;
29import com.sun.fortress.useful.Factory1P;
30import com.sun.fortress.useful.HasAt;
31import com.sun.fortress.useful.Memo1P;
32import edu.rice.cs.plt.tuple.Option;
33
34import java.util.ArrayList;
35import java.util.Comparator;
36import java.util.List;
37
38public class GenericMethod extends MethodClosure
39        implements GenericFunctionOrMethod, Factory1P<List<FType>, MethodClosure, HasAt> {
40
41    /* (non-Javadoc)
42     * @see com.sun.fortress.interpreter.evaluator.values.FValue#getString()
43     */
44    @Override
45    public String getString() {
46        return s(getDef());
47    }
48
49    boolean isTraitMethod;
50
51    Environment evaluationEnv;
52
53    protected MethodClosure newClosure(Environment clenv, List<FType> args) {
54        MethodClosure cl;
55        if (!isTraitMethod) {
56            cl = new MethodClosureInstance(getEnv(), clenv, getDef(), getDefiner(), args, this);
57        } else if (FType.anyAreSymbolic(args)) {
58            cl = new TraitMethodInstance(getEnv(), clenv, getDef(), getDefiner(), args, this);
59        } else {
60            // TODO Intention is that this is a plain old instantiation,
61            // however there are issues of capturing the evaluation
62            // environment that makes this not work quite right
63            // MethodClosureInstance ought to be MethodClosure, but
64            // isn't, yet.
65            cl = new TraitMethod(getEnv(), clenv, getDef(), getDefiner(), args);
66        }
67        cl.finishInitializing();
68        return (MethodClosure) cl;
69    }
70
71    private class Factory implements Factory1P<List<FType>, MethodClosure, HasAt> {
72
73        public MethodClosure make(List<FType> args, HasAt location) {
74            Environment clenv = evaluationEnv.extendAt(location); // TODO is this the right environment?
75            // It looks like it might be, or else good enough.  The disambiguating
76            // pass effectively hides all the names defined in the interior
77            // of the trait.
78            List<StaticParam> params = NodeUtil.getStaticParams(getDef());
79            EvalType.bindGenericParameters(params, args, clenv, location, getDef());
80            clenv.bless();
81            return newClosure(clenv, args);
82        }
83    }
84
85    Memo1P<List<FType>, MethodClosure, HasAt> memo = new Memo1P<List<FType>, MethodClosure, HasAt>(new Factory());
86
87    public MethodClosure make(List<FType> l, HasAt location) {
88        return memo.make(l, location);
89    }
90
91    public GenericMethod(Environment declarationEnv,
92                         Environment evaluationEnv,
93                         FnDecl fndef,
94                         FType definer,
95                         boolean isTraitMethod) {
96        super(// new SpineEnv(declarationEnv, fndef), // Add an extra scope/layer for the generics.
97              declarationEnv, // not yet, it changes overloading semantics.
98              fndef, definer);
99        this.isTraitMethod = isTraitMethod;
100        this.evaluationEnv = evaluationEnv;
101    }
102
103    //    public GenericMethod(Environment declarationEnv, Environment traitEnv, FnDecl fndef, String selfName) {
104    //        super(declarationEnv, fndef, selfName);
105    //
106    //    }
107
108    public MethodClosure typeApply(List<StaticArg> args, Environment e, HasAt location) {
109        List<StaticParam> params = NodeUtil.getStaticParams(getDef());
110
111        // Evaluate each of the args in e, inject into clenv.
112        if (args.size() != params.size()) {
113            error(location, e, errorMsg("Generic instantiation (size) mismatch, expected ", params, " got ", args));
114        }
115        EvalType et = new EvalType(e);
116        // TODO Can combine these two functions if we enhance the memo and factory
117        // to pass two parameters instead of one.
118
119        ArrayList<FType> argValues = et.forStaticArgList(args);
120        return make(argValues, location);
121    }
122
123    public Simple_fcn typeApply(List<FType> argValues, HasAt location) {
124        return make(argValues, location);
125    }
126
127    public Simple_fcn typeApply(List<FType> argValues) {
128        return make(argValues, getDef());
129    }
130
131    public void finishInitializing() {
132        Applicable x = getDef();
133        List<Param> params = NodeUtil.getParams(x);
134        Option<Type> rt = NodeUtil.getReturnType(x);
135        Environment env = getEnv(); // should need this for types,
136        // below.
137        // TODO work in progress
138        // Inject type parameters into environment as symbolics
139        List<StaticParam> tparams = NodeUtil.getStaticParams(getDef());
140
141        FType ft = EvalType.getFTypeFromOption(rt, env, FTypeTop.ONLY);
142        List<Parameter> fparams = EvalType.paramsToParameters(env, params);
143
144        setParamsAndReturnType(fparams, ft);
145        return;
146    }
147
148    static class GenericComparer implements Comparator<GenericMethod> {
149
150        public int compare(GenericMethod arg0, GenericMethod arg1) {
151            Applicable a0 = arg0.getDef();
152            Applicable a1 = arg1.getDef();
153
154            IdOrOpOrAnonymousName fn0 = NodeUtil.getName(a0);
155            IdOrOpOrAnonymousName fn1 = NodeUtil.getName(a1);
156            int x = NodeComparator.compare(fn0, fn1);
157            if (x != 0) return x;
158
159            List<StaticParam> oltp0 = NodeUtil.getStaticParams(a0);
160            List<StaticParam> oltp1 = NodeUtil.getStaticParams(a1);
161
162            return NodeComparator.compare(oltp0, oltp1);
163
164        }
165
166    }
167
168    static final GenericComparer genComparer = new GenericComparer();
169
170    // static class GenericFullComparer implements Comparator<GenericMethod> {
171
172    //     public int compare(GenericMethod arg0, GenericMethod arg1) {
173    //         return compare(arg0.getDef(), arg1.getDef());
174    //     }
175
176    //     int compare(Applicable left, Applicable right) {
177    //         if (left instanceof FnExpr) {
178    //             int x = Useful.compareClasses(left, right);
179    //             if (x != 0) return x;
180    //             return NodeUtil.nameString(((FnExpr)left).getName())
181    //                 .compareTo(NodeUtil.nameString(((FnExpr)right).getName()));
182    //         } else if (left instanceof FnDecl) {
183    //             int x = Useful.compareClasses(left, right);
184    //             if (x != 0) return x;
185    //             return compare(left, (FnDecl)right);
186    //         } else if (left instanceof NativeApp) {
187    //             return Useful.compareClasses(left, right);
188    //         } else {
189    //             throw new InterpreterBug(left, "NodeComparator.compare(" +
190    //                                      left.getClass() + ", " + right.getClass());
191    //         }
192    //     }
193
194    // }
195    // static final GenericFullComparer genFullComparer = new GenericFullComparer();
196
197    public IdOrOpOrAnonymousName getName() {
198        return NodeUtil.getName(getDef());
199    }
200
201    public List<StaticParam> getStaticParams() {
202        return NodeUtil.getStaticParams(getDef());
203    }
204
205    public List<Param> getParams() {
206        return NodeUtil.getParams(getDef());
207    }
208
209    public Option<Type> getReturnType() {
210        return NodeUtil.getReturnType(getDef());
211    }
212
213
214}
Note: See TracBrowser for help on using the browser.