From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Eric Ludlam Newsgroups: gmane.emacs.devel Subject: Re: completion-at-point + semantic : erroneous error Date: Sat, 12 Oct 2019 07:56:57 -0400 Message-ID: <9cf7e484-9a86-ab1c-b04f-9dc3e7c91974@gmail.com> References: <957ad127-0d84-69e3-49b6-9799975bd724@siege-engine.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="123368"; mail-complaints-to="usenet@blaine.gmane.org" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.9.0 Cc: Emacs Development To: Stefan Monnier , Eric Ludlam Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sat Oct 12 13:57:48 2019 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1iJG1r-000Vzn-Md for ged-emacs-devel@m.gmane.org; Sat, 12 Oct 2019 13:57:47 +0200 Original-Received: from localhost ([::1]:60566 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iJG1q-0005pQ-JL for ged-emacs-devel@m.gmane.org; Sat, 12 Oct 2019 07:57:46 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:47206) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iJG1A-0005jQ-CL for emacs-devel@gnu.org; Sat, 12 Oct 2019 07:57:06 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iJG17-0003nz-Uj for emacs-devel@gnu.org; Sat, 12 Oct 2019 07:57:04 -0400 Original-Received: from mail-qk1-x72f.google.com ([2607:f8b0:4864:20::72f]:34404) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iJG17-0003nq-Nj for emacs-devel@gnu.org; Sat, 12 Oct 2019 07:57:01 -0400 Original-Received: by mail-qk1-x72f.google.com with SMTP id q203so11414569qke.1 for ; Sat, 12 Oct 2019 04:57:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-transfer-encoding:content-language; bh=w7RCqrfgMCleG2fmDt/qePlkBTjRVfbTbZVKYY5Q6qs=; b=RV+wNkWSLPEIdA1oN+ejEslLgA4SIGzLwTmKYUrIdW9OF1N9CHGobMDrZ0Q382RHrZ 6gkN+w5EJM1n2GlpifZHBMNWzBsdBkvZ+MmhWJemTslXZTvHLgmPSHwWpzPycP78FnkJ iCoTyBF5tIxaMNilTY4xV07/op/20L+u5uC4Dgh6wCLudliajc8alv29Qc6TWr0iOElz zKZ7xvlS0WyhiBPXfJzHjby4F/8PJ58SuB4VOKCJ24jPtXuDNEzwQzifGrp/Shtux0ZI jhJuT+EFqTSoLfsA3Wsh+ILLdGnChm4CcVt1EdAMaBY+O/3o11tO71e7HmrPK/ALQh2e lOCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-transfer-encoding :content-language; bh=w7RCqrfgMCleG2fmDt/qePlkBTjRVfbTbZVKYY5Q6qs=; b=q6loTnBe1Pa1qWUWYYGKENJzWue0Hbwfie7VZXE2XUcI3qFHvJtlEEBY+Xki+kwABK faZ8h7ABD+DOha8B0cA7L8x9wurVRe0j9jhhi9DjK5by/S6m2YoR41nSeRosVJH8R5dj 9BhuvZbsvsREESivQSJv9zAWvwTqf9qeKseIFwYRF7d2XAturhsUfgh5gAp/ZrN7CYyj lQsXdDwoymUIexjWXPRezxiMcZIZfzTplV/VlbDfApjYIQKWX3yJ5dJCAHluXXuo9QNq 7Ic3NK1xza9YE4vzTxkXWda6CUPNbLZ/f+22qW60PqoGexzuyGJgKucHAJPlvsb7/+ru WTeg== X-Gm-Message-State: APjAAAWM7xIAdIwvBeUxGdm1qiiC9de9PbbkQJn9CW28Ngt+eLBgoU6R owz3OYodUOXF+P74pYu+XczU+6SqhG0= X-Google-Smtp-Source: APXvYqxXeleouCmh35SD/5tqqOknIJkmvHq01en+hTKz0BDjZvy05dXxOHwEl3xHYEnmXv0JEFuMwA== X-Received: by 2002:a37:b981:: with SMTP id j123mr21471906qkf.205.1570881419949; Sat, 12 Oct 2019 04:56:59 -0700 (PDT) Original-Received: from [192.168.1.202] (pool-108-20-30-136.bstnma.fios.verizon.net. [108.20.30.136]) by smtp.googlemail.com with ESMTPSA id p7sm5521655qkc.21.2019.10.12.04.56.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 12 Oct 2019 04:56:58 -0700 (PDT) In-Reply-To: Content-Language: en-US X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::72f X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:240911 Archived-At: On 10/11/19 1:34 PM, Stefan Monnier wrote: >> PS: It would also be good to replace uses of >> define-overloadable-function with cl-defmethod, although the mapping >> from one to the other is not immediate. > The patch below is an attempt to do that for > semantic-analyze-possible-completions. I'd be interested to hear your > opinion on this (especially the with-mode-local part). > Hi Stefan, As a followup, I started using the shorter version of your patch, and found there are additional errors thrown from semantic-analyze-possible-completions-default (what will be a method in your patch).  I had to eliminate those errors to fully clean up the original problem that started this thread. I used catch/throw to solve the problem (see below: patch is against the original semantic/analyze/complete.el, not your patched version with methods.) As an added wrinkle on the `should it be interactive' front, there is a keybinding in semantic.el for semantic-analyze-possible-completions that would need to be dealt with. Eric diff --git a/lisp/cedet/semantic/analyze/complete.el b/lisp/cedet/semantic/analyze/complete.el index b471c0d1a1..b8820b927f 100644 --- a/lisp/cedet/semantic/analyze/complete.el +++ b/lisp/cedet/semantic/analyze/complete.el @@ -93,7 +93,8 @@ semantic-analyze-possible-completions                context              (semantic-analyze-current-context context)))           (ans (if (not context) -              (error "Nothing to complete") +              (when (called-interactively-p 'any) +                        (error "Nothing to complete"))              (:override))))      ;; If interactive, display them.      (when (called-interactively-p 'any) @@ -132,155 +133,159 @@ semantic-analyze-possible-completions-default       (do-unique (not (memq 'no-unique flags)))       ) -    (when (not do-longprefix) -      ;; If we are not doing the long prefix, shorten all the key -      ;; elements. -      (setq prefix (list (car (reverse prefix))) -        prefixtypes nil)) - -    ;; Calculate what our prefix string is so that we can -    ;; find all our matching text. -    (setq completetext (car (reverse prefix))) -    (if (semantic-tag-p completetext) -    (setq completetext (semantic-tag-name completetext))) - -    (if (and (not completetext) (not desired-type)) -    (error "Nothing to complete")) - -    (if (not completetext) (setq completetext "")) - -    ;; This better be a reasonable type, or we should fry it. -    ;; The prefixtypes should always be at least 1 less than -    ;; the prefix since the type is never looked up for the last -    ;; item when calculating a sequence. -    (setq completetexttype (car (reverse prefixtypes))) -    (when (or (not completetexttype) -          (not (and (semantic-tag-p completetexttype) -            (eq (semantic-tag-class completetexttype) 'type)))) -      ;; What should I do here?  I think this is an error condition. -      (setq completetexttype nil) -      ;; If we had something that was a completetexttype but it wasn't -      ;; valid, then express our dismay! -      (when (> (length prefix) 1) -    (let* ((errprefix (car (cdr (reverse prefix))))) -      (error "Cannot find types for `%s'" -         (cond ((semantic-tag-p errprefix) -            (semantic-format-tag-prototype errprefix)) -               (t -            (format "%S" errprefix))))) -    )) - -    ;; There are many places to get our completion stream for. -    ;; Here we go. -    (if completetexttype - -    (setq c (semantic-find-tags-for-completion -         completetext -         (semantic-analyze-scoped-type-parts completetexttype scope) -         )) - -      ;; No type based on the completetext.  This is a free-range -      ;; var or function.  We need to expand our search beyond this -      ;; scope into semanticdb, etc. -      (setq c (nconc -           ;; Argument list and local variables -           (semantic-find-tags-for-completion completetext localvar) -           ;; The current scope -           (semantic-find-tags-for-completion completetext (when scope (oref scope fullscope))) -           ;; The world -           (semantic-analyze-find-tags-by-prefix completetext)) -        ) -      ) - -    (let ((loopc c) -      (dtname (semantic-tag-name desired-type))) - -      ;; Save off our first batch of completions -      (setq origc c) - -      ;; Reset c. -      (setq c nil) - -      ;; Loop over all the found matches, and categorize them -      ;; as being possible features. -      (while (and loopc do-typeconstraint) - -    (cond -     ;; Strip operators -     ((semantic-tag-get-attribute (car loopc) :operator-flag) -      nil -      ) - -     ;; If we are completing from within some prefix, -     ;; then we want to exclude constructors and destructors -     ((and completetexttype -           (or (semantic-tag-get-attribute (car loopc) :constructor-flag) -           (semantic-tag-get-attribute (car loopc) :destructor-flag))) -      nil -      ) - -     ;; If there is a desired type, we need a pair of restrictions -     (desired-type +    (catch 'cant-complete +      (when (not do-longprefix) +        ;; If we are not doing the long prefix, shorten all the key +        ;; elements. +        (setq prefix (list (car (reverse prefix))) +          prefixtypes nil)) + +      ;; Calculate what our prefix string is so that we can +      ;; find all our matching text. +      (setq completetext (car (reverse prefix))) +      (if (semantic-tag-p completetext) +      (setq completetext (semantic-tag-name completetext))) + +      (if (and (not completetext) (not desired-type)) +          (throw 'cant-complete nil) +      ;;(error "Nothing to complete") +        ) + +      (if (not completetext) (setq completetext "")) + +      ;; This better be a reasonable type, or we should fry it. +      ;; The prefixtypes should always be at least 1 less than +      ;; the prefix since the type is never looked up for the last +      ;; item when calculating a sequence. +      (setq completetexttype (car (reverse prefixtypes))) +      (when (or (not completetexttype) +            (not (and (semantic-tag-p completetexttype) +              (eq (semantic-tag-class completetexttype) 'type)))) +        ;; What should I do here?  I think this is an error condition. +        (setq completetexttype nil) +        ;; If we had something that was a completetexttype but it wasn't +        ;; valid, then express our dismay! +        (when (> (length prefix) 1) +          (throw 'cant-complete nil) +;;;      (let* ((errprefix (car (cdr (reverse prefix))))) +;;;        (error "Cannot find types for `%s'" +;;;           (cond ((semantic-tag-p errprefix) +;;;              (semantic-format-tag-prototype errprefix)) +;;;                 (t +;;;              (format "%S" errprefix))))) +      )) + +      ;; There are many places to get our completion stream for. +      ;; Here we go. +      (if completetexttype + +      (setq c (semantic-find-tags-for-completion +           completetext +           (semantic-analyze-scoped-type-parts completetexttype scope) +           )) + +        ;; No type based on the completetext.  This is a free-range +        ;; var or function.  We need to expand our search beyond this +        ;; scope into semanticdb, etc. +        (setq c (nconc +             ;; Argument list and local variables +             (semantic-find-tags-for-completion completetext localvar) +             ;; The current scope +             (semantic-find-tags-for-completion completetext (when scope (oref scope fullscope))) +             ;; The world +             (semantic-analyze-find-tags-by-prefix completetext)) +          ) +        ) + +      (let ((loopc c) +        (dtname (semantic-tag-name desired-type))) + +        ;; Save off our first batch of completions +        (setq origc c) + +        ;; Reset c. +        (setq c nil) + +        ;; Loop over all the found matches, and categorize them +        ;; as being possible features. +        (while (and loopc do-typeconstraint)        (cond -       ;; Ok, we now have a completion list based on the text we found -       ;; we want to complete on.  Now filter that stream against the -       ;; type we want to search for. -       ((string= dtname (semantic-analyze-type-to-name (semantic-tag-type (car loopc)))) -        (setq c (cons (car loopc) c)) +       ;; Strip operators +       ((semantic-tag-get-attribute (car loopc) :operator-flag) +        nil          ) -       ;; Now anything that is a compound type which could contain -       ;; additional things which are of the desired type -       ((semantic-tag-type (car loopc)) -        (let ((att (semantic-analyze-tag-type (car loopc) scope)) -        ) -          (if (and att (semantic-tag-type-members att)) -          (setq c (cons (car loopc) c)))) +       ;; If we are completing from within some prefix, +       ;; then we want to exclude constructors and destructors +       ((and completetexttype +             (or (semantic-tag-get-attribute (car loopc) :constructor-flag) +             (semantic-tag-get-attribute (car loopc) :destructor-flag))) +        nil          ) -       ) ; cond -      ); desired type - -     ;; No desired type, no other restrictions.  Just add. -     (t -      (setq c (cons (car loopc) c))) - -     ); cond - -    (setq loopc (cdr loopc))) - -      (when desired-type -    ;; Some types, like the enum in C, have special constant values that -    ;; we could complete with.  Thus, if the target is an enum, we can -    ;; find possible symbol values to fill in that value. -    (let ((constants -           (semantic-analyze-type-constants desired-type))) -      (if constants -          (progn -        ;; Filter -        (setq constants -              (semantic-find-tags-for-completion -               completetext constants)) -        ;; Add to the list -        (setq c (nconc c constants))) -        ))) -      ) - -    (when desired-class -      (setq c (semantic-analyze-tags-of-class-list c desired-class))) - -    (if do-unique -    (if c -        ;; Pull out trash. -        ;; NOTE TO SELF: Is this too slow? -        (setq c (semantic-unique-tag-table-by-name c)) -      (setq c (semantic-unique-tag-table-by-name origc))) -      (when (not c) -    (setq c origc))) - -    ;; All done! -    c)) +       ;; If there is a desired type, we need a pair of restrictions +       (desired-type + +        (cond +         ;; Ok, we now have a completion list based on the text we found +         ;; we want to complete on.  Now filter that stream against the +         ;; type we want to search for. +         ((string= dtname (semantic-analyze-type-to-name (semantic-tag-type (car loopc)))) +          (setq c (cons (car loopc) c)) +          ) + +         ;; Now anything that is a compound type which could contain +         ;; additional things which are of the desired type +         ((semantic-tag-type (car loopc)) +          (let ((att (semantic-analyze-tag-type (car loopc) scope)) +            ) +            (if (and att (semantic-tag-type-members att)) +            (setq c (cons (car loopc) c)))) +          ) + +         )                          ; cond +        )                           ; desired type + +       ;; No desired type, no other restrictions.  Just add. +       (t +        (setq c (cons (car loopc) c))) + +       )                            ; cond + +      (setq loopc (cdr loopc))) + +        (when desired-type +      ;; Some types, like the enum in C, have special constant values that +      ;; we could complete with.  Thus, if the target is an enum, we can +      ;; find possible symbol values to fill in that value. +      (let ((constants +             (semantic-analyze-type-constants desired-type))) +        (if constants +            (progn +          ;; Filter +          (setq constants +                (semantic-find-tags-for-completion +                 completetext constants)) +          ;; Add to the list +          (setq c (nconc c constants))) +          ))) +        ) + +      (when desired-class +        (setq c (semantic-analyze-tags-of-class-list c desired-class))) + +      (if do-unique +      (if c +          ;; Pull out trash. +          ;; NOTE TO SELF: Is this too slow? +          (setq c (semantic-unique-tag-table-by-name c)) +        (setq c (semantic-unique-tag-table-by-name origc))) +        (when (not c) +      (setq c origc))) + +      ;; All done! +      c)))  (provide 'semantic/analyze/complete)