@@ -134,27 +134,7 @@ abstract class UI5BindingPath extends BindingPath {
134134 )
135135 or
136136 /* 5. There is no call to `setModel` in the same webapp and a default model exists that is related to the binding path this refers to */
137- exists ( DefaultODataServiceModel defaultModel |
138- result = defaultModel and
139- not exists ( MethodCallNode viewSetModelCall |
140- viewSetModelCall .getMethodName ( ) = "setModel" and
141- inSameWebApp ( this .getLocation ( ) .getFile ( ) , viewSetModelCall .getFile ( ) )
142- ) and
143- /*
144- * this binding path can occur in a fragment that is the receiver object for the bindElement model approximation
145- * i.e. checks that the default model is relevant
146- */
147-
148- exists ( FragmentLoad load |
149- load .getCallbackObjectReference ( ) .flowsTo ( defaultModel .asBinding ( ) .asDataFlowNode ( ) ) and
150- load .getNameArgument ( )
151- .getStringValue ( )
152- .matches ( "%" +
153- this .getLocation ( ) .getFile ( ) .getBaseName ( ) .replaceAll ( ".fragment.xml" , "" ) + "%" ) and
154- // The fragment load call must be in the same webapp as the fragment file
155- inSameWebApp ( this .getLocation ( ) .getFile ( ) , load .getFile ( ) )
156- )
157- )
137+ result = getDefaultODataModel ( this )
158138 )
159139 // and
160140 // /* This binding path and the resulting model should live inside the same webapp */
@@ -184,20 +164,66 @@ abstract class UI5BindingPath extends BindingPath {
184164 inSameWebApp ( this .getLocation ( ) .getFile ( ) , result .getFile ( ) )
185165 )
186166 or
187- exists ( JsonModel model , CustomController controller |
188- not model .contentIsStaticallyVisible ( ) and
189- result = model and
190- this .getView ( ) = controller .getAViewReference ( ) .getDefinition ( ) and
191- controller .getModel ( ) = result
192- )
167+ /* 1-3. Internal (Client-side) model, content not statically visible */
168+ result = getNonStaticJsonModelNode ( this )
193169 or
194170 /* 2. External (Server-side) model */
195- result = this .getModel ( ) .( UI5ExternalModel ) and
196- /* Restrict search to inside the same webapp. */
197- inSameWebApp ( this .getLocation ( ) .getFile ( ) , result .getFile ( ) )
171+ result = getExternalModelNode ( this )
198172 }
199173}
200174
175+ /**
176+ * Gets the `DefaultODataServiceModel` for a binding path in a fragment,
177+ * when no explicit `setModel` call exists in the webapp.
178+ *
179+ * `nomagic` to keep the `FragmentLoad` cross-flow analysis separate from the
180+ * main `getModel()` evaluation.
181+ */
182+ pragma [ nomagic]
183+ private DefaultODataServiceModel getDefaultODataModel ( UI5BindingPath bindingPath ) {
184+ // Only applies to fragment XML files
185+ bindingPath .getLocation ( ) .getFile ( ) .getBaseName ( ) .matches ( "%.fragment.xml" ) and
186+ not exists ( MethodCallNode viewSetModelCall |
187+ viewSetModelCall .getMethodName ( ) = "setModel" and
188+ inSameWebApp ( bindingPath .getLocation ( ) .getFile ( ) , viewSetModelCall .getFile ( ) )
189+ ) and
190+ exists ( FragmentLoad load |
191+ load .getCallbackObjectReference ( ) .flowsTo ( result .asBinding ( ) .asDataFlowNode ( ) ) and
192+ load .getNameArgument ( )
193+ .getStringValue ( )
194+ .matches ( "%" +
195+ bindingPath .getLocation ( ) .getFile ( ) .getBaseName ( ) .replaceAll ( ".fragment.xml" , "" ) + "%" ) and
196+ inSameWebApp ( bindingPath .getLocation ( ) .getFile ( ) , load .getFile ( ) )
197+ )
198+ }
199+
200+ /**
201+ * Gets the `DataFlow::Node` for a non-statically-visible `JsonModel`.
202+ *
203+ * `nomagic` to avoid re-evaluation of `getModel()` when combined with other
204+ * `getNode()` disjuncts.
205+ */
206+ pragma [ nomagic]
207+ private JsonModel getNonStaticJsonModelNode ( UI5BindingPath bindingPath ) {
208+ not result .contentIsStaticallyVisible ( ) and
209+ exists ( CustomController controller |
210+ bindingPath .getView ( ) = controller .getAViewReference ( ) .getDefinition ( ) and
211+ controller .getModel ( ) = result
212+ )
213+ }
214+
215+ /**
216+ * Gets the external (server-side) model node associated with a binding path.
217+ *
218+ * `nomagic` to prevent `getModel()` from being inlined and duplicated across
219+ * the `getNode()` disjuncts.
220+ */
221+ pragma [ nomagic]
222+ private UI5ExternalModel getExternalModelNode ( UI5BindingPath bindingPath ) {
223+ result = bindingPath .getModel ( ) and
224+ inSameWebApp ( bindingPath .getLocation ( ) .getFile ( ) , result .getFile ( ) )
225+ }
226+
201227class XmlControlProperty extends XmlAttribute {
202228 XmlControlProperty ( ) { exists ( UI5Control control | this .getElement ( ) = control .asXmlControl ( ) ) }
203229}
0 commit comments