Search in sources :

Example 16 with MethodType

use of ast.Ast.MethodType in project L42 by ElvisResearchGroup.

the class AlternativeMethodTypes method _bestMatchMtype.

public static MethodType _bestMatchMtype(Program p, MethodType superMt, List<MethodType> mts) {
    List<MethodType> res = new ArrayList<>();
    for (MethodType mt : mts) {
        if (TypeSystem._methMdfTSubtype(mt, superMt)) {
            if (!res.stream().anyMatch(mti -> TypeSystem._methMdfTSubtype(mti, mt))) {
                res = res.stream().filter(mti -> !TypeSystem._methMdfTSubtype(mt, mti)).collect(Collectors.toList());
                //if there is no method that is even better, add
                res.add(mt);
            }
        }
    }
    //assert res.size()==1: res.size(); sometime is false, for example capsule->capsule and mut->mut
    if (res.isEmpty()) {
        return null;
    }
    if (res.size() == 1) {
        return res.get(0);
    }
    //for final limitations
    List<MethodType> _res = res;
    Optional<MethodType> res1 = res.stream().filter(mt1 -> _res.stream().allMatch(mt2 -> Functions.isSubtype(mt1.getReturnType().getMdf(), mt2.getReturnType().getMdf()))).findAny();
    if (res1.isPresent()) {
        return res1.get();
    }
    assert false : "";
    return res.get(0);
}
Also used : From(coreVisitors.From) WellFormednessCore(auxiliaryGrammar.WellFormednessCore) Program(programReduction.Program) Path(ast.Ast.Path) TypeManipulation(newTypeSystem.TypeManipulation) Map(tools.Map) Type(ast.Ast.Type) MethodType(ast.Ast.MethodType) Member(ast.ExpCore.ClassB.Member) MethodWithType(ast.ExpCore.ClassB.MethodWithType) Functions(auxiliaryGrammar.Functions) Collectors(java.util.stream.Collectors) MethodSelector(ast.Ast.MethodSelector) ArrayList(java.util.ArrayList) List(java.util.List) Optional(java.util.Optional) Mdf(ast.Ast.Mdf) MethodType(ast.Ast.MethodType) ArrayList(java.util.ArrayList)

Example 17 with MethodType

use of ast.Ast.MethodType in project L42 by ElvisResearchGroup.

the class TsLibrary method coherentF.

static boolean coherentF(Program p, MethodWithType ck, MethodWithType mwt) {
    MethodType mt = mwt.getMt();
    Mdf m = mt.getMdf();
    if (mwt.getMs().getUniqueNum() != ck.getMs().getUniqueNum()) {
        return false;
    }
    // internally do noFwd
    Type Ti = _extractTi(ck, mwt.getMs().getName());
    if (Ti == null) {
        return false;
    }
    //if(m==Mdf.Class){return false;}
    if (m == Mdf.Readable || m == Mdf.Immutable) {
        //getter
        if (!mt.getTs().isEmpty()) {
            return false;
        }
        Type Ti_ = TypeManipulation._toRead(Ti);
        //p|-toRead(Ti)<=T
        if (Ti_ == null) {
            return false;
        }
        if (null != TypeSystem.subtype(p, Ti_, mt.getReturnType())) {
            return false;
        }
        return true;
    }
    if (m != Mdf.Mutable) {
        return false;
    }
    //exposer/setter
    if (mt.getTs().isEmpty()) {
        //exposer
        Type Ti_ = TypeManipulation.capsuleToLent(Ti);
        //p|-capsuleToLent(Ti)<=T
        if (Ti_ == null) {
            return false;
        }
        if (null != TypeSystem.subtype(p, Ti_, mt.getReturnType())) {
            return false;
        }
        return true;
    }
    //setter refine? mut method Void m[n?](T that)
    if (!mt.getReturnType().equals(Type.immVoid)) {
        return false;
    }
    if (mt.getTs().size() != 1) {
        return false;
    }
    if (!mwt.getMs().getNames().get(0).equals("that")) {
        return false;
    }
    Type T = mt.getTs().get(0);
    if (null != TypeSystem.subtype(p, Ti, T)) {
        return false;
    }
    if (Ti.getMdf() == Mdf.Readable) {
        Mdf mT = T.getMdf();
        if (mT != Mdf.Capsule && mT != Mdf.Immutable) {
            return false;
        }
    }
    return true;
}
Also used : MethodType(ast.Ast.MethodType) Type(ast.Ast.Type) MethodType(ast.Ast.MethodType) MethodWithType(ast.ExpCore.ClassB.MethodWithType) Mdf(ast.Ast.Mdf)

Example 18 with MethodType

use of ast.Ast.MethodType in project L42 by ElvisResearchGroup.

the class TsLibrary method memberMethod.

default default TOutM memberMethod(TIn in, List<Type> supertypes, MethodWithType mwt) {
    //(member method)
    //Phase| p| Ps |-M ~> M'
    //  where
    //  M =refine? mdf method T m(T1 x1 .. Tn xn)exceptions Ps0 e?
    //  M'=refine? mdf method T m(T1 x1 .. Tn xn)exceptions Ps0 e?'
    //  G=this:mdf This0,x1:T1,..,xn:Tn
    //  if e?=e then
    //  Typed| p| G |- e ~>  e?':_ <=fwd% T | empty;Ps1
    //  forall P1 in Ps1 exists P0 in Ps0 such that p|-P1<=P0
    //else
    //  e?=e?'
    MethodWithType mwt1;
    if (!mwt.get_inner().isPresent()) {
        mwt1 = mwt;
    } else {
        TIn newIn = in.freshGFromMt(mwt);
        TOut out = type(newIn);
        if (!out.isOk()) {
            return out.toError();
        }
        for (Path P1 : out.toOk().exceptions) {
            //exists P0 in Ps0 such that p|-P1<=P0
            boolean ok = mwt.getMt().getExceptions().stream().anyMatch(P0 -> null == TypeSystem.subtype(newIn.p, P1, P0.getPath()));
            if (!ok) {
                return new TErr(newIn, "", P1.toImmNT(), ErrorKind.MethodLeaksExceptions);
            }
        }
        if (!out.toOk().returns.isEmpty()) {
            return new TErr(newIn, "", out.toOk().returns.get(0), ErrorKind.MethodLeaksReturns);
        }
        mwt1 = mwt.with_inner(Optional.of(out.toOk().annotated));
    }
    if (mwt.getMt().isRefine()) {
        //      /or  method declares an exception (P) which is not a subtype of ancestor exceptions 
        for (Type t : supertypes) {
            Path P = t.getPath();
            ClassB cbP = in.p.extractClassB(P);
            MethodWithType mwtP = (MethodWithType) cbP._getMember(mwt.getMs());
            if (mwtP == null) {
                continue;
            }
            MethodType M0 = From.from(mwtP.getMt(), P);
            ErrorKind kind = TypeSystem.subtype(in.p, mwt.getMt().getReturnType(), M0.getReturnType());
            if (kind != null) {
                return new TErr(in, "", P.toImmNT(), ErrorKind.InvalidImplements);
            }
            {
                int i = -1;
                for (Type Ti : mwt.getMt().getTs()) {
                    i += 1;
                    Type T1i = M0.getTs().get(i);
                    if (!in.p.equiv(Ti, T1i)) {
                        return new TErr(in, "", P.toImmNT(), ErrorKind.InvalidImplements);
                    }
                }
            }
            for (Type Pi : mwt.getMt().getExceptions()) {
                //exists Pj in Ps' such that p |- Pi<=Pj
                boolean ok = M0.getExceptions().stream().anyMatch(Pj -> null == TypeSystem.subtype(in.p, Pi.getPath(), Pj.getPath()));
                if (!ok) {
                    return new TErr(in, "", P.toImmNT(), ErrorKind.InvalidImplements);
                }
            }
        }
    }
    return new TOkM(mwt1);
}
Also used : Path(ast.Ast.Path) MethodType(ast.Ast.MethodType) Type(ast.Ast.Type) MethodType(ast.Ast.MethodType) MethodWithType(ast.ExpCore.ClassB.MethodWithType) MethodWithType(ast.ExpCore.ClassB.MethodWithType) ClassB(ast.ExpCore.ClassB)

Example 19 with MethodType

use of ast.Ast.MethodType in project L42 by ElvisResearchGroup.

the class TsLibrary method coherentK.

//coherent(n?,p,T1 x1..Tn xn,
//refine? class method T m[n?] (T1' x1..Tn' xn) exception _)
//where
//p|- This0 <=T.P and p|-Ti'<=fwd Ti
//T.mdf!=class and if T.mdf in {imm,capsule}, mut notin (T1..Tn).mdfs
static boolean coherentK(Program p, MethodWithType ck) {
    MethodType mt = ck.getMt();
    if (mt.getMdf() != Mdf.Class) {
        return false;
    }
    Type rt = mt.getReturnType();
    if (null != TypeSystem.subtype(p, Path.outer(0), rt.getPath())) {
        return false;
    }
    Mdf m = rt.getMdf();
    if (m == Mdf.Class) {
        return false;
    }
    boolean immOrC = (m == Mdf.Immutable || m == Mdf.Capsule);
    boolean lentOrR = (m == Mdf.Lent || m == Mdf.Readable);
    int allowedR = lentOrR ? 1 : 0;
    for (Type ti : mt.getTs()) {
        Mdf mi = ti.getMdf();
        if (mi == Mdf.Lent) {
            return false;
        }
        if (mi == Mdf.Readable) {
            if (allowedR == 0) {
                return false;
            }
            allowedR -= 1;
        }
        if (immOrC & (mi == Mdf.Mutable || mi == Mdf.MutableFwd)) {
            return false;
        }
    }
    return true;
}
Also used : MethodType(ast.Ast.MethodType) Type(ast.Ast.Type) MethodType(ast.Ast.MethodType) MethodWithType(ast.ExpCore.ClassB.MethodWithType) Mdf(ast.Ast.Mdf)

Example 20 with MethodType

use of ast.Ast.MethodType 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;
}
Also used : Path(ast.Ast.Path) Path(ast.Ast.Path) MCall(ast.ExpCore.MCall) Map(tools.Map) Doc(ast.Ast.Doc) Type(ast.Ast.Type) Assertions(tools.Assertions) MethodType(ast.Ast.MethodType) ExpCore(ast.ExpCore) Functions(auxiliaryGrammar.Functions) ArrayList(java.util.ArrayList) List(java.util.List) Collections(java.util.Collections) Mdf(ast.Ast.Mdf) MethodType(ast.Ast.MethodType) ExpCore(ast.ExpCore) ArrayList(java.util.ArrayList) Mdf(ast.Ast.Mdf) Type(ast.Ast.Type) MethodType(ast.Ast.MethodType) MCall(ast.ExpCore.MCall)

Aggregations

MethodType (ast.Ast.MethodType)48 Type (ast.Ast.Type)32 MethodWithType (ast.ExpCore.ClassB.MethodWithType)25 Mdf (ast.Ast.Mdf)14 MethodSelector (ast.Ast.MethodSelector)14 ArrayList (java.util.ArrayList)14 Path (ast.Ast.Path)10 ExpCore (ast.ExpCore)9 List (java.util.List)9 Collections (java.util.Collections)8 Functions (auxiliaryGrammar.Functions)7 Test (org.junit.Test)7 Doc (ast.Ast.Doc)6 MethodWithType (ast.Expression.ClassB.MethodWithType)6 HashMap (java.util.HashMap)6 Program (programReduction.Program)6 Ast (ast.Ast)5 ClassB (ast.ExpCore.ClassB)5 Member (ast.ExpCore.ClassB.Member)5 Optional (java.util.Optional)5