Beispiel #1
0
        public static FinalizedResponse MembAcc_AC(TokLinePlanB <PTok> orig_TL, TokLinePlanB <PTok> .CPosC pos, MGRX.MemANodeRX MA_node, Responder RESP)
        {
            #region setup

            string orig_prefix = MA_node.name;                                   // <- .name is normalized to "" , never null
            MembK  orig_MembK  = MembKF_from_refineTok(MA_node.refineOPTok);     // resolves to "_any" for null argument


            MemberInfo[] mis      = new MemberInfo[0];
            Type         baseType = null;
            try {
                // i *THINK* ACMembTypingCallback is supposed to be set at creation time of the corresponding TranslationUnit ( i.e. its constructor)  - this is not happening atm
                // fetch the type here to base SuggTreeFetching of MethodInfos on, the MembKFilter argument to that thing is something else entirely



                baseType = (MA_node as MG.ACableMemb).ACMembTypingCallback();
            } catch (MG.NoACPossible) {     // <- questionable if this exception is needed at all
                return(RESP.NoAC("excpt: MG.NoACPossible"));
            } catch (Exception e) {
                return(RESP.NoAC("general typing exception: " + e.ToString()));
            }
            if (baseType == null)
            {
                return(RESP.NoAC("baseType == null "));
            }

            try {
                mis = SGA.MembAC(baseType, orig_prefix, orig_MembK);
            } catch (Exception)  { return(RESP.NoAC(" SuggTree exception ")); }
            if (mis.Length == 0)
            {
                return(RESP.NoAC(" no suggs "));
            }


            #endregion

            string new_prefix = SGA.LongestCommonPrefix(mis.Select(mi => mi.Name).ToArray());

            bool insert_refinement = (MA_node.refineOPTok == null) && (mis.Length == 1);                    // current strat : only augment refinement op if suggestions are unique
            bool insert_name       = (MA_node.nameTok == null) /* && ( new_prefix.Length > 0 ) */;          // actually ... it's easier to always insert

            // --- if both refinement, and name are to be inserted: insert refinement first

            if (insert_refinement)
            {
                orig_TL.InsertTokAfterNode(
                    orig_TL.findTok(MA_node.initialOpTok),
                    refineTok_from_MembK(new MembK(mis[0]))      // implicitly assuming mis[] to be of length 1, or their MembKs to be identical in case of several
                    );
            }

            if (insert_name)
            {
                var new_nameTok = new PTok {
                    E = PTokE.CS_name, pay = new_prefix
                };
                pos = orig_TL.InsertAfterCPos(pos, new_nameTok);
            }
            else
            {
                // a nice invariant to fuzz against :  for all x ::   SG.MembAcc(x). map ( -> name ). LongestCommonPrefix().Length >= x.Length  ( this is implitily assumed here )
                // counter case : len ( longestCommonPrefix ) < len( MA_node.name ) should never reach this ( cuz mis == [] triggers return further up )
                D.Assert(new_prefix.Length >= orig_prefix.Length);
                MA_node.nameTok.pay = new_prefix;
                pos = orig_TL.CPosAtEndOfTok(MA_node.nameTok);
            }
            Func <MemberInfo, mi_sugg> conv_mi_sugg = (MI) => {
                var str_op = refineTok_from_MembK(new MembK(MI)).pay;
                return(new mi_sugg {
                    str_op = str_op,
                    mi = MI
                });
            };
            PTokBase [] nu_toks = orig_TL.Serialize <PTokBase>(onTok: _ => _, onWS: i => new PTokWhitespace {
                len = i
            }).ToArray();

            return(RESP.MembACWithSubst(mis.Select(conv_mi_sugg), nu_toks, pos.StringPos()));
        }