Hi,
This can't be right, can it?
type
TBird = class
procedure Fly;
end;
TEagle = TBird; // alias
procedure TEagle.Fly;
begin
end;Mattias

Mailing lists / fpc-pascal / 2022-02
28 messages · 9 people · –
Reply by email Subscribe to this list Your subscription
Read-only archive. Use j and k to move between messages.
Hi,
This can't be right, can it?
type
TBird = class
procedure Fly;
end;
TEagle = TBird; // alias
procedure TEagle.Fly;
begin
end;Mattias
Personally, I would not allow this.
But Delphi compiles and runs it...
Maybe something to check for {$mode objfpc} =-)
Michael.
Michael Van Canneyt via fpc-pascal
schrieb am Sa., 12. Feb. 2022, 12:14:
The compiler does not have any real tracking for non-type aliases... As far as the compiler is concerned these are interchangeable...
Regards,
Sven
I think Mattias just got some more gray hairs :-)
So if I understand this correctly, I can do
---
Interface
Type
TSomeReallyAnnoyingIncrediblyLongClassName = Class
Procedure DoSomething;
end;
implementation
Type
T1 = TSomeReallyAnnoyingUltraLongClassName;
procedure T1.DoSomething;
begin
end;
---And consequently also
---
Interface
Type
TSomeReallyAnnoyingIncrediblyLongClassName = Class
Type
TSomeReallyAnnoyingSubClass = class
Procedure DoSomething;
end;
end;
implementation
Type
T1 = TSomeReallyAnnoyingIncrediblyLongClassName.TSomeReallyAnnoyingSubClass;
procedure T1.DoSomething;
begin
end;
---The lazarus code tools maintainer will have a field day with this one ;-)
Michael.
PS. Just tested, the compiler accepts both... Amazing, I never thought this would be possible. I'd better update the docs :-)
Michael Van Canneyt wrotePS. Just tested, the compiler accepts both... Amazing, I never thought this would be possible. I'd better update the docs :-)
I wouldn't consider this to be working by design, but rather because of implementation limitations.
Jonas
Why do you consider it a limitation ?
Because the compiler currently has no way to distinguish the types when resolving the name "T" (as used in my example)?
Then it is a strange coincidence that Delphi has it too :-)
Michael.
Indeed.
Then it is a strange coincidence that Delphi has it too :-)
The simplest way to implement alias types is to just have them refer to the original type...
Jonas
[...] >> I wouldn't consider this to be working by design, but rather >> because of implementation limitations.
+1
pas2js complained. That's how I found out. Someone renamed a class, added an alias for compatibility, forgot to rename the implementation, and fpc did not complain.
Actually pas2js did an even simpler approach here: Look up the identifier without resolving the original type ;)
Mattias
I wouldn't consider this to be working by design, but rather because of implementation…
On Feb 12, 2022, at 11:40 PM, Jonas Maebe via fpc-pascal wrote: I wouldn't consider this to be working by design, but rather because of implementation limitations.
I agree and it should be fixed probably.
Regards,
Ryan Joseph
As I wrote in my initial answer to Mattias, I would also forbid it. (despite the temptation to use it for shortening class names in the implementation, I think it will be more confusing than helpful in the end)
But since Delphi allows it, we must continue to allow it in Delphi mode...
Michael.
Personally, I would not allow this. But Delphi compiles and runs it... Maybe something to…
On Sat, 12 Feb 2022 12:14:14 +0100 (CET)
Michael Van Canneyt via fpc-pascal
... and Delphi's class completion no longer works in the unit giving a useless error "expected ';' but '.' found". So it is one of those Delphi "features" compiling but not usable.
Mattias
I'm all for forbidding this in objfpc mode.
Michael.
Michael Van Canneyt via fpc-pascal
schrieb am So., 13. Feb. 2022, 09:47:
Then file a bug report for it. Cause it's definitely going to be one of the low priority things cause it's going to be annoying to fix...
Regards,
Sven
I thought (famous last words), checking the typesyms of the tobjectdef would be enough but who knows what else will bit :)
Michael Van Canneyt via fpc-pascal schrieb am So., 13. Feb. 2022, 09:47: Then file a bug…
Done:
https://gitlab.com/freepascal.org/fpc/source/-/issues/39576
Maybe someone can check whether Florian's solution really is 'famous last words' ;-)
Michael.
This can't be right, can it? type TBird = class procedure Fly; end; TEagle = TBird; //…
It does depend on what you expect an Type-Alias to be.
If you expect the compiler to generate an compatible class then your example must not be compilable.
If you expect an alias die make the Typenames "TEagle" and "TBird" equivalent it is no problem for the compiler which name you use at what place.
In any case I would judge such code as "bad style" - programmers should avoid doing so.
Elmar
I thought (famous last words), checking the typesyms of the tobjectdef would be enough…
@Michael Van Canneyt
I didn't test but I hope this package can parse this _minified_ CSS file? Attached on the forum
https://forum.lazarus.freepascal.org/index.php/topic,58853.msg438550.html#msg438550
It has many tricks. E.g. @media blocks (@media supports nested blocks, not only 1 level), e.g. {} block for N classes, e.g. weird class names.
Alexey
Alexey Torgashin wrote@Michael Van Canneyt I didn't test but I hope this package can parse this _minified_ CSS file?
Minified or not is normally not relevant for parsing.
Nested blocks are supported.
But weird class names:
extractcssclasses brackets.min.css -o out
Exception at 00000000004C107B: ECSSParser:
Error: line 9, pos 18: Unexpected token: Got ctkIDENTIFIER (as UTF8String: "zoom"), expected: ctkCOLON .
"*zoom", really ? That's not even valid CSS syntax.
I checked 2 EBNF grammars: neither will allow this. I checked the W3 spec: Confirms this is simply not valid syntax.
Browsers are simply very forgiving for all the junk found in CSS files: The CSS syntax is so sloppy, almost impossible to cover all cases. That's why there are a lot of test files.
But patches to make the implementation more forgiving are welcome. I suppose things like *zoom can be easily supported.
Do you have the unminified file ? So I can see how to interpret the '*zoom': treat as '* zoom' or as identifier '*zoom'
Michael.
"*zoom", really ? That's not even valid CSS syntax. I checked 2 EBNF grammars: neither will allow this. I checked the W3 spec: Confirms this is simply not valid syntax.
But "*.nnn" is valid one.
https://css-tricks.com/almanac/selectors/u/universal/
So if the "*" has meaning in one context, it is not the id-char, it is special construct.
Do you have the unminified file ?
nope.
> treat as '* zoom' or as identifier '*zoom'
as "* zoom".
Alexey
The problem is that spaces are meaningful.
so * zoom and *zoom are not the same.
Thanks, I wil check...
Michael.
I did some more checking. As a selector * can be used in some cases: the universal selector. but it can not be used as a property name.
in your file:
.clearfix{*zoom:1}
*zoom is a property name, not a selector. and properties must be identifiers. According to the spec, identifiers do not start with a *.
I will add some options to interpret "*zoom" as a property name, but they will off by default.
Michael.
I will add some options to interpret "*zoom" as a property name, but they will off by default.
OK thanks.
Can you try now with CSS (usual or minified) from
https://getbootstrap.com/ ?
See 'download' which gives file bootstrap-5.1.3-dist.zip .
Complex places:
====
.link-dark:hover, .link-dark:focus {
color: #1a1e21;
}
//Here they have :suffixes.
-----------
--bs-purple: #6f42c1;
--bs-pink: #d63384;
//Here they have color varialbles.
-----------.visually-hidden-focusable:not(:focus):not(:focus-within) {
a:not([href]):not([class]), a:not([href]):not([class]):hover {
button:not(:disabled),
[type=button]:not(:disabled),
[type=reset]:not(:disabled),
[type=submit]:not(:disabled) {
cursor: pointer;}
//Here they have weird boolean things.
-----------*,
*::before,
*::after {
box-sizing: border-box;}
//Here they have star-chars.
-----------
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15),
rgba(255, 255, 255, 0));
//They have complex func calls.
-----------::-webkit-datetime-edit-year-field {
padding: 0;}
//More suffixes
-----------
From bootstrap-4.0.0-dist.zip I got also--
-----------
abbr[title]::after {
content: " (" attr(title) ")";
}//strange value with 2 strings
-----------
.text-hide {
font: 0/0 a;
}//strange value
-----------
Alexey
Good idea, I will check this file.
I use bootstrap a lot, although I prefer Bulma these days.
From your samples, most if not all things should work.
By the way, it is easy to test. Just compile the extractcssclasses demo and run
extractcssclasses yourfile
But if you prefer a GUI program, the actual code is really simple:
uses fpcssutils;
Var
L : TStringList;
Util : TCSSUtils;
begin
Util:=Nil;
L:=TStringList.Create;
try
Util:=TCSSUtils.Create(Self);
Util.ExtractClassNames(aFileName,L);
// Do something with L
finally
Util.Free;
L.Free;
end;
end;Michael.
Currently if I run "extractcssclasses" with Bootstrap 4 (or 5) CSS file (not minified) I get it work for more than 30 seconds, then I stopped it, too long.
Output file (parameter "--output=4.txt") not created.
CPU Core i3. Linux x64.
AT
Good idea, I will check this file. I use bootstrap a lot, although I prefer Bulma these…
I had to do 2 small fixes, but the bootstrap file now parses 100%
Michael.
Currently if I run "extractcssclasses" with Bootstrap 4 (or 5) CSS file (not minified) I…
Alexey Torgashin wroteCurrently if I run "extractcssclasses" with Bootstrap 4 (or 5) CSS file (not minified) I get it work for more than 30 seconds, then I stopped it, too long.
Correct, there was an infinite loop. Is now fixed.
Michael.
On Sat, 12 Feb 2022 12:14:14 +0100 (CET) Michael Van Canneyt via fpc-pascal ... and…
(I posted to the forum, but it's better to post here.) TStringList.Text setter does this
<pre>
Procedure TStrings.DoSetTextStr(const Value: string; DoClear :
Boolean);
...
if FLineBreak=sLineBreak then
begin
While GetNextLine (Value,S,P) do
Add(S)
end
else
While GetNextLineBreak (Value,S,P) do
Add(S);
finally
EndUpdate;
end;
end;
</pre>here it calls GetNextLine which does SPECIAL handling of #10 and #13 and #13#10 line breaks. If it does special handling of #10 and #13 and #13#10 line breaks, why don't we check
if (FLineBreak=#10) or (FLineBreak=#13) or (FLineBreak=#13#10)
but we do simple
if FLineBreak=sLineBreak
Alexey
This would change the behaviour.
Now the special treatment is only done when FLinebreak exactly matches sLineBreak.
Michael.