Skip to content

Removes need for matching begin-end scope names #509

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

### Changed

- Changed need for matching begin-end scope names, in the following constructs:
Functions, Modules, Programs, Module Procedures, Subroutines, Submodules.
For a more detailed explanation as to why see the issue
([#278](https://github.com/fortran-lang/vscode-fortran-support/issues/278))
- Rewrote README to include links to fortran-lang and other projects
([#485](https://github.com/fortran-lang/vscode-fortran-support/issues/485))
([#501](https://github.com/fortran-lang/vscode-fortran-support/issues/501))
Expand Down
12 changes: 6 additions & 6 deletions syntaxes/fortran_free-form.tmLanguage.json
Original file line number Diff line number Diff line change
Expand Up @@ -4060,7 +4060,7 @@
"name": "entity.name.function.fortran"
}
},
"end": "(?ix)\\s*\\b(?:(end\\s*function)(?:\\s+(\\1))?|(end))\\b \\s*([^;!\\n]+)?(?=[;!\\n])",
"end": "(?ix)\\s*\\b(?:(end\\s*function)(?:\\s+([a-z_]\\w*))?|(end))\\b \\s*([^;!\\n]+)?(?=[;!\\n])",
"endCaptures": {
"1": {
"name": "keyword.other.endfunction.fortran"
Expand Down Expand Up @@ -4148,7 +4148,7 @@
"name": "entity.name.class.module.fortran"
}
},
"end": "(?ix)\\b(?:(end\\s*module)(?:\\s+(\\1))?|(end))\\b \\s*([^;!\\n]+)?(?=[;!\\n])",
"end": "(?ix)\\b(?:(end\\s*module)(?:\\s+([a-z_]\\w*))?|(end))\\b \\s*([^;!\\n]+)?(?=[;!\\n])",
"endCaptures": {
"1": {
"name": "keyword.other.endmodule.fortran"
Expand Down Expand Up @@ -4218,7 +4218,7 @@
"name": "entity.name.program.fortran"
}
},
"end": "(?ix)\\b(?:(end\\s*program)(?:\\s+(\\1))?|(end))\\b\\s*([^;!\\n]+)?(?=[;!\\n])",
"end": "(?ix)\\b(?:(end\\s*program)(?:\\s+([a-z_]\\w*))?|(end))\\b\\s*([^;!\\n]+)?(?=[;!\\n])",
"endCaptures": {
"1": {
"name": "keyword.control.endprogram.fortran"
Expand Down Expand Up @@ -4289,7 +4289,7 @@
"name": "entity.name.function.procedure.fortran"
}
},
"end": "(?ix)\\s*\\b(?:(end\\s*procedure)(?:\\s+(\\1))?|(end))\\b \\s*([^;!\\n]+)?(?=[;!\\n])",
"end": "(?ix)\\s*\\b(?:(end\\s*procedure)(?:\\s+([a-z_]\\w*))?|(end))\\b \\s*([^;!\\n]+)?(?=[;!\\n])",
"endCaptures": {
"1": {
"name": "keyword.other.endprocedure.fortran"
Expand Down Expand Up @@ -4395,7 +4395,7 @@
"name": "entity.name.function.subroutine.fortran"
}
},
"end": "(?ix)\\b(?:(end\\s*subroutine)(?:\\s+(\\1))?|(end))\\b \\s*([^;!\\n]+)?(?=[;!\\n])",
"end": "(?ix)\\b(?:(end\\s*subroutine)(?:\\s+([a-z_]\\w*))?|(end))\\b \\s*([^;!\\n]+)?(?=[;!\\n])",
"endCaptures": {
"1": {
"name": "keyword.other.endsubroutine.fortran"
Expand Down Expand Up @@ -4493,7 +4493,7 @@
"name": "entity.name.module.submodule.fortran"
}
},
"end": "(?ix)\\s*\\b(?:(end\\s*submodule)(?:\\s+(\\1))?|(end))\\b \\s*([^;!\\n]+)?(?=[;!\\n])",
"end": "(?ix)\\s*\\b(?:(end\\s*submodule)(?:\\s+([a-z_]\\w*))?|(end))\\b \\s*([^;!\\n]+)?(?=[;!\\n])",
"endCaptures": {
"1": {
"name": "keyword.other.endsubmodule.fortran"
Expand Down
121 changes: 121 additions & 0 deletions test/resources/pp_in_func.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
! Out of order nested function/subroutine definitions such as in the case
! of preprocessing directives, where the inner scope is not the scope that closes
! first, yield invalid.error syntax highlighting because we attempt to match
! the name from the begin REGEX to the end REGEX match i.e. \\1
! This can be circumvented by matching a word character instead [a-z_]\\w*
! Obviously this is not going to highlight when the wrong name is used to
! close a scope, but the linter should solve that

!
subroutine blasmul_mm()
interface
#ifdef DOUBLEP
SUBROUTINE DGEMM ( )
#else
SUBROUTINE SGEMM ( )
#endif

#ifdef DOUBLEP
END SUBROUTINE DGEMM
#else
END SUBROUTINE SGEMM
#endif
end interface

end subroutine blasmul_mm

! This would work with the previous definition of the end REGEX because the scopes
! close in the order that they open
subroutine blasmul_mm()
interface
#ifdef DOUBLEP
SUBROUTINE DGEMM ( )
#else
SUBROUTINE SGEMM ( )
#endif

#ifndef DOUBLEP
END SUBROUTINE SGEMM
#else
END SUBROUTINE DGEMM
#endif
end interface

end subroutine blasmul_mm

REAL FUNCTION blasmul_mm() RESULT(VAL)
interface
#ifdef DOUBLEP
FUNCTION DGEMM ( )
#else
FUNCTION SGEMM ( )
#endif

#ifdef DOUBLEP
END FUNCTION DGEMM
#else
END FUNCTION SGEMM
#endif
end interface

END FUNCTION blasmul_mm

MODULE blasmul_mm
#ifdef DOUBLEP
MODULE DGEMM
#else
MODULE SGEMM
#endif

#ifdef DOUBLEP
END MODULE DGEMM
#else
END MODULE SGEMM
#endif

end MODULE blasmul_mm

SUBMODULE (name) blasmul_mm
#ifdef DOUBLEP
SUBMODULE (name) DGEMM
#else
SUBMODULE (name) SGEMM
#endif

#ifdef DOUBLEP
END SUBMODULE DGEMM
#else
END SUBMODULE SGEMM
#endif

end SUBMODULE blasmul_mm

PROGRAM blasmul_mm
#ifdef DOUBLEP
PROGRAM DGEMM
#else
PROGRAM SGEMM
#endif

#ifdef DOUBLEP
END PROGRAM DGEMM
#else
END PROGRAM SGEMM
#endif

end PROGRAM blasmul_mm

MODULE PROCEDURE blasmul_mm
#ifdef DOUBLEP
MODULE PROCEDURE DGEMM
#else
MODULE PROCEDURE SGEMM
#endif

#ifdef DOUBLEP
END PROCEDURE DGEMM
#else
END PROCEDURE SGEMM
#endif

end PROCEDURE blasmul_mm
Loading