Skip to content
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

#889 TList/TMap variable types and minor updates #890

Merged
merged 6 commits into from
Apr 17, 2023

Conversation

belisoful
Copy link
Member

TList and TMap variables and some methods are typed. subclass methods that could override an input or output are not typed.

The storage is made protected rather than private because some subclasses may need direct access to the storage _d. TWeakList needs to scrub _d in place without accessor functions.

A few functions were move around to make the files and method locations more symmetric to each other.

_getZappableSleepProps is added to TList, TPriorityList, TPriorityMap, and TWeakCallableCollections

TPriorityList uses its parent _d. Smaller code can be made for insertAtIndexInPriority as well. offsetGet is redundant

Regression on existing TList and TMap subclasses are updated

TPriorityListTest unit tests are corrected (not that it did something erroneous)

TList and TMap variables and some methods are typed.  subclass methods that could override an input or output are not typed.

The storage is made protected rather than private because some subclasses may need direct access to the storage _d.  TWeakList needs to scrub _d in place without accessor functions.

A few functions were move around to make the files and method locations more symmetric to each other.

_getZappableSleepProps is added to TList, TPriorityList, TPriorityMap, and TWeakCallableCollections

TPriorityList uses its parent _d.  Smaller code can be made for insertAtIndexInPriority as well.  offsetGet is redundant

Regression on existing TList and TMap subclasses are updated

TPriorityListTest unit tests are corrected (not that it did something erroneous)
@belisoful
Copy link
Member Author

belisoful commented Apr 15, 2023

a lot of PRADO could be updated with PHP types. I'm just starting with TList and TMap because they are a core of PRADO.

Some places shouldn't be typed so they can be overridden.

This is a general clean-up of the TList and TMap

Copy link
Member

@ctrlaltca ctrlaltca left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think i found a problem, everything else looks good to me

framework/Collections/TList.php Outdated Show resolved Hide resolved
framework/Collections/TMap.php Outdated Show resolved Hide resolved
@belisoful
Copy link
Member Author

I had no idea that TList was being used to parse like that. Great catch. My unknowingness. I think there needs to be a unit test for this to ensure it doesn't happen. However, given #837, this shouldn't be an issue for too long and so no unit test as it would need to be rolled back when #837 is available.

@belisoful
Copy link
Member Author

If setReadOnly can be set in the template it needs to not be protected but public. I'll fix that right now.

@belisoful
Copy link
Member Author

Done. ready for review and merge.

I have a TWeakList ready when this merged. I'm going to use the TWeakList in a future update of TClassBehavior. The TWeakCallableCollection is coming next and will be based upon TWeakList. It's a review and overhaul.

…nd should be protected

TList::Read only has been historically protected so a list cannot be made mutable on the fly.  A copy can be made and made changable.
@belisoful
Copy link
Member Author

setReadOnly has been historically protected. A list instanced as read only typically cannot be made mutable after the fact. a mutable copy can be made, but a read only list is just that. Does the config and template instance a list as read only or is it a set property?

Should we make setReadOnly public rather than protected?

@ctrlaltca
Copy link
Member

ctrlaltca commented Apr 17, 2023

If it's always been protected we should probably keep it this way.
Let me make an example of what i meant in my previous comment.
Imagine you have a custom TControl that internally uses a TList, and gets a boolean value from the template that gets used to instantiate the TList:

<com:MyControl ID="xxxx" ReadOnly="true" />
class MyControl extends TWebControl
{
  private $_list;

  public function setReadOnly($value)
  {
     if($this->list === null) {
         $this->_list = new TList(null, $value) ;
     }
  }
}

Ideally the TPropertyValue::ensureBoolean() check should go inside MyControl::setReadOnly().
TList has no business with templates, so it should just receive a clean boolean.
Anyway, since xue added this check 18 years ago, i guess some code could exists that uses TList the wrong way passing the readonly value as a string.
Now the choice is up to you: should we keep backward compatibility with old broken code or try to clean up the type system?

@belisoful
Copy link
Member Author

belisoful commented Apr 17, 2023

All of PRADO needs a class-variable/method-parameter type update, which I suggest is a PRADO 4.3 version thing that the community can work on together. This would be well served with #837. It would be a great upgrade esp with moving to PHP 8.

Breaking backward compatibility here, in TList::setReadOnly with a parameter type, can be pushed out until then. I do prefer ReadOnly being set on construct and setReadOnly being protected for subclass access to change default behavior: read only stays read only.

Other languages tend to be strict about Mutable and ReadOnly Lists. Java comes to mind. Lists there must be copied to reset their ReadOnly flag.

The general update of variable and parameters in this merge can serve as a model. This effort is also to keep the variable types open where subclasses could override the type.

I do have a use case in mind: the Tiff class maintains its Image File Directory (IFD) in a TList, but overrides basic TList functions to check if the value isn't an integer. Integer based index are routed to the main IFD TList, but it can flatten the TIFF tree with each sub-Directory having an accessible indexed name that is equally as accessible, like a TMap.

The Tiff class is a hybrid TMap/TList. That may be turn into its own Collections class, a hybrid between TList and TMap: The TMapList access depending on the index/key being numeric or not. TMap is less code to duplicate.

@ctrlaltca ctrlaltca merged commit 75256f1 into pradosoft:master Apr 17, 2023
@ctrlaltca
Copy link
Member

ctrlaltca commented Apr 17, 2023

Looks like we have a problem here

[Compile Error] Declaration of Prado\Web\UI\ActiveControls\TActiveListItemCollection::insertAt($index, $value) must be compatible with Prado\Collections\TListItemCollection::insertAt($index, $item): void (@line 91 in file framework/Web/UI/ActiveControls/TActiveListItemCollection.php).

@belisoful
Copy link
Member Author

I see, insertAt should be have return :void

@ctrlaltca
Copy link
Member

ctrlaltca commented Apr 17, 2023

I'm also getting some other errors that seems unrelated, i'm currently investigating
eg. tests/FunctionalTests/tickets/index700.php fails with

Prado\Exceptions\TConfigurationException
Description

Control 'BasePage' requires a master control since the control uses [TContent](http://pradosoft.github.io/docs/manual/class-Prado.Web.UI.WebControls.TContent.html).

@belisoful
Copy link
Member Author

I'll have a fix on TListItemCollection shortly.

@belisoful
Copy link
Member Author

Here is the merge fix for the overly typed TListItemCollection: #894

@ctrlaltca
Copy link
Member

Merged, thank you. Looks like the other errors were caused by the previous application state not being compatible, so cleaning it fixed the other problems. Bumping the version number will lad to a new application state for all users, so this should not be a problem

@belisoful
Copy link
Member Author

I'm not too surprised, changing the TList _d variable from private to protected would do that. It would shimmy the unserialize function from the change. It is something that should be done so subclasses can directly access _d.

I never really liked that TPriorityList recreated _d for its own purpose and so had two _d.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants