| 1 |
/******************************************************************************* |
|---|
| 2 |
Copyright 2008 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 |
|
|---|
| 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 |
|
|---|
| 23 |
import java.util.List; |
|---|
| 24 |
|
|---|
| 25 |
import com.sun.fortress.interpreter.evaluator.Environment; |
|---|
| 26 |
import com.sun.fortress.interpreter.evaluator.types.FTraitOrObjectOrGeneric; |
|---|
| 27 |
import com.sun.fortress.interpreter.evaluator.types.FType; |
|---|
| 28 |
import com.sun.fortress.nodes_util.Applicable; |
|---|
| 29 |
import com.sun.fortress.nodes_util.NodeUtil; |
|---|
| 30 |
import com.sun.fortress.useful.AssignedList; |
|---|
| 31 |
import com.sun.fortress.useful.HasAt; |
|---|
| 32 |
import com.sun.fortress.useful.Useful; |
|---|
| 33 |
|
|---|
| 34 |
public class FunctionalMethod extends Closure implements HasSelfParameter { |
|---|
| 35 |
|
|---|
| 36 |
final private int selfParameterIndex; |
|---|
| 37 |
final private FTraitOrObjectOrGeneric selfParameterType; |
|---|
| 38 |
final private String mname; |
|---|
| 39 |
|
|---|
| 40 |
public FunctionalMethod(Environment e, Applicable fndef, int self_parameter_index, FTraitOrObjectOrGeneric self_parameter_type) { |
|---|
| 41 |
super(e, fndef, true); |
|---|
| 42 |
selfParameterIndex = self_parameter_index; |
|---|
| 43 |
selfParameterType = self_parameter_type; |
|---|
| 44 |
mname = NodeUtil.nameAsMethod(getDef()); |
|---|
| 45 |
// TODO Auto-generated constructor stub |
|---|
| 46 |
} |
|---|
| 47 |
|
|---|
| 48 |
protected FunctionalMethod(Environment e, Applicable fndef, List<FType> static_args, int self_parameter_index, FTraitOrObjectOrGeneric self_parameter_type) { |
|---|
| 49 |
super(e, fndef, static_args); |
|---|
| 50 |
selfParameterIndex = self_parameter_index; |
|---|
| 51 |
selfParameterType = self_parameter_type; |
|---|
| 52 |
mname = NodeUtil.nameAsMethod(getDef()); |
|---|
| 53 |
// TODO Auto-generated constructor stub |
|---|
| 54 |
} |
|---|
| 55 |
|
|---|
| 56 |
public MethodClosure getApplicableClosure(List<FValue> args0, |
|---|
| 57 |
HasAt loc, Environment envForInference) { |
|---|
| 58 |
FValue selfVal = args0.get(selfParameterIndex); |
|---|
| 59 |
DottedMethodApplication ma = |
|---|
| 60 |
DottedMethodApplication.make(selfVal,s(def),mname,loc); |
|---|
| 61 |
Method cl = ma.getMethod(); |
|---|
| 62 |
if (cl instanceof MethodClosure) { |
|---|
| 63 |
return (MethodClosure)cl; |
|---|
| 64 |
} else if (cl instanceof OverloadedMethod) { |
|---|
| 65 |
List<FValue> args = Useful.removeIndex(selfParameterIndex,args0); |
|---|
| 66 |
OverloadedMethod om = (OverloadedMethod)cl; |
|---|
| 67 |
return om.getApplicableMethod(args,loc,envForInference); |
|---|
| 68 |
} else { |
|---|
| 69 |
return bug(loc,envForInference, |
|---|
| 70 |
errorMsg("Functional method resolution for ",this,args0, |
|---|
| 71 |
" yields non-MethodClosure ",cl)); |
|---|
| 72 |
} |
|---|
| 73 |
} |
|---|
| 74 |
|
|---|
| 75 |
/* (non-Javadoc) |
|---|
| 76 |
* @see com.sun.fortress.interpreter.evaluator.values.Closure#applyInner(java.util.List, com.sun.fortress.interpreter.useful.HasAt, com.sun.fortress.interpreter.env.BetterEnv) |
|---|
| 77 |
*/ |
|---|
| 78 |
@Override |
|---|
| 79 |
public FValue applyInner(List<FValue> args, HasAt loc, Environment envForInference) { |
|---|
| 80 |
FValue selfVal = args.get(selfParameterIndex); |
|---|
| 81 |
args = Useful.removeIndex(selfParameterIndex, args); |
|---|
| 82 |
return DottedMethodApplication.invokeMethod(selfVal, s(def), mname, args, |
|---|
| 83 |
loc, envForInference); |
|---|
| 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() + |
|---|
| 94 |
(instArgs == null ? 0 : instArgs.hashCode()); |
|---|
| 95 |
} |
|---|
| 96 |
|
|---|
| 97 |
public boolean equals(Object o) { |
|---|
| 98 |
if (this == o) return true; |
|---|
| 99 |
if (o.getClass().equals(this.getClass())) { |
|---|
| 100 |
FunctionalMethod oc = (FunctionalMethod) o; |
|---|
| 101 |
return def == oc.def && |
|---|
| 102 |
selfParameterType.equals(oc.selfParameterType) && |
|---|
| 103 |
(instArgs == null ? (oc.instArgs == null) : |
|---|
| 104 |
oc.instArgs == null ? false : 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)+ |
|---|
| 119 |
"fn meth(self "+selfParameterIndex+")"; |
|---|
| 120 |
if (instArgs != null) |
|---|
| 121 |
res += Useful.listInOxfords(instArgs); |
|---|
| 122 |
if (type() != null) { |
|---|
| 123 |
res += ":" + type(); |
|---|
| 124 |
} else { |
|---|
| 125 |
res += " [no type]"; |
|---|
| 126 |
} |
|---|
| 127 |
return res+" ("+def.at()+")"; |
|---|
| 128 |
} |
|---|
| 129 |
|
|---|
| 130 |
} |
|---|