Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .all-contributorsrc
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@
"maintenance",
"code"
]
},
{
"login": "tomastrajan",
"name": "Tomas Trajan",
"avatar_url": "https://avatars.githubusercontent.com/u/3764868?v=4",
"profile": "http://angularexperts.io",
"contributions": [
"maintenance",
"code"
]
}
],
"contributorsPerLine": 7,
Expand Down
3 changes: 3 additions & 0 deletions src/converters/component/component.converter.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ describe('Component converter', () => {
implementation: '',
template: '',
styles: '',
extends: undefined,
methods: [],
methodsPublicExplicit: [],
fieldsPublicExplicit: [],
Expand All @@ -34,6 +35,7 @@ describe('Component converter', () => {
implementation: '',
template: '',
styles: '',
extends: undefined,
methods: [],
methodsPublicExplicit: [],
fieldsPublicExplicit: [],
Expand All @@ -51,6 +53,7 @@ describe('Component converter', () => {
implementation: '',
template: '',
styles: '',
extends: undefined,
methods: [],
methodsPublicExplicit: [],
fieldsPublicExplicit: [],
Expand Down
3 changes: 3 additions & 0 deletions src/converters/directive/directive.converter.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ describe('Directive converter', () => {
inputs: [],
outputs: [],
implementation: '',
extends: undefined,
methods: [],
methodsPublicExplicit: [],
fieldsPublicExplicit: [],
Expand All @@ -28,6 +29,7 @@ describe('Directive converter', () => {
inputs: [],
outputs: [],
implementation: '',
extends: undefined,
methods: [],
methodsPublicExplicit: [],
fieldsPublicExplicit: [],
Expand All @@ -42,6 +44,7 @@ describe('Directive converter', () => {
inputs: [],
outputs: [],
implementation: '',
extends: undefined,
methods: [],
methodsPublicExplicit: [],
fieldsPublicExplicit: [],
Expand Down
3 changes: 3 additions & 0 deletions src/converters/service/service.converter.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ describe('Service stats converter', () => {
className: 'first',
type: NgParselOutputType.SERVICE,
filePath: '',
extends: undefined,
fieldsPublicExplicit: [],
methods: [],
methodsPublicExplicit: [],
Expand All @@ -17,6 +18,7 @@ describe('Service stats converter', () => {
className: 'second',
type: NgParselOutputType.SERVICE,
filePath: '',
extends: undefined,
fieldsPublicExplicit: [],
methods: [],
methodsPublicExplicit: [],
Expand All @@ -25,6 +27,7 @@ describe('Service stats converter', () => {
className: 'third',
type: NgParselOutputType.SERVICE,
filePath: '',
extends: undefined,
fieldsPublicExplicit: [],
methods: [],
methodsPublicExplicit: [],
Expand Down
1 change: 1 addition & 0 deletions src/parser/component/component.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export interface NgParselComponent extends NgParselOutput {
selector: string;
standalone: boolean;
cva: boolean;
extends: string | undefined;
onPush: boolean;
inputs: NgParselFieldDecorator[];
outputs: NgParselFieldDecorator[];
Expand Down
2 changes: 2 additions & 0 deletions src/parser/component/component.parser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ describe('ComponentParser', () => {
selector: 'my-test-comp',
standalone: false,
cva: false,
extends: undefined,
onPush: false,
template: inlineTemplate,
styles: [styles],
Expand Down Expand Up @@ -133,6 +134,7 @@ describe('ComponentParser', () => {
selector: 'my-test-comp',
standalone: true,
cva: false,
extends: undefined,
onPush: false,
template: inlineTemplate,
styles: [styles],
Expand Down
2 changes: 2 additions & 0 deletions src/parser/component/component.parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as ts from 'typescript';
import { tsquery } from '@phenomnomnominal/tsquery';

import { isCva } from '../shared/parser/cva.parser.js';
import { parseExtends } from '../shared/parser/extends.parser.js';
import { NgParselOutputType } from '../shared/model/types.model.js';
import { parseInputsAndOutputs } from '../shared/parser/field-decorator.parser.js';
import { getDecoratorProperties } from '../shared/parser/decorator.parser.js';
Expand Down Expand Up @@ -33,6 +34,7 @@ export function parseComponent(ast: ts.SourceFile, componentFilePath: string): N
filePath: componentFilePath,
selector: componentDecorators.selector as string,
standalone: componentDecorators.standalone || false,
extends: parseExtends(ast),
template: template,
cva: isCva(ast),
onPush: isOnPushChangeDetection(ast),
Expand Down
1 change: 1 addition & 0 deletions src/parser/directive/directive.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export interface NgParselDirective extends NgParselOutput {
className: string;
selector: string;
standalone: boolean;
extends: string | undefined;
cva: boolean;
implementation: string;
inputs: NgParselFieldDecorator[];
Expand Down
2 changes: 2 additions & 0 deletions src/parser/directive/directive.parser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ describe('DirectiveParser', () => {
selector: '[myTestDirective]',
standalone: false,
cva: false,
extends: undefined,
inputs: [
{
decorator: '@Input()',
Expand Down Expand Up @@ -90,6 +91,7 @@ describe('DirectiveParser', () => {
selector: '[myTestDirective]',
standalone: true,
cva: false,
extends: undefined,
inputs: [
{
decorator: '@Input()',
Expand Down
2 changes: 2 additions & 0 deletions src/parser/directive/directive.parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { parseClassName, parseClassJsDoc } from '../shared/parser/class.parser.j
import { parseExplicitPublicMethods, parseMethods } from '../shared/parser/method.parser.js';

import { NgParselDirective } from './directive.model.js';
import { parseExtends } from '../shared/parser/extends.parser.js';

export function parseDirective(ast: ts.SourceFile, directiveFilePath: string): NgParselDirective {
const directiveDecorators = getDecoratorProperties(ast);
Expand All @@ -24,6 +25,7 @@ export function parseDirective(ast: ts.SourceFile, directiveFilePath: string): N
filePath: directiveFilePath,
selector: directiveDecorators.selector as string,
standalone: directiveDecorators.standalone || false,
extends: parseExtends(ast),
cva: isCva(ast),
implementation: directiveImplementation,
inputs: inputsAndOutputs.inputs,
Expand Down
1 change: 1 addition & 0 deletions src/parser/services/service.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { NgParselMethod } from '../shared/model/method.model.js';
import { NgParselField } from '../shared/model/field.model.js';

export interface NgParselService extends NgParselOutput {
extends: string | undefined;
fieldsPublicExplicit: NgParselField[];
methods: NgParselMethod[];
methodsPublicExplicit: NgParselMethod[];
Expand Down
3 changes: 3 additions & 0 deletions src/parser/services/service.parser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ describe('ServiceParser', () => {
type: NgParselOutputType.SERVICE,
className,
filePath,
extends: undefined,
fieldsPublicExplicit: [],
methods: [
{
Expand Down Expand Up @@ -89,6 +90,7 @@ describe('ServiceParser', () => {
className,
filePath,
fieldsPublicExplicit: [],
extends: undefined,
methods: [
{
name: 'foo',
Expand Down Expand Up @@ -146,6 +148,7 @@ describe('ServiceParser', () => {
type: NgParselOutputType.SERVICE,
className,
filePath,
extends: undefined,
fieldsPublicExplicit: [
{
name: 'counter',
Expand Down
4 changes: 3 additions & 1 deletion src/parser/services/service.parser.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import * as ts from 'typescript';

import { parseExtends } from '../shared/parser/extends.parser.js';
import { NgParselOutputType } from '../shared/model/types.model.js';
import { parseExplicitPublicFields } from '../shared/parser/field.parser.js';
import { parseClassName, parseClassJsDoc } from '../shared/parser/class.parser.js';
import { parseExplicitPublicMethods, parseMethods } from '../shared/parser/method.parser.js';

import { NgParselService } from './service.model.js';
import { parseExplicitPublicFields } from '../shared/parser/field.parser.js';

export function parseService(ast: ts.SourceFile, filePath: string): NgParselService {
return {
type: NgParselOutputType.SERVICE,
className: parseClassName(ast),
extends: parseExtends(ast),
filePath,
fieldsPublicExplicit: parseExplicitPublicFields(ast),
methods: parseMethods(ast),
Expand Down
56 changes: 56 additions & 0 deletions src/parser/shared/parser/extends.parser.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { tsquery } from '@phenomnomnominal/tsquery';
import { parseExtends } from './extends.parser.js';

describe('parseExtends', () => {
it('parses extends for a component-like class with extends', () => {
const ast = tsquery.ast(`
@Component({ selector: 'x' })
export class MyComponent extends BaseComponent {}
`);

expect(parseExtends(ast)).toEqual('BaseComponent');
});

it('returns an undefined for a component-like class without extends', () => {
const ast = tsquery.ast(`
@Component({ selector: 'x' })
export class MyComponent {}
`);

expect(parseExtends(ast)).toEqual(undefined);
});

it('parses extends for a directive-like class with extends', () => {
const ast = tsquery.ast(`
@Directive({ selector: '[x]' })
export class MyDirective extends SomeDirectiveBase {}
`);

expect(parseExtends(ast)).toEqual('SomeDirectiveBase');
});

it('returns an undefined for a directive-like class without extends', () => {
const ast = tsquery.ast(`
@Directive({ selector: '[x]' })
export class MyDirective {}
`);

expect(parseExtends(ast)).toEqual(undefined);
});

it('parses extends for a service-like class with generic extends', () => {
const ast = tsquery.ast(`
export class MyService extends BaseService<Thing> {}
`);

expect(parseExtends(ast)).toEqual('BaseService');
});

it('returns an undefined for a service-like class without extends', () => {
const ast = tsquery.ast(`
export class MyService {}
`);

expect(parseExtends(ast)).toEqual(undefined);
});
});
19 changes: 19 additions & 0 deletions src/parser/shared/parser/extends.parser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import * as ts from 'typescript';
import { tsquery } from '@phenomnomnominal/tsquery';

export function parseExtends(ast: ts.SourceFile): string | undefined {
// Find identifiers used in extends heritage clauses
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const identifiers = tsquery(ast, 'HeritageClause > ExpressionWithTypeArguments > Identifier') as any[];

for (const id of identifiers) {
const heritageClause = (id.parent as any)?.parent as ts.HeritageClause | undefined;
if (!heritageClause) continue;

if (heritageClause.token === ts.SyntaxKind.ExtendsKeyword) {
return id.getText();
}
}

return undefined;
}
Loading