| 1 | |
|---|
| 2 | |
|---|
| 3 | |
|---|
| 4 | |
|---|
| 5 | |
|---|
| 6 | |
|---|
| 7 | |
|---|
| 8 | |
|---|
| 9 | |
|---|
| 10 | |
|---|
| 11 | |
|---|
| 12 | |
|---|
| 13 | |
|---|
| 14 | |
|---|
| 15 | |
|---|
| 16 | |
|---|
| 17 | |
|---|
| 18 | package com.sun.fortress.interpreter.evaluator.values; |
|---|
| 19 | |
|---|
| 20 | import static com.sun.fortress.exceptions.InterpreterBug.bug; |
|---|
| 21 | import static com.sun.fortress.exceptions.ProgramError.errorMsg; |
|---|
| 22 | import com.sun.fortress.interpreter.evaluator.Environment; |
|---|
| 23 | import com.sun.fortress.interpreter.evaluator.types.FTraitOrObjectOrGeneric; |
|---|
| 24 | import com.sun.fortress.interpreter.evaluator.types.FType; |
|---|
| 25 | import com.sun.fortress.nodes.Applicable; |
|---|
| 26 | import com.sun.fortress.nodes_util.NodeUtil; |
|---|
| 27 | import com.sun.fortress.useful.AssignedList; |
|---|
| 28 | import com.sun.fortress.useful.Useful; |
|---|
| 29 | |
|---|
| 30 | import java.util.List; |
|---|
| 31 | |
|---|
| 32 | public class FunctionalMethod extends FunctionClosure implements HasSelfParameter { |
|---|
| 33 | |
|---|
| 34 | final private int selfParameterIndex; |
|---|
| 35 | final private FTraitOrObjectOrGeneric selfParameterType; |
|---|
| 36 | final private String mname; |
|---|
| 37 | |
|---|
| 38 | public FunctionalMethod(Environment e, |
|---|
| 39 | Applicable fndef, |
|---|
| 40 | int self_parameter_index, |
|---|
| 41 | FTraitOrObjectOrGeneric self_parameter_type) { |
|---|
| 42 | super(e, fndef, true); |
|---|
| 43 | selfParameterIndex = self_parameter_index; |
|---|
| 44 | selfParameterType = self_parameter_type; |
|---|
| 45 | mname = NodeUtil.nameAsMethod(getDef()); |
|---|
| 46 | |
|---|
| 47 | } |
|---|
| 48 | |
|---|
| 49 | protected FunctionalMethod(Environment e, |
|---|
| 50 | Applicable fndef, |
|---|
| 51 | List<FType> static_args, |
|---|
| 52 | int self_parameter_index, |
|---|
| 53 | FTraitOrObjectOrGeneric self_parameter_type) { |
|---|
| 54 | super(e, fndef, static_args); |
|---|
| 55 | selfParameterIndex = self_parameter_index; |
|---|
| 56 | selfParameterType = self_parameter_type; |
|---|
| 57 | mname = NodeUtil.nameAsMethod(getDef()); |
|---|
| 58 | |
|---|
| 59 | } |
|---|
| 60 | |
|---|
| 61 | public MethodClosure getApplicableClosure(List<FValue> args0) { |
|---|
| 62 | FValue selfVal = args0.get(selfParameterIndex); |
|---|
| 63 | DottedMethodApplication ma = DottedMethodApplication.make(selfVal, s(def), mname); |
|---|
| 64 | Method cl = ma.getMethod(); |
|---|
| 65 | if (cl instanceof MethodClosure) { |
|---|
| 66 | return (MethodClosure) cl; |
|---|
| 67 | } else if (cl instanceof OverloadedMethod) { |
|---|
| 68 | List<FValue> args = Useful.removeIndex(selfParameterIndex, args0); |
|---|
| 69 | OverloadedMethod om = (OverloadedMethod) cl; |
|---|
| 70 | return om.getApplicableMethod(args); |
|---|
| 71 | } else { |
|---|
| 72 | return bug(errorMsg("Functional method resolution for ", this, args0, " yields non-MethodClosure ", cl)); |
|---|
| 73 | } |
|---|
| 74 | } |
|---|
| 75 | |
|---|
| 76 | |
|---|
| 77 | |
|---|
| 78 | |
|---|
| 79 | @Override |
|---|
| 80 | public FValue applyInnerPossiblyGeneric(List<FValue> args) { |
|---|
| 81 | FValue selfVal = args.get(selfParameterIndex); |
|---|
| 82 | args = Useful.removeIndex(selfParameterIndex, args); |
|---|
| 83 | return DottedMethodApplication.invokeMethod(selfVal, s(def), mname, args); |
|---|
| 84 | } |
|---|
| 85 | |
|---|
| 86 | @Override |
|---|
| 87 | public List<Parameter> getParameters() { |
|---|
| 88 | Parameter selfParam = new Parameter("self", selfParameterType, false); |
|---|
| 89 | return new AssignedList<Parameter>(super.getParameters(), selfParameterIndex, selfParam); |
|---|
| 90 | } |
|---|
| 91 | |
|---|
| 92 | public int hashCode() { |
|---|
| 93 | return def.hashCode() + selfParameterType.hashCode() + (instArgs == null ? 0 : instArgs.hashCode()); |
|---|
| 94 | } |
|---|
| 95 | |
|---|
| 96 | public boolean equals(Object o) { |
|---|
| 97 | if (this == o) return true; |
|---|
| 98 | if (o.getClass().equals(this.getClass())) { |
|---|
| 99 | FunctionalMethod oc = (FunctionalMethod) o; |
|---|
| 100 | return def == oc.def && selfParameterType.equals(oc.selfParameterType) && (instArgs == null ? |
|---|
| 101 | (oc.instArgs == null) : |
|---|
| 102 | oc.instArgs == null ? |
|---|
| 103 | false : |
|---|
| 104 | instArgs.equals(oc.instArgs)); |
|---|
| 105 | } |
|---|
| 106 | return false; |
|---|
| 107 | } |
|---|
| 108 | |
|---|
| 109 | public int getSelfParameterIndex() { |
|---|
| 110 | return selfParameterIndex; |
|---|
| 111 | } |
|---|
| 112 | |
|---|
| 113 | public FTraitOrObjectOrGeneric getSelfParameterType() { |
|---|
| 114 | return selfParameterType; |
|---|
| 115 | } |
|---|
| 116 | |
|---|
| 117 | public String toString() { |
|---|
| 118 | String res = s(def) + "fn meth(self " + selfParameterIndex + ")"; |
|---|
| 119 | if (instArgs != null) res += Useful.listInOxfords(instArgs); |
|---|
| 120 | if (type() != null) { |
|---|
| 121 | res += ":" + type(); |
|---|
| 122 | } else { |
|---|
| 123 | res += " [no type]"; |
|---|
| 124 | } |
|---|
| 125 | return res + " (" + def.at() + ")"; |
|---|
| 126 | } |
|---|
| 127 | |
|---|
| 128 | } |
|---|