@@ -537,4 +537,39 @@ module Templating {
537537 )
538538 }
539539 }
540+
541+ /**
542+ * An EJS-style `include` call within a template tag, such as `<%- include(file, { params }) %>`.
543+ */
544+ private class EjsIncludeCallInTemplate extends TemplateInstantiaton:: Range , DataFlow:: CallNode {
545+ EjsIncludeCallInTemplate ( ) {
546+ exists ( TemplatePlaceholderTag tag |
547+ tag .getRawText ( ) .regexpMatch ( "(?s)<%-.*" ) and
548+ this = tag .getInnerTopLevel ( ) .getAVariableUse ( "include" ) .getACall ( )
549+ )
550+ }
551+
552+ /** Gets a data flow node that refers to the instantiated template, if any. */
553+ override DataFlow:: SourceNode getOutput ( ) { result = this }
554+
555+ /** Gets a data flow node that refers a template file to be instantiated, if any. */
556+ override DataFlow:: Node getTemplateFileNode ( ) { result = getArgument ( 0 ) }
557+
558+ /** Gets a data flow node that refers to the contents of the template to be instantiated, if any. */
559+ override DataFlow:: Node getTemplateContentNode ( ) { none ( ) }
560+
561+ /** Gets a data flow node that refers to an object whose properties become variables in the template. */
562+ override DataFlow:: Node getTemplateParamsNode ( ) { result = getArgument ( 1 ) }
563+ }
564+
565+ /** The `include` function, seen as an API node, so we can treat it as a template instantiation. */
566+ private class IncludeFunctionAsEntryPoint extends API:: EntryPoint {
567+ IncludeFunctionAsEntryPoint ( ) { this = "IncludeFunctionAsEntryPoint" }
568+
569+ override DataFlow:: SourceNode getAUse ( ) {
570+ result = any ( TemplatePlaceholderTag tag ) .getInnerTopLevel ( ) .getAVariableUse ( "include" )
571+ }
572+
573+ override DataFlow:: Node getARhs ( ) { none ( ) }
574+ }
540575}
0 commit comments