eslint-plugin-use-agnostic 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/library/_commons/utilities/helpers.js +6 -29
- package/library/agnostic20/_commons/utilities/helpers.js +4 -4
- package/library/directive21/_commons/constants/bases.js +0 -42
- package/library/directive21/_commons/rules/import-rules.js +1 -1
- package/library/directive21/_commons/utilities/helpers.js +71 -51
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -78,7 +78,7 @@ Base url and aliased import paths are currently resolved under the assumption th
|
|
|
78
78
|
|
|
79
79
|
It is up to you to confirm that your Agnostic Modules are indeed agnostic, meaning that they have neither server- nor client-side code. `eslint-plugin-use-agnostic`, at least at this time, does not do this verification for you.
|
|
80
80
|
|
|
81
|
-
It is also up to you to ensure, as outlined above, that **you avoid** exporting React components along with other logics within the same
|
|
81
|
+
It is also up to you to ensure, as outlined above, that **you avoid** exporting React components along with other logics within the same modules (unless you have to per the design of your current framework), which may derail the linting in some cases. Separating exporting React components within their own modules ending with a JSX file extension, from exporting other logics within modules that don't end with a JSX file extension, is crucial for distinguishing between Components Modules and Logics Modules respectively.
|
|
82
82
|
|
|
83
83
|
The import rules are designed to be as permissive as possible, allowing for more obscure use cases as long as they are non-breaking. However, it is still your responsibility as a developer to, within a file, not mix in incompatible ways code that cannot compose.
|
|
84
84
|
|
|
@@ -81,15 +81,14 @@ export const resolveImportPath = (currentDir, importPath, cwd) => {
|
|
|
81
81
|
return null; // not found
|
|
82
82
|
};
|
|
83
83
|
|
|
84
|
-
/*
|
|
85
|
-
// Note: For agnostic20, I need the AST so that the directive can be picked up on any line as long as it is the first statement of the file.
|
|
84
|
+
/* getSourceCodeFromFilePath */
|
|
86
85
|
|
|
87
86
|
/**
|
|
88
|
-
* Gets the ESLint-generated
|
|
87
|
+
* Gets the ESLint-generated SourceCode object of a file from its resolved path.
|
|
89
88
|
* @param {string} resolvedPath The resolved path of the file.
|
|
90
|
-
* @returns The ESLint-generated
|
|
89
|
+
* @returns The ESLint-generated SourceCode object of the file.
|
|
91
90
|
*/
|
|
92
|
-
export const
|
|
91
|
+
export const getSourceCodeFromFilePath = (resolvedPath) => {
|
|
93
92
|
// ensures each instance of the function is based on its own linter
|
|
94
93
|
// (just in case somehow some linters were running concurrently)
|
|
95
94
|
const linter = new Linter();
|
|
@@ -97,32 +96,10 @@ export const getASTFromFilePath = (resolvedPath) => {
|
|
|
97
96
|
const text = fs.readFileSync(resolvedPath, "utf8");
|
|
98
97
|
// utilizes linter.verify ...
|
|
99
98
|
linter.verify(text, { languageOptions: typeScriptAndJSXCompatible });
|
|
100
|
-
// ... to retrieve the raw code as a SourceCode object
|
|
99
|
+
// ... to retrieve the raw code as a SourceCode object
|
|
101
100
|
const code = linter.getSourceCode();
|
|
102
|
-
// ... from which to extract the ESLint-generated AST
|
|
103
|
-
const ast = code.ast;
|
|
104
101
|
|
|
105
|
-
return
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
/* getImportedFileFirstLine */ // for directive21
|
|
109
|
-
// Note: For directive21, I prioritize reading from the file system for performance, foregoing the retrieval of the source code comments for imported modules, since the Directive-First Architecture imposes that the first line of the file is reserved for its commented directive.
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Gets the first line of code of the imported module.
|
|
113
|
-
* @param {string} resolvedImportPath The resolved path of the imported module.
|
|
114
|
-
* @returns The first line of the imported module.
|
|
115
|
-
*/
|
|
116
|
-
export const getImportedFileFirstLine = (resolvedImportPath) => {
|
|
117
|
-
// gets the code of the import
|
|
118
|
-
const importedFileContent = fs.readFileSync(resolvedImportPath, "utf8");
|
|
119
|
-
// gets the first line of the code of the import
|
|
120
|
-
const importedFileFirstLine = importedFileContent
|
|
121
|
-
.trim()
|
|
122
|
-
.split("\n")[0]
|
|
123
|
-
.trim(); // the line itself needs to be trimmed too
|
|
124
|
-
|
|
125
|
-
return importedFileFirstLine;
|
|
102
|
+
return code;
|
|
126
103
|
};
|
|
127
104
|
|
|
128
105
|
/* highlightFirstLineOfCode */
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
isImportBlocked as commonsIsImportBlocked,
|
|
13
13
|
makeMessageFromCurrentFileResolvedDirective,
|
|
14
14
|
findSpecificViolationMessage as commonsFindSpecificViolationMessage,
|
|
15
|
-
|
|
15
|
+
getSourceCodeFromFilePath,
|
|
16
16
|
} from "../../../_commons/utilities/helpers.js";
|
|
17
17
|
|
|
18
18
|
/**
|
|
@@ -85,12 +85,12 @@ export const getDirectiveFromCurrentModule = (context) => {
|
|
|
85
85
|
* - `'use server'` denotes a Server Functions Module.
|
|
86
86
|
* - `'use agnostic'` denotes an Agnostic Module (formerly Shared Module).
|
|
87
87
|
* - `null` denotes a server-by-default module, ideally a Server Module.
|
|
88
|
-
* @param {string}
|
|
88
|
+
* @param {string} resolvedPath The resolved path of the imported module.
|
|
89
89
|
* @returns The directive, or lack thereof via `null`. The lack of a directive is considered server-by-default.
|
|
90
90
|
*/
|
|
91
|
-
export const getDirectiveFromImportedModule = (
|
|
91
|
+
export const getDirectiveFromImportedModule = (resolvedPath) => {
|
|
92
92
|
// the AST of the imported module
|
|
93
|
-
const ast =
|
|
93
|
+
const ast = getSourceCodeFromFilePath(resolvedPath).ast;
|
|
94
94
|
|
|
95
95
|
return getDirectiveFromModule(ast);
|
|
96
96
|
};
|
|
@@ -119,48 +119,6 @@ export const commentedDirectiveMessage = "commentedDirectiveMessage";
|
|
|
119
119
|
export const specificViolationMessage = "specificViolationMessage";
|
|
120
120
|
export const specificFailure = "specificFailure";
|
|
121
121
|
|
|
122
|
-
/* commentedDirectives_4RawImplementations */
|
|
123
|
-
|
|
124
|
-
// all formatting styles as an array of [prefix, quote, suffix]
|
|
125
|
-
/** @type {CommentStyles} */
|
|
126
|
-
const commentStyles = Object.freeze([
|
|
127
|
-
Object.freeze([`// `, `'`, ``]), // V1: `// 'directive'`
|
|
128
|
-
Object.freeze([`// `, `"`, ``]), // V2: `// "directive"`
|
|
129
|
-
Object.freeze([`\/\* `, `'`, ` \*\/`]), // V3: `/* 'directive' */`
|
|
130
|
-
Object.freeze([`\/\* `, `"`, ` \*\/`]), // V4: `/* "directive" */`
|
|
131
|
-
]);
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Makes the array of all four accepted commented directive implementations on a directive basis.
|
|
135
|
-
* @template {CommentedDirective} T
|
|
136
|
-
* @param {T} directive The commented directive.
|
|
137
|
-
* @returns The array of formatted commented directives.
|
|
138
|
-
*/
|
|
139
|
-
const make4RawImplementations = (directive) => {
|
|
140
|
-
/** @type {readonly [`// '${T}'`, `// "${T}""`, `\/\* '${T}' \*\/`, `\/\* "${T}"" \*\/`]} */
|
|
141
|
-
const rawImplementations = Object.freeze(
|
|
142
|
-
commentStyles.map(
|
|
143
|
-
([prefix, quote, suffix]) =>
|
|
144
|
-
`${prefix}${quote}${directive}${quote}${suffix}`
|
|
145
|
-
)
|
|
146
|
-
);
|
|
147
|
-
|
|
148
|
-
return rawImplementations;
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
export const commentedDirectives_4RawImplementations = Object.freeze({
|
|
152
|
-
[USE_SERVER_LOGICS]: make4RawImplementations(USE_SERVER_LOGICS),
|
|
153
|
-
[USE_CLIENT_LOGICS]: make4RawImplementations(USE_CLIENT_LOGICS),
|
|
154
|
-
[USE_AGNOSTIC_LOGICS]: make4RawImplementations(USE_AGNOSTIC_LOGICS),
|
|
155
|
-
[USE_SERVER_COMPONENTS]: make4RawImplementations(USE_SERVER_COMPONENTS),
|
|
156
|
-
[USE_CLIENT_COMPONENTS]: make4RawImplementations(USE_CLIENT_COMPONENTS),
|
|
157
|
-
[USE_AGNOSTIC_COMPONENTS]: make4RawImplementations(USE_AGNOSTIC_COMPONENTS),
|
|
158
|
-
[USE_SERVER_FUNCTIONS]: make4RawImplementations(USE_SERVER_FUNCTIONS),
|
|
159
|
-
[USE_CLIENT_CONTEXTS]: make4RawImplementations(USE_CLIENT_CONTEXTS),
|
|
160
|
-
[USE_AGNOSTIC_CONDITIONS]: make4RawImplementations(USE_AGNOSTIC_CONDITIONS),
|
|
161
|
-
[USE_AGNOSTIC_STRATEGIES]: make4RawImplementations(USE_AGNOSTIC_STRATEGIES),
|
|
162
|
-
});
|
|
163
|
-
|
|
164
122
|
/* commentedDirectives_verificationReports */
|
|
165
123
|
|
|
166
124
|
const MODULES_MARKED_WITH_THE_ = "modules marked with the";
|
|
@@ -39,7 +39,7 @@ Here, "{{ ${currentFileCommentedDirective} }}" and "{{ ${importedFileCommentedDi
|
|
|
39
39
|
[importBreaksCommentedImportRulesMessageId]: `{{ ${commentedDirectiveMessage} }}
|
|
40
40
|
In this case, {{ ${specificViolationMessage} }} `,
|
|
41
41
|
[noCommentedDirective]: `No commented directive detected.
|
|
42
|
-
All targeted modules need to be marked with their respective directives (\`// "use server logics"\`, etc.) for the purpose of this linting rule. `,
|
|
42
|
+
All targeted modules need to be marked with their respective directives (\`// "use server logics"\`, etc.) for the purpose of this linting rule, evaluated from the first JavaScript comment starting on the first column within the first three lines of a module. `,
|
|
43
43
|
[commentedDirectiveVerificationFailed]: `The commented directive could not pass verification due to an incompatible combination with its file extension.
|
|
44
44
|
In this context, {{ ${specificFailure} }} `,
|
|
45
45
|
[importNotStrategized]: `Imports from Agnostic Strategies Modules must be strategized (\`/* @serverLogics */\`, etc.).
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { exportNotStrategized } from "../../../_commons/constants/bases.js";
|
|
2
2
|
import {
|
|
3
|
-
USE_AGNOSTIC_LOGICS,
|
|
4
3
|
USE_AGNOSTIC_STRATEGIES,
|
|
5
4
|
commentedDirectivesArray,
|
|
6
5
|
strategiesArray,
|
|
7
6
|
commentedDirectives_extensionRules,
|
|
8
|
-
commentedDirectives_4RawImplementations,
|
|
9
7
|
commentedStrategies_commentedDirectives,
|
|
10
8
|
commentedDirectives_blockedImports,
|
|
11
9
|
} from "../constants/bases.js";
|
|
@@ -14,10 +12,11 @@ import {
|
|
|
14
12
|
isImportBlocked as commonsIsImportBlocked,
|
|
15
13
|
makeMessageFromCurrentFileResolvedDirective,
|
|
16
14
|
findSpecificViolationMessage as commonsFindSpecificViolationMessage,
|
|
17
|
-
|
|
15
|
+
getSourceCodeFromFilePath,
|
|
18
16
|
} from "../../../_commons/utilities/helpers.js";
|
|
19
17
|
|
|
20
18
|
/**
|
|
19
|
+
* @typedef {import('../../../../types/directive21/_commons/typedefs.js').SourceCode} SourceCode
|
|
21
20
|
* @typedef {import('../../../../types/directive21/_commons/typedefs.js').Context} Context
|
|
22
21
|
* @typedef {import('../../../../types/directive21/_commons/typedefs.js').CommentedDirective} CommentedDirective
|
|
23
22
|
* @typedef {import('../../../../types/directive21/_commons/typedefs.js').CommentedDirectiveWithoutUseAgnosticStrategies} CommentedDirectiveWithoutUseAgnosticStrategies
|
|
@@ -28,7 +27,7 @@ import {
|
|
|
28
27
|
* @typedef {import('../../../../types/directive21/_commons/typedefs.js').ExportDefaultDeclaration} ExportDefaultDeclaration
|
|
29
28
|
*/
|
|
30
29
|
|
|
31
|
-
/*
|
|
30
|
+
/* getCommentedDirectiveFromSourceCode */
|
|
32
31
|
|
|
33
32
|
/**
|
|
34
33
|
* Detects whether a string is single- or double-quoted.
|
|
@@ -70,7 +69,7 @@ const stripDoubleQuotes = (string) => {
|
|
|
70
69
|
};
|
|
71
70
|
|
|
72
71
|
/**
|
|
73
|
-
* Gets the commented directive of
|
|
72
|
+
* Gets the commented directive of a module from its ESLint SourceCode object.
|
|
74
73
|
*
|
|
75
74
|
* Accepted directives for the default Directive-First Architecture are (single or double quotes included):
|
|
76
75
|
* - `'use server logics'`, `"use server logics"` denoting a Server Logics Module.
|
|
@@ -84,19 +83,26 @@ const stripDoubleQuotes = (string) => {
|
|
|
84
83
|
* - `'use client contexts'`, `"use client contexts"` denoting a Client Contexts Module.
|
|
85
84
|
* - `'use agnostic conditions'`, `"use agnostic conditions"` denoting an Agnostic Conditions Module.
|
|
86
85
|
* - `'use agnostic strategies'`, `"use agnostic strategies"` denoting an Agnostic Strategies Module.
|
|
87
|
-
* @param {
|
|
86
|
+
* @param {SourceCode} sourceCode The ESLint SourceCode object.
|
|
88
87
|
* @returns The commented directive, or lack thereof via `null`. Given the strictness of this architecture, the lack of a directive is considered a mistake. (Though rules may provide the opportunity to declare a default, and configs with preset defaults may become provided.)
|
|
89
88
|
*/
|
|
90
|
-
export const
|
|
89
|
+
export const getCommentedDirectiveFromSourceCode = (sourceCode) => {
|
|
91
90
|
// gets the first comment from the source code
|
|
92
|
-
const
|
|
91
|
+
const rawFirstComment = sourceCode.getAllComments()[0];
|
|
92
|
+
|
|
93
|
+
const firstComment =
|
|
94
|
+
rawFirstComment.type === "Shebang"
|
|
95
|
+
? sourceCode.getAllComments()[1]
|
|
96
|
+
: rawFirstComment;
|
|
93
97
|
|
|
94
98
|
// returns null early if there is no first comment
|
|
95
99
|
if (!firstComment) return null;
|
|
96
100
|
|
|
97
|
-
// returns null early if the first comment is not on
|
|
98
|
-
if (firstComment.loc.start.line
|
|
99
|
-
|
|
101
|
+
// returns null early if the first comment is not on one of the first three lines
|
|
102
|
+
if (firstComment.loc.start.line > 3) return null;
|
|
103
|
+
|
|
104
|
+
// returns null early if the first comment is not on the first column
|
|
105
|
+
if (firstComment.loc.start.column !== 0) return null;
|
|
100
106
|
|
|
101
107
|
// gets the trimmed raw value of the first comment
|
|
102
108
|
const rawValue = firstComment.value.trim();
|
|
@@ -119,6 +125,60 @@ export const getCommentedDirectiveFromCurrentModule = (context) => {
|
|
|
119
125
|
return commentedDirective;
|
|
120
126
|
};
|
|
121
127
|
|
|
128
|
+
/* getCommentedDirectiveFromCurrentModule */
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Gets the commented directive of the current module.
|
|
132
|
+
*
|
|
133
|
+
* Accepted directives for the default Directive-First Architecture are (single or double quotes included):
|
|
134
|
+
* - `'use server logics'`, `"use server logics"` denoting a Server Logics Module.
|
|
135
|
+
* - `'use client logics'`, `"use client logics"` denoting a Client Logics Module.
|
|
136
|
+
* - `'use agnostic logics'`, `"use agnostic logics"` denoting an Agnostic Logics Module.
|
|
137
|
+
* - `'use server components'`, `"use server components"` denoting a Server Components Module.
|
|
138
|
+
* - `'use client components'`, `"use client components"` denoting a Client Components Module.
|
|
139
|
+
* - `'use agnostic components'`, `"use agnostic components"` denoting an Agnostic Components Module.
|
|
140
|
+
* - `'use agnostic logics'`, `"use agnostic logics"` denoting an Agnostic Logics Module.
|
|
141
|
+
* - `'use server functions'`, `"use server functions"` denoting a Server Functions Module.
|
|
142
|
+
* - `'use client contexts'`, `"use client contexts"` denoting a Client Contexts Module.
|
|
143
|
+
* - `'use agnostic conditions'`, `"use agnostic conditions"` denoting an Agnostic Conditions Module.
|
|
144
|
+
* - `'use agnostic strategies'`, `"use agnostic strategies"` denoting an Agnostic Strategies Module.
|
|
145
|
+
* @param {Context} context The ESLint rule's `context` object.
|
|
146
|
+
* @returns The commented directive, or lack thereof via `null`. Given the strictness of this architecture, the lack of a directive is considered a mistake. (Though rules may provide the opportunity to declare a default, and configs with preset defaults may become provided.)
|
|
147
|
+
*/
|
|
148
|
+
export const getCommentedDirectiveFromCurrentModule = (context) => {
|
|
149
|
+
const sourceCode = context.sourceCode;
|
|
150
|
+
const commentedDirective = getCommentedDirectiveFromSourceCode(sourceCode);
|
|
151
|
+
|
|
152
|
+
return commentedDirective;
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
/* getCommentedDirectiveFromImportedModule */
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Gets the commented directive of the imported module.
|
|
159
|
+
*
|
|
160
|
+
* Accepted directives for the default Directive-First Architecture are (single or double quotes included):
|
|
161
|
+
* - `'use server logics'`, `"use server logics"` denoting a Server Logics Module.
|
|
162
|
+
* - `'use client logics'`, `"use client logics"` denoting a Client Logics Module.
|
|
163
|
+
* - `'use agnostic logics'`, `"use agnostic logics"` denoting an Agnostic Logics Module.
|
|
164
|
+
* - `'use server components'`, `"use server components"` denoting a Server Components Module.
|
|
165
|
+
* - `'use client components'`, `"use client components"` denoting a Client Components Module.
|
|
166
|
+
* - `'use agnostic components'`, `"use agnostic components"` denoting an Agnostic Components Module.
|
|
167
|
+
* - `'use agnostic logics'`, `"use agnostic logics"` denoting an Agnostic Logics Module.
|
|
168
|
+
* - `'use server functions'`, `"use server functions"` denoting a Server Functions Module.
|
|
169
|
+
* - `'use client contexts'`, `"use client contexts"` denoting a Client Contexts Module.
|
|
170
|
+
* - `'use agnostic conditions'`, `"use agnostic conditions"` denoting an Agnostic Conditions Module.
|
|
171
|
+
* - `'use agnostic strategies'`, `"use agnostic strategies"` denoting an Agnostic Strategies Module.
|
|
172
|
+
* @param {string} resolvedPath The resolved path of the imported module.
|
|
173
|
+
* @returns The commented directive, or lack thereof via `null`. Given the strictness of this architecture, the lack of a directive is considered a mistake. (Though rules may provide the opportunity to declare a default, and configs with preset defaults may become provided.)
|
|
174
|
+
*/
|
|
175
|
+
export const getCommentedDirectiveFromImportedModule = (resolvedPath) => {
|
|
176
|
+
const sourceCode = getSourceCodeFromFilePath(resolvedPath);
|
|
177
|
+
const commentedDirective = getCommentedDirectiveFromSourceCode(sourceCode);
|
|
178
|
+
|
|
179
|
+
return commentedDirective;
|
|
180
|
+
};
|
|
181
|
+
|
|
122
182
|
/* getVerifiedCommentedDirective */
|
|
123
183
|
|
|
124
184
|
/**
|
|
@@ -148,46 +208,6 @@ export const getVerifiedCommentedDirective = (directive, extension) => {
|
|
|
148
208
|
return null; // verification failed
|
|
149
209
|
};
|
|
150
210
|
|
|
151
|
-
/* getCommentedDirectiveFromImportedModule */
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Gets the commented directive of the imported module.
|
|
155
|
-
*
|
|
156
|
-
* Accepted directives for the default Directive-First Architecture are (single or double quotes included):
|
|
157
|
-
* - `'use server logics'`, `"use server logics"` denoting a Server Logics Module.
|
|
158
|
-
* - `'use client logics'`, `"use client logics"` denoting a Client Logics Module.
|
|
159
|
-
* - `'use agnostic logics'`, `"use agnostic logics"` denoting an Agnostic Logics Module.
|
|
160
|
-
* - `'use server components'`, `"use server components"` denoting a Server Components Module.
|
|
161
|
-
* - `'use client components'`, `"use client components"` denoting a Client Components Module.
|
|
162
|
-
* - `'use agnostic components'`, `"use agnostic components"` denoting an Agnostic Components Module.
|
|
163
|
-
* - `'use agnostic logics'`, `"use agnostic logics"` denoting an Agnostic Logics Module.
|
|
164
|
-
* - `'use server functions'`, `"use server functions"` denoting a Server Functions Module.
|
|
165
|
-
* - `'use client contexts'`, `"use client contexts"` denoting a Client Contexts Module.
|
|
166
|
-
* - `'use agnostic conditions'`, `"use agnostic conditions"` denoting an Agnostic Conditions Module.
|
|
167
|
-
* - `'use agnostic strategies'`, `"use agnostic strategies"` denoting an Agnostic Strategies Module.
|
|
168
|
-
* @param {string} resolvedImportPath The resolved path of the import.
|
|
169
|
-
* @returns The commented directive, or lack thereof via `null`. Given the strictness of this architecture, the lack of a directive is considered a mistake. (Though rules may provide the opportunity to declare a default, and configs with preset defaults may become provided.)
|
|
170
|
-
*/
|
|
171
|
-
export const getCommentedDirectiveFromImportedModule = (resolvedImportPath) => {
|
|
172
|
-
// gets the first line of the code of the import
|
|
173
|
-
const importedFileFirstLine = getImportedFileFirstLine(resolvedImportPath);
|
|
174
|
-
|
|
175
|
-
// sees if the first line includes any of the directives and finds the directive that it includes, with USE_AGNOSTIC_LOGICS as a default
|
|
176
|
-
const includedDirective = commentedDirectivesArray.reduce((acc, curr) => {
|
|
177
|
-
if (importedFileFirstLine.includes(curr)) return curr;
|
|
178
|
-
else return acc;
|
|
179
|
-
}, USE_AGNOSTIC_LOGICS);
|
|
180
|
-
|
|
181
|
-
// sees if the first line is strictly equal to one of the four raw implementations of the commented directive and returns that directive if true or null if false
|
|
182
|
-
if (
|
|
183
|
-
commentedDirectives_4RawImplementations[includedDirective].some(
|
|
184
|
-
(raw) => raw === importedFileFirstLine
|
|
185
|
-
)
|
|
186
|
-
)
|
|
187
|
-
return includedDirective;
|
|
188
|
-
else return null;
|
|
189
|
-
};
|
|
190
|
-
|
|
191
211
|
/* getStrategizedDirective */
|
|
192
212
|
|
|
193
213
|
/**
|