.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / tslint / lib / rules / completedDocsRule.js
1 "use strict";
2 /**
3  * @license
4  * Copyright 2013 Palantir Technologies, Inc.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 Object.defineProperty(exports, "__esModule", { value: true });
19 var tslib_1 = require("tslib");
20 var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
21 var tsutils = require("tsutils");
22 var ts = require("typescript");
23 var Lint = require("../index");
24 var exclusions_1 = require("./completed-docs/exclusions");
25 exports.ALL = "all";
26 exports.ARGUMENT_CLASSES = "classes";
27 exports.ARGUMENT_ENUMS = "enums";
28 exports.ARGUMENT_ENUM_MEMBERS = "enum-members";
29 exports.ARGUMENT_FUNCTIONS = "functions";
30 exports.ARGUMENT_INTERFACES = "interfaces";
31 exports.ARGUMENT_METHODS = "methods";
32 exports.ARGUMENT_NAMESPACES = "namespaces";
33 exports.ARGUMENT_PROPERTIES = "properties";
34 exports.ARGUMENT_TYPES = "types";
35 exports.ARGUMENT_VARIABLES = "variables";
36 exports.DESCRIPTOR_TAGS = "tags";
37 exports.DESCRIPTOR_LOCATIONS = "locations";
38 exports.DESCRIPTOR_OVERLOADS = "overloads";
39 exports.DESCRIPTOR_PRIVACIES = "privacies";
40 exports.DESCRIPTOR_VISIBILITIES = "visibilities";
41 exports.LOCATION_INSTANCE = "instance";
42 exports.LOCATION_STATIC = "static";
43 exports.PRIVACY_PRIVATE = "private";
44 exports.PRIVACY_PROTECTED = "protected";
45 exports.PRIVACY_PUBLIC = "public";
46 exports.TAGS_FOR_CONTENT = "content";
47 exports.TAGS_FOR_EXISTENCE = "existence";
48 exports.VISIBILITY_EXPORTED = "exported";
49 exports.VISIBILITY_INTERNAL = "internal";
50 var Rule = /** @class */ (function (_super) {
51     tslib_1.__extends(Rule, _super);
52     function Rule() {
53         return _super !== null && _super.apply(this, arguments) || this;
54     }
55     /* tslint:enable:object-literal-sort-keys */
56     Rule.prototype.apply = function (sourceFile) {
57         var options = this.getOptions();
58         var exclusionsMap = this.getExclusionsMap(options.ruleArguments);
59         return this.applyWithFunction(sourceFile, walk, exclusionsMap);
60     };
61     Rule.prototype.getExclusionsMap = function (ruleArguments) {
62         if (ruleArguments.length === 0) {
63             ruleArguments = [Rule.defaultArguments];
64         }
65         return exclusions_1.constructExclusionsMap(ruleArguments);
66     };
67     Rule.FAILURE_STRING_EXIST = "Documentation must exist for ";
68     Rule.defaultArguments = (_a = {},
69         _a[exports.ARGUMENT_CLASSES] = true,
70         _a[exports.ARGUMENT_FUNCTIONS] = true,
71         _a[exports.ARGUMENT_METHODS] = (_b = {},
72             _b[exports.DESCRIPTOR_TAGS] = (_c = {},
73                 _c[exports.TAGS_FOR_CONTENT] = {
74                     see: ".*",
75                 },
76                 _c[exports.TAGS_FOR_EXISTENCE] = ["deprecated", "inheritdoc"],
77                 _c),
78             _b),
79         _a[exports.ARGUMENT_PROPERTIES] = (_d = {},
80             _d[exports.DESCRIPTOR_TAGS] = (_e = {},
81                 _e[exports.TAGS_FOR_CONTENT] = {
82                     see: ".*",
83                 },
84                 _e[exports.TAGS_FOR_EXISTENCE] = ["deprecated", "inheritdoc"],
85                 _e),
86             _d),
87         _a);
88     Rule.ARGUMENT_DESCRIPTOR_BLOCK = {
89         properties: (_f = {},
90             _f[exports.DESCRIPTOR_TAGS] = {
91                 properties: (_g = {},
92                     _g[exports.TAGS_FOR_CONTENT] = {
93                         items: {
94                             type: "string",
95                         },
96                         type: "object",
97                     },
98                     _g[exports.TAGS_FOR_EXISTENCE] = {
99                         items: {
100                             type: "string",
101                         },
102                         type: "array",
103                     },
104                     _g),
105             },
106             _f[exports.DESCRIPTOR_VISIBILITIES] = {
107                 enum: [exports.ALL, exports.VISIBILITY_EXPORTED, exports.VISIBILITY_INTERNAL],
108                 type: "string",
109             },
110             _f),
111         type: "object",
112     };
113     Rule.ARGUMENT_DESCRIPTOR_CLASS = {
114         properties: (_h = {},
115             _h[exports.DESCRIPTOR_TAGS] = {
116                 properties: (_j = {},
117                     _j[exports.TAGS_FOR_CONTENT] = {
118                         items: {
119                             type: "string",
120                         },
121                         type: "object",
122                     },
123                     _j[exports.TAGS_FOR_EXISTENCE] = {
124                         items: {
125                             type: "string",
126                         },
127                         type: "array",
128                     },
129                     _j),
130             },
131             _h[exports.DESCRIPTOR_LOCATIONS] = {
132                 enum: [exports.ALL, exports.LOCATION_INSTANCE, exports.LOCATION_STATIC],
133                 type: "string",
134             },
135             _h[exports.DESCRIPTOR_PRIVACIES] = {
136                 enum: [exports.ALL, exports.PRIVACY_PRIVATE, exports.PRIVACY_PROTECTED, exports.PRIVACY_PUBLIC],
137                 type: "string",
138             },
139             _h),
140         type: "object",
141     };
142     Rule.ARGUMENT_DESCRIPTOR_FUNCTION = {
143         properties: tslib_1.__assign({}, Rule.ARGUMENT_DESCRIPTOR_BLOCK.properties, (_k = {}, _k[exports.DESCRIPTOR_OVERLOADS] = {
144             type: "boolean",
145         }, _k)),
146         type: "object",
147     };
148     Rule.ARGUMENT_DESCRIPTOR_METHOD = {
149         properties: tslib_1.__assign({}, Rule.ARGUMENT_DESCRIPTOR_CLASS.properties, (_l = {}, _l[exports.DESCRIPTOR_OVERLOADS] = {
150             type: "boolean",
151         }, _l)),
152         type: "object",
153     };
154     /* tslint:disable:object-literal-sort-keys */
155     Rule.metadata = {
156         ruleName: "completed-docs",
157         description: "Enforces JSDoc comments for important items be filled out.",
158         optionsDescription: Lint.Utils.dedent(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["\n            `true` to enable for `[", "]`,\n            or an array with each item in one of two formats:\n\n            * `string` to enable for that type\n            * `object` keying types to when their documentation is required:\n                * `\"", "\"` and `\"", "\"` may specify:\n                    * `\"", "\"`:\n                        * `\"", "\"`\n                        * `\"", "\"`\n                        * `\"", "\"`\n                        * `\"", "\"`\n                    * `\"", "\"`:\n                        * `\"", "\"`\n                        * `\"", "\"`\n                        * `\"", "\"`\n                * Other types may specify `\"", "\"`:\n                    * `\"", "\"`\n                    * `\"", "\"`\n                    * `\"", "\"`\n                * `\"", "\"` `\"", "\"` may also specify `\"", "\"`\n                  to indicate that each overload should have its own documentation, which is `false` by default.\n                * All types may also provide `\"", "\"`\n                  with members specifying tags that allow the docs to not have a body.\n                    * `\"", "\"`: Object mapping tags to `RegExp` bodies content allowed to count as complete docs.\n                    * `\"", "\"`: Array of tags that must only exist to count as complete docs.\n\n            Types that may be enabled are:\n\n            * `\"", "\"`\n            * `\"", "\"`\n            * `\"", "\"`\n            * `\"", "\"`\n            * `\"", "\"`\n            * `\"", "\"`\n            * `\"", "\"`\n            * `\"", "\"`\n            * `\"", "\"`\n            * `\"", "\"`"], ["\n            \\`true\\` to enable for \\`[", "]\\`,\n            or an array with each item in one of two formats:\n\n            * \\`string\\` to enable for that type\n            * \\`object\\` keying types to when their documentation is required:\n                * \\`\"", "\"\\` and \\`\"", "\"\\` may specify:\n                    * \\`\"", "\"\\`:\n                        * \\`\"", "\"\\`\n                        * \\`\"", "\"\\`\n                        * \\`\"", "\"\\`\n                        * \\`\"", "\"\\`\n                    * \\`\"", "\"\\`:\n                        * \\`\"", "\"\\`\n                        * \\`\"", "\"\\`\n                        * \\`\"", "\"\\`\n                * Other types may specify \\`\"", "\"\\`:\n                    * \\`\"", "\"\\`\n                    * \\`\"", "\"\\`\n                    * \\`\"", "\"\\`\n                * \\`\"", "\"\\` \\`\"", "\"\\` may also specify \\`\"", "\"\\`\n                  to indicate that each overload should have its own documentation, which is \\`false\\` by default.\n                * All types may also provide \\`\"", "\"\\`\n                  with members specifying tags that allow the docs to not have a body.\n                    * \\`\"", "\"\\`: Object mapping tags to \\`RegExp\\` bodies content allowed to count as complete docs.\n                    * \\`\"", "\"\\`: Array of tags that must only exist to count as complete docs.\n\n            Types that may be enabled are:\n\n            * \\`\"", "\"\\`\n            * \\`\"", "\"\\`\n            * \\`\"", "\"\\`\n            * \\`\"", "\"\\`\n            * \\`\"", "\"\\`\n            * \\`\"", "\"\\`\n            * \\`\"", "\"\\`\n            * \\`\"", "\"\\`\n            * \\`\"", "\"\\`\n            * \\`\"", "\"\\`"])), Object.keys(Rule.defaultArguments).join(", "), exports.ARGUMENT_METHODS, exports.ARGUMENT_PROPERTIES, exports.DESCRIPTOR_PRIVACIES, exports.ALL, exports.PRIVACY_PRIVATE, exports.PRIVACY_PROTECTED, exports.PRIVACY_PUBLIC, exports.DESCRIPTOR_LOCATIONS, exports.ALL, exports.LOCATION_INSTANCE, exports.LOCATION_STATIC, exports.DESCRIPTOR_VISIBILITIES, exports.ALL, exports.VISIBILITY_EXPORTED, exports.VISIBILITY_INTERNAL, exports.ARGUMENT_FUNCTIONS, exports.ARGUMENT_METHODS, exports.DESCRIPTOR_OVERLOADS, exports.DESCRIPTOR_TAGS, exports.TAGS_FOR_CONTENT, exports.TAGS_FOR_EXISTENCE, exports.ARGUMENT_CLASSES, exports.ARGUMENT_ENUMS, exports.ARGUMENT_ENUM_MEMBERS, exports.ARGUMENT_FUNCTIONS, exports.ARGUMENT_INTERFACES, exports.ARGUMENT_METHODS, exports.ARGUMENT_NAMESPACES, exports.ARGUMENT_PROPERTIES, exports.ARGUMENT_TYPES, exports.ARGUMENT_VARIABLES),
159         options: {
160             type: "array",
161             items: {
162                 anyOf: [
163                     {
164                         options: [
165                             exports.ARGUMENT_CLASSES,
166                             exports.ARGUMENT_ENUMS,
167                             exports.ARGUMENT_FUNCTIONS,
168                             exports.ARGUMENT_INTERFACES,
169                             exports.ARGUMENT_METHODS,
170                             exports.ARGUMENT_NAMESPACES,
171                             exports.ARGUMENT_PROPERTIES,
172                             exports.ARGUMENT_TYPES,
173                             exports.ARGUMENT_VARIABLES,
174                         ],
175                         type: "string",
176                     },
177                     {
178                         type: "object",
179                         properties: (_m = {},
180                             _m[exports.ARGUMENT_CLASSES] = Rule.ARGUMENT_DESCRIPTOR_BLOCK,
181                             _m[exports.ARGUMENT_ENUMS] = Rule.ARGUMENT_DESCRIPTOR_BLOCK,
182                             _m[exports.ARGUMENT_ENUM_MEMBERS] = Rule.ARGUMENT_DESCRIPTOR_BLOCK,
183                             _m[exports.ARGUMENT_FUNCTIONS] = Rule.ARGUMENT_DESCRIPTOR_FUNCTION,
184                             _m[exports.ARGUMENT_INTERFACES] = Rule.ARGUMENT_DESCRIPTOR_BLOCK,
185                             _m[exports.ARGUMENT_METHODS] = Rule.ARGUMENT_DESCRIPTOR_METHOD,
186                             _m[exports.ARGUMENT_NAMESPACES] = Rule.ARGUMENT_DESCRIPTOR_BLOCK,
187                             _m[exports.ARGUMENT_PROPERTIES] = Rule.ARGUMENT_DESCRIPTOR_CLASS,
188                             _m[exports.ARGUMENT_TYPES] = Rule.ARGUMENT_DESCRIPTOR_BLOCK,
189                             _m[exports.ARGUMENT_VARIABLES] = Rule.ARGUMENT_DESCRIPTOR_BLOCK,
190                             _m),
191                     },
192                 ],
193             },
194         },
195         optionExamples: [
196             true,
197             [true, exports.ARGUMENT_ENUMS, exports.ARGUMENT_FUNCTIONS, exports.ARGUMENT_METHODS],
198             [
199                 true,
200                 (_o = {},
201                     _o[exports.ARGUMENT_ENUMS] = true,
202                     _o[exports.ARGUMENT_FUNCTIONS] = (_p = {},
203                         _p[exports.DESCRIPTOR_VISIBILITIES] = [exports.VISIBILITY_EXPORTED],
204                         _p),
205                     _o[exports.ARGUMENT_METHODS] = (_q = {},
206                         _q[exports.DESCRIPTOR_LOCATIONS] = exports.LOCATION_INSTANCE,
207                         _q[exports.DESCRIPTOR_PRIVACIES] = [exports.PRIVACY_PUBLIC, exports.PRIVACY_PROTECTED],
208                         _q),
209                     _o[exports.ARGUMENT_PROPERTIES] = (_r = {},
210                         _r[exports.DESCRIPTOR_TAGS] = (_s = {},
211                             _s[exports.TAGS_FOR_CONTENT] = {
212                                 see: ["#.*"],
213                             },
214                             _s[exports.TAGS_FOR_EXISTENCE] = ["inheritdoc"],
215                             _s),
216                         _r),
217                     _o),
218             ],
219         ],
220         rationale: Lint.Utils.dedent(templateObject_2 || (templateObject_2 = tslib_1.__makeTemplateObject(["\n            Helps ensure important components are documented.\n\n            Note: use this rule sparingly. It's better to have self-documenting names on components with single, concise responsibilities.\n            Comments that only restate the names of variables add nothing to code, and can easily become outdated.\n        "], ["\n            Helps ensure important components are documented.\n\n            Note: use this rule sparingly. It's better to have self-documenting names on components with single, concise responsibilities.\n            Comments that only restate the names of variables add nothing to code, and can easily become outdated.\n        "]))),
221         type: "style",
222         typescriptOnly: false,
223     };
224     return Rule;
225 }(Lint.Rules.AbstractRule));
226 exports.Rule = Rule;
227 var modifierAliases = {
228     export: "exported",
229 };
230 function walk(context) {
231     return ts.forEachChild(context.sourceFile, cb);
232     function cb(node) {
233         switch (node.kind) {
234             case ts.SyntaxKind.ClassDeclaration:
235                 checkNode(node, exports.ARGUMENT_CLASSES);
236                 break;
237             case ts.SyntaxKind.EnumDeclaration:
238                 checkNode(node, exports.ARGUMENT_ENUMS);
239                 for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
240                     var member = _a[_i];
241                     // Enum members don't have modifiers, so use the parent
242                     // enum declaration when checking the requirements.
243                     checkNode(member, exports.ARGUMENT_ENUM_MEMBERS, node);
244                 }
245                 break;
246             case ts.SyntaxKind.FunctionDeclaration:
247                 checkNode(node, exports.ARGUMENT_FUNCTIONS);
248                 break;
249             case ts.SyntaxKind.InterfaceDeclaration:
250                 checkNode(node, exports.ARGUMENT_INTERFACES);
251                 break;
252             case ts.SyntaxKind.MethodSignature:
253                 checkNode(node, exports.ARGUMENT_METHODS);
254                 break;
255             case ts.SyntaxKind.MethodDeclaration:
256                 if (node.parent.kind !== ts.SyntaxKind.ObjectLiteralExpression) {
257                     checkNode(node, exports.ARGUMENT_METHODS);
258                 }
259                 break;
260             case ts.SyntaxKind.ModuleDeclaration:
261                 checkNode(node, exports.ARGUMENT_NAMESPACES);
262                 break;
263             case ts.SyntaxKind.PropertySignature:
264                 checkNode(node, exports.ARGUMENT_PROPERTIES);
265                 break;
266             case ts.SyntaxKind.PropertyDeclaration:
267                 checkNode(node, exports.ARGUMENT_PROPERTIES);
268                 break;
269             case ts.SyntaxKind.TypeAliasDeclaration:
270                 checkNode(node, exports.ARGUMENT_TYPES);
271                 break;
272             case ts.SyntaxKind.VariableStatement:
273                 // Only check variables at the namespace/module-level or file-level
274                 // and not variables declared inside functions and other things.
275                 switch (node.parent.kind) {
276                     case ts.SyntaxKind.SourceFile:
277                     case ts.SyntaxKind.ModuleBlock:
278                         for (var _b = 0, _c = node.declarationList
279                             .declarations; _b < _c.length; _b++) {
280                             var declaration = _c[_b];
281                             checkNode(declaration, exports.ARGUMENT_VARIABLES, node);
282                         }
283                 }
284                 break;
285             case ts.SyntaxKind.GetAccessor:
286             case ts.SyntaxKind.SetAccessor:
287                 if (node.parent.kind !== ts.SyntaxKind.ObjectLiteralExpression) {
288                     checkAccessorNode(node, exports.ARGUMENT_PROPERTIES);
289                 }
290         }
291         return ts.forEachChild(node, cb);
292     }
293     function checkNode(node, docType, requirementNode) {
294         if (requirementNode === void 0) { requirementNode = node; }
295         if (!nodeIsExcluded(node, docType, requirementNode) && !nodeHasDocs(node, docType)) {
296             addDocumentationFailure(node, describeDocType(docType), requirementNode);
297         }
298     }
299     function checkAccessorNode(node, docType) {
300         if (nodeIsExcluded(node, exports.ARGUMENT_PROPERTIES, node) || nodeHasDocs(node, docType)) {
301             return;
302         }
303         var correspondingAccessor = getCorrespondingAccessor(node);
304         if (correspondingAccessor === undefined || !nodeHasDocs(correspondingAccessor, docType)) {
305             addDocumentationFailure(node, exports.ARGUMENT_PROPERTIES, node);
306         }
307     }
308     function nodeIsExcluded(node, docType, requirementNode) {
309         var name = node.name;
310         if (name === undefined) {
311             return true;
312         }
313         var exclusions = context.options.get(docType);
314         if (exclusions === undefined) {
315             return true;
316         }
317         for (var _i = 0, _a = exclusions.requirements; _i < _a.length; _i++) {
318             var requirement = _a[_i];
319             if (requirement.excludes(requirementNode)) {
320                 return true;
321             }
322         }
323         return false;
324     }
325     function nodeHasDocs(node, docType) {
326         var docs = getApparentJsDoc(node, docType, context.sourceFile);
327         if (docs === undefined) {
328             return false;
329         }
330         var comments = docs
331             .map(function (doc) { return doc.comment; })
332             .filter(function (comment) { return comment !== undefined && comment.trim() !== ""; });
333         return comments.length !== 0;
334     }
335     /**
336      * @see https://github.com/ajafff/tsutils/issues/16
337      */
338     function getApparentJsDoc(node, docType, sourceFile) {
339         if (ts.isVariableDeclaration(node)) {
340             if (variableIsAfterFirstInDeclarationList(node)) {
341                 return undefined;
342             }
343             node = node.parent;
344         }
345         if (ts.isVariableDeclarationList(node)) {
346             node = node.parent;
347         }
348         var equivalentNodesForDocs = getEquivalentNodesForDocs(node, docType);
349         return equivalentNodesForDocs
350             .map(function (docsNode) { return tsutils.getJsDoc(docsNode, sourceFile); })
351             .filter(function (nodeDocs) { return nodeDocs !== undefined; })
352             .reduce(function (docs, moreDocs) { return docs.concat(moreDocs); }, []);
353     }
354     /**
355      * @see https://github.com/palantir/tslint/issues/4416
356      */
357     function getEquivalentNodesForDocs(node, docType) {
358         var exclusions = context.options.get(docType);
359         if (exclusions === undefined || exclusions.overloadsSeparateDocs) {
360             return [node];
361         }
362         if (tsutils.isFunctionDeclaration(node) && node.name !== undefined) {
363             var functionName_1 = node.name.text;
364             return getSiblings(node).filter(function (child) {
365                 return tsutils.isFunctionDeclaration(child) &&
366                     child.name !== undefined &&
367                     child.name.text === functionName_1;
368             });
369         }
370         if (tsutils.isMethodDeclaration(node) &&
371             tsutils.isIdentifier(node.name) &&
372             tsutils.isClassDeclaration(node.parent)) {
373             var methodName_1 = node.name.text;
374             return node.parent.members.filter(function (member) {
375                 return tsutils.isMethodDeclaration(member) &&
376                     tsutils.isIdentifier(member.name) &&
377                     member.name.text === methodName_1;
378             });
379         }
380         return [node];
381     }
382     function addDocumentationFailure(node, docType, requirementNode) {
383         var start = node.getStart();
384         var width = node.getText().split(/\r|\n/g)[0].length;
385         var description = describeDocumentationFailure(requirementNode, docType);
386         context.addFailureAt(start, width, description);
387     }
388 }
389 function getCorrespondingAccessor(node) {
390     var propertyName = tsutils.getPropertyName(node.name);
391     if (propertyName === undefined) {
392         return undefined;
393     }
394     var parent = node.parent;
395     var correspondingKindCheck = node.kind === ts.SyntaxKind.GetAccessor ? isSetAccessor : isGetAccessor;
396     for (var _i = 0, _a = parent.members; _i < _a.length; _i++) {
397         var member = _a[_i];
398         if (!correspondingKindCheck(member)) {
399             continue;
400         }
401         if (tsutils.getPropertyName(member.name) === propertyName) {
402             return member;
403         }
404     }
405     return undefined;
406 }
407 function variableIsAfterFirstInDeclarationList(node) {
408     var parent = node.parent;
409     if (parent === undefined) {
410         return false;
411     }
412     return ts.isVariableDeclarationList(parent) && node !== parent.declarations[0];
413 }
414 function describeDocumentationFailure(node, docType) {
415     var description = Rule.FAILURE_STRING_EXIST;
416     if (node.modifiers !== undefined) {
417         description += node.modifiers
418             .map(function (modifier) { return describeModifier(modifier.kind); })
419             .join(" ") + " ";
420     }
421     return "" + description + docType + ".";
422 }
423 function describeModifier(kind) {
424     var description = ts.SyntaxKind[kind].toLowerCase().split("keyword")[0];
425     var alias = modifierAliases[description];
426     return alias !== undefined ? alias : description;
427 }
428 function describeDocType(docType) {
429     return docType.replace("-", " ");
430 }
431 function getSiblings(node) {
432     var parent = node.parent;
433     // Source files nest their statements within a node for getChildren()
434     if (ts.isSourceFile(parent)) {
435         return parent.statements.slice();
436     }
437     return parent.getChildren();
438 }
439 function isGetAccessor(node) {
440     return node.kind === ts.SyntaxKind.GetAccessor;
441 }
442 function isSetAccessor(node) {
443     return node.kind === ts.SyntaxKind.SetAccessor;
444 }
445 var templateObject_1, templateObject_2;