[fpc-pascal] Feature announcement: default namespaces
Sven Barth
pascaldragon at googlemail.com
Sat May 5 19:23:04 CEST 2018
Hello together!
I'm pleased to announce the implementation of a new feature: default
namespaces.
As you may know FPC supports the use of dots/points/periods (".") inside
unit (and program/library) names which allows to avoid name collisions
with a syntax similar to other languages like Java and C# (and somewhat
also to C++'s "::"). Unlike those languages in FPC such names don't
introduce a real namespace system, so you can't do a "uses MyUnits.*" or
something like that to have both units MyUnits.FancyFuncs and
MyUnits.FoobarStuff included. Nevertheless the prefix of such a unit (in
my example "MyUnits") is called a namespace.
For some users it might be cumbersome however to write the complete
names (even though their IDE of choice might support them here) or maybe
they have different sets of units with same names and interfaces, but
different namespaces (e.g. ProductX and ProductY which contain wrappers
units for the 3rd party products X and Y with a common interface). Of
course in the latter case these can be switched using ifdefs or some
creative usage of macros, but that can be done simpler.
Enter default namespaces.
The compiler is told about a default namespace using the new -FN<x>
parameter, whereby <x> is a valid Pascal identifier for a namespace
(e.g. "MyUnits" or "FCL.XML" or "FCL.Web.Base"). Like with all similar
-F parameters -FN only takes a single value, but can be specified
multiple times.
Now if the compiler encounters a unit name in the uses declaration it
first searches for the unit as-is (first for a compiled unit, then for
the sources). If the unit wasn't found then it walks the list of default
namespaces, prepends them to the provided unit name as a prefix (with
"." as a separator) and then again searches first for a compiled unit
and then the sources.
If the unit was found then all symbols are available as usual.
Additionally you can use a full or partial unit name:
- assume a unit XMLReader which is part of the default namespace FCL.XML
with the symbol ReadXML
- ReadXML can be addressed either as ReadXML, XMLReader.ReadXML or
FCL.XML.XMLReader.ReadXML
- if FCL is also given as a default namespace then XML.XMLReader.ReadXML
is valid as well
The default namespace functionality is compatible with the -Un switch:
E.g. if unit Blubb resides in foo.bar.pp then supplying the default
namespace "foo" and using the unit "Bar" (with -Un active) will result
in the file foo.bar to be found and used correctly.
The feature is Delphi compatible (aside from the parameter of course :P ).
Known issue:
Assume the following situation:
- unit ./somepath/someunit.pp
- unit ./somens.someunit.pp
- unit search path ./somepath and ./
- unit output path ./whatever
- default namespace "somens"
Now by design the unit someunit will be picked up. However if the search
path ./somepath is removed or the unit source is removed then the
compiler *will not* pick up somens.someunit.pp as long as someunit.ppu
is in the unit output directory even if -B is specified. The reason for
this is as-designed functionality to keep using the compiled unit if the
source is not available (at least as long as no change to a dependant
unit would trigger a required recompilation of said unit).
Regards,
Sven
More information about the fpc-pascal
mailing list