View Issue Details
|ID||Project||Category||View Status||Date Submitted||Last Update|
|0037762||pas2js||transpiler||public||2020-09-16 23:09||2020-09-19 16:50|
|Reporter||henrique||Assigned To||Mattias Gaertner|
|Summary||0037762: TypeError: Cannot read property 'name' of undefined|
|Description||I've added a project with the problem I'm having, it's just an example of what's going on in a larger project I'm working on.|
In the unit "UnitError" I declared an array with the name "TMyClassArray", and Try to fetch information from its RTTI.
When I do this, the "TypeError: Cannot read property 'name' of undefined" error occurs, which is why the "ElType" of "TTypeInfoDynArray" is undefined.
This occurs because in js file generation, it is placing the type of a class not yet defined. In the Error.js file this can be seen on line 41, but the implementation of the class occurs only on line 157, when loading the module it is part of.
|Additional Information||I'm using the -Jc parameter.|
|Tags||No tags attached.|
|Fixed in Revision|
Error.zip (2,334 bytes)
Finally I was able to understand a little better the organization of the classes, and I was able to fix the problem.
My change causes the genérios types to be generated within the unit that form declared, and not in the unit that has the template.
As is the case with TList<T>, which is in the Generics.Collections unit, and when I declared a list of my unit, the JS generation placed this "new" class within Generic.Collections.js, which in my view is incorrect.
I modified the shape that declarations are added, to ensure that the dependencies of a class are always declared before the final type.
This applies to the parameters of the generic type, a generic procedure, and the derivations of the classes.
Generics..patch (3,096 bytes)
diff -r packages/fcl-passrc/src/pasresolver.pp (3e0b42cf) packages/fcl-passrc/src/pasresolver.pp (Working Tree) 16570,16573c16570,16575 < Last: TPasElement; < i, LastIndex: Integer; < GenScope: TPasGenericScope; < ProcScope: TPasProcedureScope; --- > Element: TPasElement; > > PasType: TPasElement; > > InsertPosition: Integer; > 16584,16585c16586,16591 < Last:=GenericEl; < if SpecializedItems<>nil then --- > InsertPosition := 0; > > for Element in ParamsResolved do > InsertPosition := Max(InsertPosition, List.IndexOf(Element) + 1); > > if GenericEl is TPasClassType then 16587,16622c16593,16627 < i:=SpecializedItems.Count-2; < if i>=0 then < Last:=TPRSpecializedItem(SpecializedItems[i]).SpecializedEl; < end; < LastIndex:=List.IndexOf(Last); < if (LastIndex<0) then < if GenericEl is TPasProcedure then < else < RaiseNotYetImplemented(20200725093218,El); < i:=List.Count-1; < while i>LastIndex do < begin < Last:=TPasElement(List[i]); < if Last is TPasGenericType then < begin < if (Last.CustomData<>nil) then < begin < GenScope:=Last.CustomData as TPasGenericScope; < if GenScope.GenericStep>=psgsInterfaceParsed then < break; // finished generic type < end; < // type is still parsed => insert in front < dec(i); < end < else if Last is TPasProcedure then < begin < ProcScope:=Last.CustomData as TPasProcedureScope; < if ProcScope.GenericStep>=psgsInterfaceParsed then < break; // finished generic proc < // proc is still parsed => insert in front < dec(i); < end < else < break; < end; < List.Insert(i+1,NewEl); --- > PasType := GenericEl; > > while Assigned(PasType) do > begin > InsertPosition := Max(InsertPosition, List.IndexOf(PasType) + 1); > > if PasType is TPasClassType then > PasType := TPasClassType(PasType).AncestorType > else if PasType is TPasAliasType then > PasType := TPasAliasType(PasType).DestType > else > RaiseNotYetImplemented(202009118134955, PasType, 'Type not implemented'); > end; > end; > > List.Insert(InsertPosition,NewEl); > end; > > function GetParent(Element: TPasElement): TPasElement; > begin > Result := Element; > > while Assigned(Element) and not ((Element is TInterfaceSection) or (Element is TPasMembersType)) do > Element := Element.Parent; > > if Assigned(Element) then > Result := Element; > > while Assigned(Element) and not (Element is TInterfaceSection) do > Element := Element.Parent; > > if Assigned(Element) then > Result := Element > else > Result := GenericEl.Parent; 16667c16672 < NewParent:=GenericEl.Parent; --- > NewParent:=GetParent(El);
Generics..patch (3,096 bytes)
1. Thanks for the patch.
2. When you change the resolver, you must fix the test suites as well.
3. Generic param types can be from multiple units.
4. Param types can be in declared inside a class. Therefore you *cannot* sort topologically specializations. Instead these specializations must be split and some parts must be delayed. This is already implemented, but for some reason the delay does not trigger here -> bug.
1 - Cool!
2 - Ok, I will check the tests.
3 - Yes, and I having problems with this now. I trying to fix this too...
4 - Hum... I guest that I understand you explanation.
|2020-09-16 23:09||henrique||New Issue|
|2020-09-16 23:09||henrique||File Added: Error.zip|
|2020-09-16 23:49||Michael Van Canneyt||Assigned To||=> Mattias Gaertner|
|2020-09-16 23:49||Michael Van Canneyt||Status||new => assigned|
|2020-09-18 19:13||henrique||Note Added: 0125626|
|2020-09-18 19:13||henrique||File Added: Generics..patch|
|2020-09-19 10:01||Mattias Gaertner||Status||assigned => confirmed|
|2020-09-19 10:17||Mattias Gaertner||Note Added: 0125639|
|2020-09-19 16:50||henrique||Note Added: 0125643|