ngWalker.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. "use strict";
  2. var __extends = (this && this.__extends) || (function () {
  3. var extendStatics = function (d, b) {
  4. extendStatics = Object.setPrototypeOf ||
  5. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  6. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  7. return extendStatics(d, b);
  8. };
  9. return function (d, b) {
  10. extendStatics(d, b);
  11. function __() { this.constructor = d; }
  12. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  13. };
  14. })();
  15. Object.defineProperty(exports, "__esModule", { value: true });
  16. var compiler = require("@angular/compiler");
  17. var Lint = require("tslint");
  18. var ts = require("typescript");
  19. var logger_1 = require("../util/logger");
  20. var utils_1 = require("../util/utils");
  21. var config_1 = require("./config");
  22. var metadata_1 = require("./metadata");
  23. var ngWalkerFactoryUtils_1 = require("./ngWalkerFactoryUtils");
  24. var basicCssAstVisitor_1 = require("./styles/basicCssAstVisitor");
  25. var parseCss_1 = require("./styles/parseCss");
  26. var basicTemplateAstVisitor_1 = require("./templates/basicTemplateAstVisitor");
  27. var recursiveAngularExpressionVisitor_1 = require("./templates/recursiveAngularExpressionVisitor");
  28. var referenceCollectorVisitor_1 = require("./templates/referenceCollectorVisitor");
  29. var templateParser_1 = require("./templates/templateParser");
  30. var getDecoratorStringArgs = function (decorator) {
  31. var expression = decorator.expression;
  32. var args = ts.isCallExpression(expression) ? expression.arguments : ts.createNodeArray();
  33. return args.filter(ts.isStringLiteral).map(function (x) { return x.text; });
  34. };
  35. var getPosition = function (node) {
  36. var pos = 0;
  37. if (node) {
  38. pos = node.pos + 1;
  39. try {
  40. pos = node.getStart() + 1;
  41. }
  42. catch (_a) { }
  43. }
  44. return pos;
  45. };
  46. var NgWalker = (function (_super) {
  47. __extends(NgWalker, _super);
  48. function NgWalker(sourceFile, _originalOptions, _config, _metadataReader) {
  49. var _this = _super.call(this, sourceFile, _originalOptions) || this;
  50. _this._originalOptions = _originalOptions;
  51. _this._config = _config;
  52. _this._metadataReader = _metadataReader;
  53. _this._metadataReader = _this._metadataReader || ngWalkerFactoryUtils_1.ngWalkerFactoryUtils.defaultMetadataReader();
  54. _this._config = Object.assign({
  55. cssVisitorCtrl: basicCssAstVisitor_1.BasicCssAstVisitor,
  56. templateVisitorCtrl: basicTemplateAstVisitor_1.BasicTemplateAstVisitor,
  57. expressionVisitorCtrl: recursiveAngularExpressionVisitor_1.RecursiveAngularExpressionVisitor
  58. }, _this._config || {});
  59. return _this;
  60. }
  61. NgWalker.prototype.visitClassDeclaration = function (declaration) {
  62. if (this.hasClassName(declaration)) {
  63. var metadata = this._metadataReader.read(declaration);
  64. if (metadata instanceof metadata_1.ComponentMetadata) {
  65. this.visitNgComponent(metadata);
  66. }
  67. else if (metadata instanceof metadata_1.DirectiveMetadata) {
  68. this.visitNgDirective(metadata);
  69. }
  70. else if (metadata instanceof metadata_1.PipeMetadata) {
  71. this.visitNgPipe(metadata);
  72. }
  73. else if (metadata instanceof metadata_1.ModuleMetadata) {
  74. this.visitNgModule(metadata);
  75. }
  76. else if (metadata instanceof metadata_1.InjectableMetadata) {
  77. this.visitNgInjectable(metadata);
  78. }
  79. }
  80. utils_1.maybeNodeArray(ts.createNodeArray(declaration.decorators)).forEach(this.visitClassDecorator.bind(this));
  81. _super.prototype.visitClassDeclaration.call(this, declaration);
  82. };
  83. NgWalker.prototype.visitMethodDeclaration = function (method) {
  84. utils_1.maybeNodeArray(ts.createNodeArray(method.decorators)).forEach(this.visitMethodDecorator.bind(this));
  85. _super.prototype.visitMethodDeclaration.call(this, method);
  86. };
  87. NgWalker.prototype.visitPropertyDeclaration = function (prop) {
  88. utils_1.maybeNodeArray(ts.createNodeArray(prop.decorators)).forEach(this.visitPropertyDecorator.bind(this));
  89. _super.prototype.visitPropertyDeclaration.call(this, prop);
  90. };
  91. NgWalker.prototype.visitMethodDecorator = function (decorator) {
  92. var name = utils_1.getDecoratorName(decorator);
  93. if (name === 'HostListener') {
  94. this.visitNgHostListener(decorator.parent, decorator, getDecoratorStringArgs(decorator));
  95. }
  96. };
  97. NgWalker.prototype.visitPropertyDecorator = function (decorator) {
  98. var name = utils_1.getDecoratorName(decorator);
  99. switch (name) {
  100. case 'Input':
  101. this.visitNgInput(decorator.parent, decorator, getDecoratorStringArgs(decorator));
  102. break;
  103. case 'Output':
  104. this.visitNgOutput(decorator.parent, decorator, getDecoratorStringArgs(decorator));
  105. break;
  106. case 'HostBinding':
  107. this.visitNgHostBinding(decorator.parent, decorator, getDecoratorStringArgs(decorator));
  108. break;
  109. case 'ContentChild':
  110. this.visitNgContentChild(decorator.parent, decorator, getDecoratorStringArgs(decorator));
  111. break;
  112. case 'ContentChildren':
  113. this.visitNgContentChildren(decorator.parent, decorator, getDecoratorStringArgs(decorator));
  114. break;
  115. case 'ViewChild':
  116. this.visitNgViewChild(decorator.parent, decorator, getDecoratorStringArgs(decorator));
  117. break;
  118. case 'ViewChildren':
  119. this.visitNgViewChildren(decorator.parent, decorator, getDecoratorStringArgs(decorator));
  120. break;
  121. }
  122. };
  123. NgWalker.prototype.visitNgComponent = function (metadata) {
  124. var _a = metadata.styles, styles = _a === void 0 ? [] : _a;
  125. for (var _i = 0, styles_1 = styles; _i < styles_1.length; _i++) {
  126. var style = styles_1[_i];
  127. try {
  128. var cssAst = parseCss_1.parseCss(style.style.code);
  129. this.visitNgStyleHelper(cssAst, metadata, style, getPosition(style.node));
  130. }
  131. catch (e) {
  132. var name_1 = metadata.controller.name;
  133. var text = name_1 && ts.isIdentifier(name_1) ? name_1.text : '';
  134. logger_1.logger.error('Cannot parse the styles of', text, e);
  135. }
  136. }
  137. var template = metadata.template;
  138. if (template && template.template) {
  139. try {
  140. var templateAst = templateParser_1.parseTemplate(template.template.code, config_1.Config.predefinedDirectives);
  141. this.visitNgTemplateHelper(templateAst, metadata, getPosition(template.node));
  142. }
  143. catch (e) {
  144. var name_2 = metadata.controller.name;
  145. var text = name_2 && ts.isIdentifier(name_2) ? name_2.text : '';
  146. logger_1.logger.error('Cannot parse the template of', text, e);
  147. }
  148. }
  149. };
  150. NgWalker.prototype.visitClassDecorator = function (decorator) { };
  151. NgWalker.prototype.visitNgModule = function (metadata) { };
  152. NgWalker.prototype.visitNgDirective = function (metadata) { };
  153. NgWalker.prototype.visitNgPipe = function (metadata) { };
  154. NgWalker.prototype.visitNgInjectable = function (metadata) { };
  155. NgWalker.prototype.visitNgInput = function (property, input, args) { };
  156. NgWalker.prototype.visitNgOutput = function (property, output, args) { };
  157. NgWalker.prototype.visitNgHostBinding = function (property, decorator, args) { };
  158. NgWalker.prototype.visitNgHostListener = function (method, decorator, args) { };
  159. NgWalker.prototype.visitNgContentChild = function (property, input, args) { };
  160. NgWalker.prototype.visitNgContentChildren = function (property, input, args) { };
  161. NgWalker.prototype.visitNgViewChild = function (property, input, args) { };
  162. NgWalker.prototype.visitNgViewChildren = function (property, input, args) { };
  163. NgWalker.prototype.visitNgTemplateHelper = function (roots, context, baseStart) {
  164. var _this = this;
  165. if (!roots || !roots.length) {
  166. return;
  167. }
  168. var sourceFile = this.getContextSourceFile(context.template.url, context.template.template.source);
  169. var referenceVisitor = new referenceCollectorVisitor_1.ReferenceCollectorVisitor();
  170. var visitor = new this._config.templateVisitorCtrl(sourceFile, this._originalOptions, context, baseStart, this._config.expressionVisitorCtrl);
  171. compiler.templateVisitAll(referenceVisitor, roots, null);
  172. visitor._variables = referenceVisitor.variables;
  173. roots.forEach(function (r) { return visitor.visit(r, context.controller); });
  174. visitor.getFailures().forEach(function (f) { return _this.addFailure(f); });
  175. };
  176. NgWalker.prototype.visitNgStyleHelper = function (style, context, styleMetadata, baseStart) {
  177. var _this = this;
  178. if (!style) {
  179. return;
  180. }
  181. var sourceFile = this.getContextSourceFile(styleMetadata.url, styleMetadata.style.source);
  182. var visitor = new this._config.cssVisitorCtrl(sourceFile, this._originalOptions, context, styleMetadata, baseStart);
  183. style.visit(visitor);
  184. visitor.getFailures().forEach(function (f) { return _this.addFailure(f); });
  185. };
  186. NgWalker.prototype.getContextSourceFile = function (path, content) {
  187. if (!path) {
  188. return this.getSourceFile();
  189. }
  190. var sf = ts.createSourceFile(path, "`" + content + "`", ts.ScriptTarget.ES5);
  191. var original = sf.getFullText;
  192. sf.getFullText = function () {
  193. var text = original.apply(sf);
  194. return text.substring(1, text.length - 1);
  195. };
  196. return sf;
  197. };
  198. NgWalker.prototype.hasClassName = function (node) {
  199. return (ts.isDecorator(node) && utils_1.getClassName(node.parent)) || (ts.isClassDeclaration(node) && utils_1.getClassName(node));
  200. };
  201. return NgWalker;
  202. }(Lint.RuleWalker));
  203. exports.NgWalker = NgWalker;