All dependency resolution in Gradle should happen via TaskDependencyResolveContext during when building the task graph. Calling `DefaultTaskDependency.getDependencies(task)` should be avoided since it creates a new `TaskDependencyResolveContext` and needs to calculate the dependencies again.

`SkipTaskWithNoActionsExecuter` now re-uses the `TaskExecutionGraph` to determine the dependencies of a task instead of re-evaluating them.

After this commit, the task properties are resolved at three places:

- When building the task graph for walking the input files

- When checking if there a task can be executed in parallel with the currently running tasks based on on the declared outputs, destroyables and task local state

- For using the task properties during task execution

The last two places could still be unified into one, but that seems to be a little bit more complicated.