[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