use of ast.ExpCore.MCall in project L42 by ElvisResearchGroup.
the class MethodPathCloneVisitor method visit.
public ExpCore visit(MCall s) {
Program ep = p;
for (ClassB cbi : this.getLocator().getCbs()) {
if (cbi != null) {
ep = ep.evilPush(cbi);
}
}
MethodSelector ms = s.getS();
Path guessed = null;
try {
TIn in = TIn.top(Phase.Typed, ep, s.getInner());
in = in.withG(varEnv.entrySet().stream().collect(Collectors.toMap(me -> me.getKey(), me -> new java.util.AbstractMap.SimpleEntry<>(false, me.getValue()))));
Type tGuessed = newTypeSystem.GuessTypeCore._of(in.p, in, s.getInner());
if (tGuessed == null) {
return super.visit(s);
}
guessed = tGuessed.getPath();
assert guessed != null;
} catch (NormImpossible ignored) {
return super.visit(s);
}
MethodSelector ms2 = visitMS(ms, guessed);
if (ms2.equals(ms)) {
return super.visit(s);
}
s = new MCall(s.getInner(), ms2, s.getDoc(), s.getEs(), s.getP());
return super.visit(s);
}
use of ast.ExpCore.MCall in project L42 by ElvisResearchGroup.
the class UsedPaths method collectNotAnyPaths.
private static List<Ast.Path> collectNotAnyPaths(Program p, ExpCore e) {
class HeuristicForNotAnyPathsSplit extends PropagatorVisitor {
public Void visit(ClassB s) {
return null;
}
protected List<Path> paths = new ArrayList<Path>();
private void add(Path p) {
this.paths.add(p);
}
//non determinism heuristic:
//**if P.m(_) inside e, P not Any
public Void visit(MCall s) {
Path p = justPath(s.getInner());
if (p != null) {
add(p);
}
return super.visit(s);
}
//**if ( _ T x=P _ _) inside e and T!=class Any, P not Any.
//**if (mdf P x=_ _) inside e, P not Any
protected void liftDec(Block.Dec s) {
if (s.getT().isPresent()) {
Path pt = s.getT().get().getPath();
if (!pt.isPrimitive()) {
add(pt);
}
}
Path p = justPath(s.getInner());
if (p != null) {
add(p);
}
super.liftDec(s);
}
private Path justPath(ExpCore e) {
if (e instanceof ExpCore.EPath) {
if (!((ExpCore.EPath) e).getInner().isPrimitive()) {
return ((ExpCore.EPath) e).getInner();
}
}
if (e instanceof ExpCore.Block) {
return justPath(((ExpCore.Block) e).getInner());
}
return null;
}
//**if p(Pi).Cache=Typed, Pi is not Any
@Override
protected void liftP(Path s) {
if (s.isPrimitive()) {
return;
}
try {
if (p.extractClassB(s).getPhase() == Phase.Typed) {
super.liftP(s);
return;
}
} catch (ErrorMessage.PathMetaOrNonExistant pne) {
/*we do not rise this error while computing the heuristic*/
}
}
//**if using P _ _ inside e, P not Any
public Void visit(ExpCore.Using s) {
if (!s.getPath().isPrimitive()) {
add(s.getPath());
}
return super.visit(s);
}
//**if catch T inside e, T.P not Any
protected void liftO(ExpCore.Block.On on) {
Path pOn = on.getT().getPath();
if (!pOn.isPrimitive()) {
add(pOn);
}
super.liftO(on);
}
List<Path> result(ExpCore e) {
e.accept(this);
return this.paths;
}
}
return new HeuristicForNotAnyPathsSplit().result(e);
}
use of ast.ExpCore.MCall in project L42 by ElvisResearchGroup.
the class TsMCall method tsMCall.
default default TOut tsMCall(TIn in, MCall s) {
Type _rec = GuessTypeCore._of(in.p, in, s.getInner());
if (_rec == null) {
return new TErr(in, "", null, ErrorKind.SelectorNotFound);
}
Path rec = _rec.getPath();
if (rec.isPrimitive()) {
return new TErr(in, "MethodCall on primitive type", null, ErrorKind.SelectorNotFound);
}
MethodType mDec = AlternativeMethodTypes._mtDeclared(in.p, rec, s.getS());
if (mDec == null) {
return new TErr(in, "", null, ErrorKind.SelectorNotFound);
}
Type ret = mDec.getReturnType();
ErrorKind kind = TypeSystem.subtype(in.p, ret.getPath(), in.expected.getPath());
if (kind != null) {
return new TErr(in, "", ret, kind);
}
List<MethodType> mTypes = AlternativeMethodTypes.types(mDec);
MethodType mType = AlternativeMethodTypes._firstMatchReturn(in.p, in.expected, mTypes);
if (mType == null) {
return new TErr(in, "", ret, ErrorKind.NotSubtypeMdf);
}
//unachievable return type (T) for method (P.ms) [line numbers of expression and declaration]
//2 type all the parameters with mutOnlyToLent(Ts) //we may include mutOnlyToLent in the computation of the MTypes, instead of in the loop below
List<TOk> resp = new ArrayList<>();
List<Type> computed = new ArrayList<>();
List<ExpCore> annotated = new ArrayList<>();
ExpCore e0 = s.getInner();
Type t0 = new Type(mType.getMdf(), rec, Doc.empty());
TOut _res0 = type(in.withE(e0, TypeManipulation.mutOnlyToLent(t0)));
if (!_res0.isOk()) {
return improveReceiverError(in, t0, _res0.toError());
}
TOk res0 = _res0.toOk();
Mdf recMdf = _res0.toOk().computed.getMdf();
{
int i = -1;
for (ExpCore ei : s.getEs()) {
i += 1;
Type ti = mType.getTs().get(i);
TOut _resi = type(in.withE(ei, TypeManipulation.mutOnlyToLent(ti)));
if (!_resi.isOk()) {
return _resi.toError();
}
resp.add(_resi.toOk());
computed.add(_resi.toOk().computed);
annotated.add(_resi.toOk().annotated);
}
}
MethodType computedMt = new MethodType(false, recMdf, computed, in.expected, Collections.emptyList());
MethodType mTypeRev = AlternativeMethodTypes._bestMatchMtype(in.p, computedMt, mTypes);
if (mTypeRev != null) {
MCall resM = new MCall(res0.annotated, s.getS(), s.getDoc(), annotated, s.getP());
TOk res = new TOk(in, resM, mTypeRev.getReturnType());
// Trs[with r in resp (use[r.Tr])].collapse())
res = res.trUnion(res0);
for (TOk oki : resp) {
res = res.trUnion(oki);
}
return res;
}
//3 if there is no matching method, we may need to retype some mut
//in capsule caused by mvp:
//it is not over if there is a mathing method type with mutToCapsule(result param types)
//tsToCaps=Ts[with r in resp (use[mutToCapsule(r.T)])]
//mTypeMVP=_bestMatchMtype(tsToCaps,TSIn.T,mTypes)
List<Type> tsToCaps = new ArrayList<>();
for (TOk r : resp) {
Mdf m = r.computed.getMdf();
if (m == Mdf.MutableFwd || m == Mdf.MutablePFwd) {
return new TErr(in, "impossible to search for mvp since mdf " + m, mTypes.get(0).getReturnType(), ErrorKind.NotSubtypeClass);
}
Type nt = TypeManipulation.mutToCapsule(r.computed);
tsToCaps.add(nt);
}
computedMt = computedMt.withTs(tsToCaps).withMdf(TypeManipulation.mutToCapsule(computedMt.getMdf()));
MethodType mTypeMVP = AlternativeMethodTypes._bestMatchMtype(in.p, computedMt, mTypes);
if (mTypeMVP == null) {
return new TErr(in, "mvp candidate notfound", mTypes.get(0).getReturnType(), ErrorKind.NotSubtypeClass);
}
//To be happy, we can retype the obtained mut parameters into expected capsule
TOut _newRes0 = innerMVPRetype(res0, t0.withMdf(mTypeMVP.getMdf()));
if (!_newRes0.isOk()) {
return _newRes0;
}
TOk newRes0 = _newRes0.toOk();
List<TOk> newResp = new ArrayList<>();
{
int i = -1;
for (TOk ri : resp) {
i += 1;
Type ti = mTypeMVP.getTs().get(i);
TOut outi = innerMVPRetype(ri, ti);
if (!outi.isOk()) {
return outi.toError();
}
newResp.add(outi.toOk());
}
}
//return res=makeMCallOK(TSIn,respMVP,mTypeMVP)
MCall resM = new MCall(newRes0.annotated, s.getS(), s.getDoc(), Map.of(r -> r.annotated, newResp), s.getP());
TOk res = new TOk(in, resM, mTypeMVP.getReturnType());
// Trs[with r in resp (use[r.Tr])].collapse())
res = res.trUnion(newRes0);
for (TOk oki : newResp) {
res = res.trUnion(oki);
}
return res;
}
use of ast.ExpCore.MCall in project L42 by ElvisResearchGroup.
the class InjectionOnSugar method visit.
@Override
public Expression visit(MCall s) {
ast.Expression receiver = lift(s.getInner());
String name = s.getS().nameToS();
Doc docs = s.getDoc();
List<String> xs = s.getS().getNames();
List<ast.ExpCore> es1 = s.getEs();
List<ast.Expression> es = new ArrayList<ast.Expression>();
for (ast.ExpCore e : es1) {
es.add(lift(e));
}
ast.Ast.Parameters ps = new ast.Ast.Parameters(Optional.<ast.Expression>empty(), xs, es);
Position pos = s.getP();
return new Expression.MCall(receiver, name, docs, ps, pos);
}
use of ast.ExpCore.MCall in project L42 by ElvisResearchGroup.
the class PlgWrapperGenerator method updateTemplateUsing.
private static MethodWithType updateTemplateUsing(UsingInfo ui, MethodWithType mwt) {
MCall e = templateUsingExc;
MethodType mt = mwt.getMt();
ExpCore.Block b = (Block) e.getEs().get(0);
if (mwt.getMt().getExceptions().isEmpty()) {
b = b.withOns(Collections.emptyList());
}
ExpCore.Using u = (Using) b.getDecs().get(0).getInner();
//parameter expressions
ExpCore.MCall p0 = (MCall) u.getEs().get(0);
//e#mcall.inner<-mwt.retType.path
e = e.withInner(ExpCore.EPath.wrap(mt.getReturnType().getPath()));
//u=u.withS(ui.usingMs);
List<ExpCore> ues = new ArrayList<>();
if (mt.getMdf() != Mdf.Class) {
ues.add(p0.withInner(new ExpCore.X(mwt.getP(), "this")));
}
{
int i = -1;
for (String x : mwt.getMs().getNames()) {
i++;
ExpCore pi = new ExpCore.X(mwt.getP(), x);
boolean needAddBinaryRepr = true;
Type ti = mwt.getMt().getTs().get(i);
if (ti.equals(Type.immLibrary)) {
needAddBinaryRepr = false;
}
if (ti.getMdf() == Mdf.Class) {
needAddBinaryRepr = false;
}
if (needAddBinaryRepr) {
pi = p0.withInner(pi);
}
ues.add(pi);
}
}
u = new Using(u.getPath(), ui.usingMs, u.getDoc(), ues, u.getInner());
String errorS = "plugin string: " + ui.plgInfo.plgString + "\n" + "plugin part: " + ui.plgInfo.plgName + "\n" + "method name: " + mwt.getMs() + "\n" + "java method: " + ui.plgInfo.plgClass.getName() + "." + ui.usingMs + "\n";
//u.inner#mcall.es(0)<-EncodingHelper.wrapStringU()
List<ExpCore> errorEs = Collections.singletonList(EncodingHelper.wrapStringU(errorS));
Signal tmpS = (Signal) u.getInner();
MCall tmpMc = ((MCall) tmpS.getInner()).withEs(errorEs);
u = u.withInner(tmpS.withInner(tmpMc));
b = b.withDecs(Collections.singletonList(b.getDecs().get(0).withInner(u)));
//--
if (!mwt.getMt().getExceptions().isEmpty()) {
On on = b.getOns().get(0);
Dec k0 = ((Block) on.getInner()).getDecs().get(0);
List<Dec> ks = new ArrayList<>();
{
int i = -1;
for (Type ti : mt.getExceptions()) {
i++;
MCall mci = ((MCall) k0.getInner()).withInner(ExpCore.EPath.wrap(ti.getPath()));
ks.add(k0.withInner(mci).withX(k0.getX() + i));
}
}
on = on.withInner(((Block) on.getInner()).withDecs(ks));
b = b.withOns(Collections.singletonList(on));
//k0=b.k(0).inner#block.decs(0)
//k0 add more on need
//ki.inner#mcall.inner<-Pi
}
if (ui.isVoid) {
b = b.withDecs(Collections.singletonList(b.getDecs().get(0).withT(Optional.of(Type.immVoid))));
}
if (!ui.isVoid && !mwt.getMt().getReturnType().equals(Type.immLibrary)) {
e = e.withEs(Collections.singletonList(b));
mwt = mwt.withInner(e);
} else {
mwt = mwt.withInner(b);
}
return mwt;
}
Aggregations