f90: handle F2008 module function

* lisp/progmodes/f90.el (f90-font-lock-keywords-1)
(f90-looking-at-program-block-start):
Handle F2008 "module function" and subroutine.  (Bug#38415)
* test/lisp/progmodes/f90-tests.el (f90-test-bug38415): New test.
This commit is contained in:
Glenn Morris 2020-01-15 18:47:51 -08:00
parent 55803cc189
commit 3b0d1a50aa
2 changed files with 32 additions and 5 deletions

View file

@ -539,8 +539,10 @@ type-name parts, respectively."
read\\|write\\)\\)[ \t]*(" (1 font-lock-keyword-face t))
;; Other functions and declarations. Named interfaces = F2003.
;; F2008: end submodule submodule_name.
'("\\_<\\(\\(?:end[ \t]*\\)?\\(program\\|\\(?:sub\\)?module\\|\
function\\|associate\\|subroutine\\|interface\\)\\|use\\|call\\)\
;; F2008: module function|subroutine NAME.
'("\\_<\\(\\(?:end[ \t]*\\)?\\(program\\|\
\\(?:module[ \t]*\\)?\\(?:function\\|subroutine\\)\\|\
\\(?:sub\\)?module\\|associate\\|interface\\)\\|use\\|call\\)\
\\_>[ \t]*\\(\\(?:\\sw\\|\\s_\\)+\\)?"
(1 font-lock-keyword-face) (3 font-lock-function-name-face nil t))
;; F2008: submodule (parent_name) submodule_name.
@ -1381,14 +1383,19 @@ write\\)[ \t]*([^)\n]*)")
(cond
((looking-at "\\(program\\)[ \t]+\\(\\(?:\\sw\\|\\s_\\)+\\)\\_>")
(list (match-string 1) (match-string 2)))
((and (not (looking-at "module[ \t]*procedure\\_>"))
((and (not (looking-at "module[ \t]*\\(procedure\\|function\\|subroutine\\)\\_>"))
(looking-at "\\(module\\)[ \t]+\\(\\(?:\\sw\\|\\s_\\)+\\)\\_>"))
(list (match-string 1) (match-string 2)))
((looking-at "\\(submodule\\)[ \t]*([^)\n]+)[ \t]*\\(\\(?:\\sw\\|\\s_\\)+\\)\\_>")
(list (match-string 1) (match-string 2)))
((and (not (looking-at "end[ \t]*\\(function\\|subroutine\\)"))
(looking-at "[^!'\"&\n]*\\(function\\|subroutine\\)[ \t]+\
((and (not (looking-at "end[ \t]*\\(function\\|procedure\\|subroutine\\)"))
(looking-at "[^!'\"&\n]*\\(?:module[ \t]*\\)?\
\\(function\\|subroutine\\)[ \t]+\
\\(\\(?:\\sw\\|\\s_\\)+\\)"))
;; TODO: In F2008 "module procedure foo" may or may not start a block,
;; It is impossible to tell the difference without parsing state.
;;; (looking-at "[^!'\"&\n]*module[ \t]*\\(procedure\\)[ \t]+\
;;;\\(\\(?:\\sw\\|\\s_\\)+\\)")))
(list (match-string 1) (match-string 2)))))
;; Following will match an un-named main program block; however
;; one needs to check if there is an actual PROGRAM statement after

View file

@ -277,4 +277,24 @@ end program prog")
(forward-line -2)
(should (= 2 (current-indentation))))) ; type is
(ert-deftest f90-test-bug38415 ()
"Test for https://debbugs.gnu.org/38415 ."
(with-temp-buffer
(f90-mode)
(setq-local f90-smart-end 'no-blink)
(insert "module function foo(x)
real :: x
end")
(f90-indent-line)
(should (equal " function foo"
(buffer-substring (point) (line-end-position))))
(goto-char (point-max))
(insert "\nmodule subroutine bar(x)
real :: x
end")
(f90-indent-line)
(should (equal " subroutine bar"
(buffer-substring (point) (line-end-position))))))
;;; f90-tests.el ends here