diff --git a/README.md b/README.md
index 43576e0..378a2c3 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@ Lightweight language support for angular definitions.
## Prerequisites
- Angular with **Typescript**
-- [Official style guide](https://angular.io/docs/ts/latest/guide/style-guide.html#!#naming) file naming (component `.ts` and `.html` names should match).
+- [Official style guide](https://angular.io/docs/ts/latest/guide/style-guide.html#!#naming) file & selector naming
## Features
diff --git a/src/providers/angular-html-definition-provider.ts b/src/providers/angular-html-definition-provider.ts
index 1b43f37..f28b926 100644
--- a/src/providers/angular-html-definition-provider.ts
+++ b/src/providers/angular-html-definition-provider.ts
@@ -12,7 +12,7 @@ export class AngularHtmlDefinitionProvider implements DefinitionProvider {
async provideDefinition(document: TextDocument, position: Position, token: CancellationToken) {
const lineText = document.lineAt(position).text;
- const regexps = [
+ const propertyRegexps = [
// Interpolation. ex: {{ myProp }}
/({{)([^}]+)}}/g,
@@ -25,9 +25,34 @@ export class AngularHtmlDefinitionProvider implements DefinitionProvider {
// Structural attributes. ex: *ngIf="myProp"
/(\*\w+=")([^"]+)"/g
];
- const expressionMatch: string = utils.parseByLocationRegexps(lineText, position.character, regexps);
- if (!expressionMatch) return null;
+ const propertyMatch = utils.parseByLocationRegexps(lineText, position.character, propertyRegexps);
+ if (!!propertyMatch) {
+ return await this.propertyDefinition(document, position);
+ }
+ // Element. ex: ...
+ const elementRegexp = /(<\/?)([a-zA-Z0-9-]+)/g;
+ const elementMatch = utils.parseByLocationRegexp(lineText, position.character, elementRegexp);
+ if (!!elementMatch) {
+ return await this.elementDefinition(elementMatch);
+ }
+
+ return null;
+ }
+
+ private async elementDefinition(selector: string) {
+ const expectedFileName = `src/**/${selector.replace(/(\w+-)/, (f) => '')}.component.ts`;
+ const foundFiles = await workspace.findFiles(expectedFileName, '**∕node_modules∕**', 2);
+
+ // To be sure of defition origin return only when there is one match.
+ if (foundFiles.length === 1) {
+ return new Location(Uri.file(foundFiles[0].path), new Position(0, 0));
+ }
+
+ return null;
+ }
+
+ private async propertyDefinition(document: TextDocument, position: Position) {
const range = document.getWordRangeAtPosition(position, /[$\w]+/);
if (!range) return null;
diff --git a/test/_test_files/bar.component.ts b/test/_test_files/bar.component.ts
new file mode 100644
index 0000000..9dd3353
--- /dev/null
+++ b/test/_test_files/bar.component.ts
@@ -0,0 +1,4 @@
+@Component({
+ selector: 'xx-bar'
+})
+export class BarComponent { }
diff --git a/test/_test_files/foo.component.html b/test/_test_files/foo.component.html
index 67d40c9..54aa782 100644
--- a/test/_test_files/foo.component.html
+++ b/test/_test_files/foo.component.html
@@ -3,8 +3,10 @@
-
+
{{ myProperty | myPipe }}
{{ myService.myProp }}
{{ myObj?.foo }}
+
+
\ No newline at end of file
diff --git a/test/providers/angular-html-definition-provider.test.ts b/test/providers/angular-html-definition-provider.test.ts
index b08499b..f8ead0f 100644
--- a/test/providers/angular-html-definition-provider.test.ts
+++ b/test/providers/angular-html-definition-provider.test.ts
@@ -75,4 +75,12 @@ suite('AngularHtmlDefinitionProvider', () => {
await assertGoToDefinition(templateFilePath, inputPosition, expectedFile, expectedPosition);
});
+
+ test('should resolve component', async () => {
+ const inputPosition = new vscode.Position(10, 7);
+ const expectedFile = workspaceFilePath('bar.component.ts');
+ const expectedPosition = new vscode.Position(0, 0);
+
+ await assertGoToDefinition(templateFilePath, inputPosition, expectedFile, expectedPosition);
+ });
});