2020-11-19 16:31:34 -05:00
|
|
|
/**
|
|
|
|
* @license
|
|
|
|
* Copyright Google LLC All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
|
|
* found in the LICENSE file at https://angular.io/license
|
|
|
|
*/
|
|
|
|
|
2021-02-08 18:23:41 -05:00
|
|
|
import {initMockFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system/testing';
|
2020-11-19 16:31:34 -05:00
|
|
|
|
2021-02-08 18:23:41 -05:00
|
|
|
import {assertFileNames, assertTextSpans, createModuleAndProjectWithDeclarations, humanizeDocumentSpanLike, LanguageServiceTestEnv, OpenBuffer} from '../testing';
|
2020-11-19 16:31:34 -05:00
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('find references and rename locations', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let env: LanguageServiceTestEnv;
|
2020-11-19 16:31:34 -05:00
|
|
|
|
|
|
|
beforeEach(() => {
|
|
|
|
initMockFileSystem('Native');
|
|
|
|
});
|
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
afterEach(() => {
|
|
|
|
// Clear env so it's not accidentally carried over to the next test.
|
|
|
|
env = undefined!;
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('cursor is on binding in component class', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let appFile: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
|
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const files = {
|
|
|
|
'app.ts': `import {Component} from '@angular/core';
|
2020-11-19 16:31:34 -05:00
|
|
|
|
|
|
|
@Component({templateUrl: './app.html'})
|
|
|
|
export class AppCmp {
|
2021-02-08 18:23:41 -05:00
|
|
|
myProp!: string;
|
|
|
|
}`,
|
|
|
|
'app.html': '{{myProp}}'
|
|
|
|
};
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
|
|
|
appFile = project.openFile('app.ts');
|
|
|
|
appFile.moveCursorToText('myP¦rop');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
it('gets component member references from TS file and external template', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(appFile)!;
|
2021-05-03 14:08:24 -04:00
|
|
|
expect(refs.length).toBe(2);
|
|
|
|
assertFileNames(refs, ['app.html', 'app.ts']);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
assertTextSpans(refs, ['myProp']);
|
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
it('gets rename locations from TS file and external template', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(appFile)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(renameLocations.length).toBe(2);
|
|
|
|
assertFileNames(renameLocations, ['app.html', 'app.ts']);
|
|
|
|
assertTextSpans(renameLocations, ['myProp']);
|
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
});
|
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('when cursor is on binding in an external template', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let templateFile: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
|
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const files = {
|
|
|
|
'app.ts': `
|
2020-11-19 16:31:34 -05:00
|
|
|
import {Component} from '@angular/core';
|
|
|
|
|
|
|
|
@Component({templateUrl: './app.html'})
|
|
|
|
export class AppCmp {
|
|
|
|
myProp = '';
|
|
|
|
}`,
|
2021-02-08 18:23:41 -05:00
|
|
|
'app.html': '{{myProp}}'
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
};
|
2021-02-08 18:23:41 -05:00
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
|
|
|
templateFile = project.openFile('app.html');
|
|
|
|
templateFile.moveCursorToText('myP¦rop');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('gets references', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(templateFile)!;
|
2021-05-03 14:08:24 -04:00
|
|
|
expect(refs.length).toBe(2);
|
|
|
|
assertFileNames(refs, ['app.html', 'app.ts']);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
assertTextSpans(refs, ['myProp']);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('gets rename locations', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(templateFile)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(renameLocations.length).toBe(2);
|
|
|
|
assertFileNames(renameLocations, ['app.html', 'app.ts']);
|
|
|
|
assertTextSpans(renameLocations, ['myProp']);
|
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
});
|
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('when cursor is on function call in external template', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let appFile: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
|
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const files = {
|
|
|
|
'app.ts': `
|
2020-11-19 16:31:34 -05:00
|
|
|
import {Component} from '@angular/core';
|
|
|
|
|
2021-02-08 18:23:41 -05:00
|
|
|
@Component({template: '<div (click)="setTitle(2)"></div>'})
|
2020-11-19 16:31:34 -05:00
|
|
|
export class AppCmp {
|
|
|
|
setTitle(s: number) {}
|
2021-02-08 18:23:41 -05:00
|
|
|
}`
|
|
|
|
};
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
|
|
|
appFile = project.openFile('app.ts');
|
|
|
|
appFile.moveCursorToText('setTi¦tle(2)');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
it('gets component member reference in ts file', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(appFile)!;
|
2021-05-03 14:08:24 -04:00
|
|
|
expect(refs.length).toBe(2);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
|
|
|
|
assertFileNames(refs, ['app.ts']);
|
|
|
|
assertTextSpans(refs, ['setTitle']);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('gets rename location in ts file', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(appFile)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(renameLocations.length).toBe(2);
|
|
|
|
|
|
|
|
assertFileNames(renameLocations, ['app.ts']);
|
|
|
|
assertTextSpans(renameLocations, ['setTitle']);
|
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
});
|
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('when cursor in on argument to a function call in an external template', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let appFile: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
|
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const files = {
|
|
|
|
'app.ts': `
|
2020-11-19 16:31:34 -05:00
|
|
|
import {Component} from '@angular/core';
|
|
|
|
|
2021-02-08 18:23:41 -05:00
|
|
|
@Component({template: '<div (click)="setTitle(title)"></div>'})
|
2020-11-19 16:31:34 -05:00
|
|
|
export class AppCmp {
|
|
|
|
title = '';
|
|
|
|
setTitle(s: string) {}
|
2021-02-08 18:23:41 -05:00
|
|
|
}`
|
|
|
|
};
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
|
|
|
appFile = project.openFile('app.ts');
|
|
|
|
appFile.moveCursorToText('(ti¦tle)');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('gets member reference in ts file', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(appFile)!;
|
2021-05-03 14:08:24 -04:00
|
|
|
expect(refs.length).toBe(2);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
|
|
|
|
assertTextSpans(refs, ['title']);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('finds rename location in ts file', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getRenameLocationsAtPosition(appFile)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(refs.length).toBe(2);
|
2020-11-19 16:31:34 -05:00
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
assertTextSpans(refs, ['title']);
|
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
});
|
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('when cursor is on $event in method call arguments', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let file: OpenBuffer;
|
2020-12-16 14:13:34 -05:00
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const files = {
|
|
|
|
'app.ts': `
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
import {Component} from '@angular/core';
|
2021-02-08 18:23:41 -05:00
|
|
|
@Component({template: '<div (click)="setTitle($event)"></div>'})
|
2020-12-16 14:13:34 -05:00
|
|
|
export class AppCmp {
|
|
|
|
setTitle(s: any) {}
|
2021-02-08 18:23:41 -05:00
|
|
|
}`
|
|
|
|
};
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
|
|
|
file = project.openFile('app.ts');
|
|
|
|
file.moveCursorToText('($even¦t)');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('find references', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(refs.length).toBe(1);
|
2020-12-16 14:13:34 -05:00
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
assertTextSpans(refs, ['$event']);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('gets no rename locations', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(renameLocations).toBeUndefined();
|
|
|
|
});
|
2020-12-16 14:13:34 -05:00
|
|
|
});
|
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('when cursor in on LHS of property write in external template', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let file: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
|
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const files = {
|
|
|
|
'app.ts': `
|
2020-11-19 16:31:34 -05:00
|
|
|
import {Component} from '@angular/core';
|
|
|
|
|
|
|
|
@Component({templateUrl: './app.html' })
|
|
|
|
export class AppCmp {
|
|
|
|
title = '';
|
|
|
|
}`,
|
2021-02-08 18:23:41 -05:00
|
|
|
'app.html': `<div (click)="title = 'newtitle'"></div>`
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
};
|
2021-02-08 18:23:41 -05:00
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
|
|
|
file = project.openFile('app.html');
|
|
|
|
file.moveCursorToText('ti¦tle = ');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('gets member reference in ts file', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(file)!;
|
2021-05-03 14:08:24 -04:00
|
|
|
expect(refs.length).toBe(2);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
|
2021-05-03 14:08:24 -04:00
|
|
|
assertFileNames(refs, ['app.ts', 'app.html']);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
assertTextSpans(refs, ['title']);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('gets rename location in ts file', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(renameLocations.length).toBe(2);
|
|
|
|
|
|
|
|
assertFileNames(renameLocations, ['app.ts', 'app.html']);
|
|
|
|
assertTextSpans(renameLocations, ['title']);
|
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
});
|
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('when cursor in on RHS of property write in external template', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let file: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
|
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const files = {
|
|
|
|
'app.ts': `
|
2020-11-19 16:31:34 -05:00
|
|
|
import {Component} from '@angular/core';
|
|
|
|
|
2021-02-08 18:23:41 -05:00
|
|
|
@Component({template: '<div (click)="title = otherTitle"></div>' })
|
2020-11-19 16:31:34 -05:00
|
|
|
export class AppCmp {
|
|
|
|
title = '';
|
|
|
|
otherTitle = '';
|
2021-02-08 18:23:41 -05:00
|
|
|
}`
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
};
|
2021-02-08 18:23:41 -05:00
|
|
|
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
|
|
|
file = project.openFile('app.ts');
|
|
|
|
file.moveCursorToText('= otherT¦itle">');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('get reference to member in ts file', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(file)!;
|
2021-05-03 14:08:24 -04:00
|
|
|
expect(refs.length).toBe(2);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
|
|
|
|
assertFileNames(refs, ['app.ts']);
|
|
|
|
assertTextSpans(refs, ['otherTitle']);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('finds rename location in ts file', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(renameLocations.length).toBe(2);
|
2020-11-19 16:31:34 -05:00
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
assertFileNames(renameLocations, ['app.ts']);
|
|
|
|
assertTextSpans(renameLocations, ['otherTitle']);
|
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
});
|
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('when cursor in on a keyed read', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let file: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
|
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const files = {
|
|
|
|
'app.ts': `
|
2020-11-19 16:31:34 -05:00
|
|
|
import {Component} from '@angular/core';
|
|
|
|
|
2021-02-08 18:23:41 -05:00
|
|
|
@Component({template: '{{hero["name"]}}' })
|
2020-11-19 16:31:34 -05:00
|
|
|
export class AppCmp {
|
|
|
|
hero: {name: string} = {name: 'Superman'};
|
2021-02-08 18:23:41 -05:00
|
|
|
}`
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
};
|
2021-02-08 18:23:41 -05:00
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
|
|
|
file = project.openFile('app.ts');
|
|
|
|
file.moveCursorToText('{{hero["na¦me"]}}');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('gets reference to member type definition and initialization in component class', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
// 3 references: the type definition, the value assignment, and the read in the template
|
2021-05-03 14:08:24 -04:00
|
|
|
expect(refs.length).toBe(3);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
|
|
|
|
assertFileNames(refs, ['app.ts']);
|
|
|
|
// TODO(atscott): investigate if we can make the template keyed read be just the 'name' part.
|
|
|
|
// The TypeScript implementation specifically adjusts the span to accommodate string literals:
|
|
|
|
// https://sourcegraph.com/github.com/microsoft/TypeScript@d5779c75d3dd19565b60b9e2960b8aac36d4d635/-/blob/src/services/findAllReferences.ts#L508-512
|
|
|
|
// One possible solution would be to extend `FullTemplateMapping` to include the matched TCB
|
|
|
|
// node and then do the same thing that TS does: if the node is a string, adjust the span.
|
2021-05-03 14:08:24 -04:00
|
|
|
assertTextSpans(refs, ['name', '"name"']);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('gets rename locations in component class', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(renameLocations).toBeUndefined();
|
|
|
|
|
|
|
|
// TODO(atscott): We should handle this case. The fix requires us to fix the result span as
|
|
|
|
// described above.
|
|
|
|
// 3 references: the type definition, the value assignment, and the read in the template
|
|
|
|
// expect(renameLocations.length).toBe(3);
|
|
|
|
//
|
|
|
|
// assertFileNames(renameLocations, ['app.ts']);
|
|
|
|
// assertTextSpans(renameLocations, ['name']);
|
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
});
|
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('when cursor in on RHS of keyed write in a template', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let file: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
|
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const files = {
|
|
|
|
'app.ts': `
|
2020-11-19 16:31:34 -05:00
|
|
|
import {Component} from '@angular/core';
|
|
|
|
|
|
|
|
@Component({templateUrl: './app.html' })
|
|
|
|
export class AppCmp {
|
|
|
|
hero: {name: string} = {name: 'Superman'};
|
|
|
|
batman = 'batman';
|
|
|
|
}`,
|
2021-02-08 18:23:41 -05:00
|
|
|
'app.html': `<div (click)="hero['name'] = batman"></div>`
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
};
|
2021-02-08 18:23:41 -05:00
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
|
|
|
file = project.openFile('app.html');
|
|
|
|
file.moveCursorToText('bat¦man');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('get references in ts file', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(file)!;
|
2021-05-03 14:08:24 -04:00
|
|
|
expect(refs.length).toBe(2);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
|
2021-05-03 14:08:24 -04:00
|
|
|
assertFileNames(refs, ['app.ts', 'app.html']);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
assertTextSpans(refs, ['batman']);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('finds rename location in ts file', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(renameLocations.length).toBe(2);
|
|
|
|
|
|
|
|
assertFileNames(renameLocations, ['app.ts', 'app.html']);
|
|
|
|
assertTextSpans(renameLocations, ['batman']);
|
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
});
|
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('when cursor in on an element reference', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let file: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
|
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const files = {
|
|
|
|
'app.ts': `
|
2020-11-19 16:31:34 -05:00
|
|
|
import {Component} from '@angular/core';
|
|
|
|
|
2021-02-08 18:23:41 -05:00
|
|
|
@Component({template: '<input #myInput /> {{ myInput.value }}'})
|
2020-11-19 16:31:34 -05:00
|
|
|
export class AppCmp {
|
|
|
|
title = '';
|
2021-02-08 18:23:41 -05:00
|
|
|
}`
|
|
|
|
};
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
|
|
|
file = project.openFile('app.ts');
|
|
|
|
file.moveCursorToText('myInp¦ut.value');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('get reference to declaration in template', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
|
2020-11-19 16:31:34 -05:00
|
|
|
expect(refs.length).toBe(2);
|
|
|
|
assertTextSpans(refs, ['myInput']);
|
|
|
|
|
|
|
|
// Get the declaration by finding the reference that appears first in the template
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
refs.sort((a, b) => a.textSpan.start - b.textSpan.start);
|
|
|
|
expect(refs[0].isDefinition).toBe(true);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('finds rename location in template', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
|
|
|
|
expect(renameLocations.length).toBe(2);
|
|
|
|
assertTextSpans(renameLocations, ['myInput']);
|
2020-11-19 16:31:34 -05:00
|
|
|
});
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('when cursor in on a template reference', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let file: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
|
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const files = {
|
|
|
|
'app.ts': `
|
2020-11-19 16:31:34 -05:00
|
|
|
import {Component} from '@angular/core';
|
|
|
|
|
|
|
|
@Component({templateUrl: './app.html'})
|
|
|
|
export class AppCmp {
|
|
|
|
title = '';
|
|
|
|
}`,
|
2021-02-08 18:23:41 -05:00
|
|
|
'app.html': `
|
|
|
|
<ng-template #myTemplate >bla</ng-template>
|
|
|
|
<ng-container [ngTemplateOutlet]="myTemplate"></ng-container>`
|
2020-11-19 16:31:34 -05:00
|
|
|
};
|
2021-02-08 18:23:41 -05:00
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
|
|
|
file = project.openFile('app.html');
|
|
|
|
file.moveCursorToText('#myTem¦plate');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('gets reference to declaration', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(file)!;
|
2020-11-19 16:31:34 -05:00
|
|
|
expect(refs.length).toBe(2);
|
|
|
|
assertTextSpans(refs, ['myTemplate']);
|
|
|
|
assertFileNames(refs, ['app.html']);
|
|
|
|
|
|
|
|
// Get the declaration by finding the reference that appears first in the template
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
refs.sort((a, b) => a.textSpan.start - b.textSpan.start);
|
|
|
|
expect(refs[0].isDefinition).toBe(true);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('finds rename location in template', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(renameLocations.length).toBe(2);
|
|
|
|
assertTextSpans(renameLocations, ['myTemplate']);
|
|
|
|
assertFileNames(renameLocations, ['app.html']);
|
2020-11-19 16:31:34 -05:00
|
|
|
});
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('template references', () => {
|
|
|
|
describe('directives', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const dirFileContents = `
|
2020-11-19 16:31:34 -05:00
|
|
|
import {Directive} from '@angular/core';
|
|
|
|
|
|
|
|
@Directive({selector: '[dir]', exportAs: 'myDir'})
|
|
|
|
export class Dir {
|
|
|
|
dirValue!: string;
|
|
|
|
doSomething() {}
|
|
|
|
}`;
|
2021-02-08 18:23:41 -05:00
|
|
|
const appFileContents = `
|
2020-11-19 16:31:34 -05:00
|
|
|
import {Component} from '@angular/core';
|
|
|
|
|
|
|
|
@Component({templateUrl: './app.html'})
|
|
|
|
export class AppCmp {}`;
|
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('when cursor is on usage of template reference', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let file: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const files = {
|
|
|
|
'app.ts': appFileContents,
|
|
|
|
'dir.ts': dirFileContents,
|
|
|
|
'app.html': '<div [dir] #dirRef="myDir"></div> {{ dirRef }}'
|
|
|
|
};
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
|
|
|
file = project.openFile('app.html');
|
|
|
|
file.moveCursorToText('#dirR¦ef');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should get references', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(refs.length).toBe(2);
|
|
|
|
assertFileNames(refs, ['app.html']);
|
|
|
|
assertTextSpans(refs, ['dirRef']);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should find rename locations', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(renameLocations.length).toBe(2);
|
|
|
|
assertFileNames(renameLocations, ['app.html']);
|
|
|
|
assertTextSpans(renameLocations, ['dirRef']);
|
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
});
|
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('when cursor is on a property read of directive reference', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let file: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const files = {
|
|
|
|
'app.ts': appFileContents,
|
|
|
|
'dir.ts': dirFileContents,
|
|
|
|
'app.html': '<div [dir] #dirRef="myDir"></div> {{ dirRef.dirValue }}'
|
|
|
|
};
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
|
|
|
file = project.openFile('app.html');
|
|
|
|
file.moveCursorToText('dirRef.dirV¦alue');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should get references', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(file)!;
|
2021-05-03 14:08:24 -04:00
|
|
|
expect(refs.length).toBe(2);
|
|
|
|
assertFileNames(refs, ['dir.ts', 'app.html']);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
assertTextSpans(refs, ['dirValue']);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should find rename locations', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(renameLocations.length).toBe(2);
|
|
|
|
assertFileNames(renameLocations, ['dir.ts', 'app.html']);
|
|
|
|
assertTextSpans(renameLocations, ['dirValue']);
|
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
});
|
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('when cursor is on a safe prop read', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let file: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const files = {
|
|
|
|
'app.ts': appFileContents,
|
|
|
|
'dir.ts': dirFileContents,
|
|
|
|
'app.html': '<div [dir] #dirRef="myDir"></div> {{ dirRef?.dirValue }}'
|
|
|
|
};
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
|
|
|
file = project.openFile('app.html');
|
|
|
|
file.moveCursorToText('dirRef?.dirV¦alue');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('should get references', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(file)!;
|
2021-05-03 14:08:24 -04:00
|
|
|
expect(refs.length).toBe(2);
|
|
|
|
assertFileNames(refs, ['dir.ts', 'app.html']);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
assertTextSpans(refs, ['dirValue']);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should find rename locations', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(renameLocations.length).toBe(2);
|
|
|
|
assertFileNames(renameLocations, ['dir.ts', 'app.html']);
|
|
|
|
assertTextSpans(renameLocations, ['dirValue']);
|
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
});
|
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('when cursor is on safe method call', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let file: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const files = {
|
|
|
|
'app.ts': appFileContents,
|
|
|
|
'dir.ts': dirFileContents,
|
|
|
|
'app.html': '<div [dir] #dirRef="myDir"></div> {{ dirRef?.doSomething() }}'
|
|
|
|
};
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
|
|
|
file = project.openFile('app.html');
|
|
|
|
file.moveCursorToText('dirRef?.doSometh¦ing()');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('should get references', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(file)!;
|
2021-05-03 14:08:24 -04:00
|
|
|
expect(refs.length).toBe(2);
|
|
|
|
assertFileNames(refs, ['dir.ts', 'app.html']);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
assertTextSpans(refs, ['doSomething']);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should find rename locations', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(renameLocations.length).toBe(2);
|
|
|
|
assertFileNames(renameLocations, ['dir.ts', 'app.html']);
|
|
|
|
assertTextSpans(renameLocations, ['doSomething']);
|
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('template variables', () => {
|
|
|
|
describe('when cursor is on variable which was initialized implicitly', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let file: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const files = {
|
|
|
|
'app.ts': `
|
2020-11-19 16:31:34 -05:00
|
|
|
import {Component} from '@angular/core';
|
|
|
|
|
2021-01-15 13:47:39 -05:00
|
|
|
@Component({templateUrl: './template.ng.html'})
|
2020-11-19 16:31:34 -05:00
|
|
|
export class AppCmp {
|
|
|
|
heroes: string[] = [];
|
2021-02-08 18:23:41 -05:00
|
|
|
}`,
|
|
|
|
'template.ng.html': `
|
|
|
|
<div *ngFor="let hero of heroes">
|
|
|
|
<span *ngIf="hero">
|
|
|
|
{{hero}}
|
|
|
|
</span>
|
|
|
|
</div>
|
|
|
|
`
|
2021-01-15 13:47:39 -05:00
|
|
|
};
|
2021-02-08 18:23:41 -05:00
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
|
|
|
file = project.openFile('template.ng.html');
|
|
|
|
file.moveCursorToText('{{her¦o}}');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
it('should find references', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(file)!;
|
2021-01-15 13:47:39 -05:00
|
|
|
expect(refs.length).toBe(3);
|
|
|
|
assertFileNames(refs, ['template.ng.html']);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
assertTextSpans(refs, ['hero']);
|
|
|
|
|
|
|
|
// Get the declaration by finding the reference that appears first in the template
|
2021-02-08 18:23:41 -05:00
|
|
|
refs.sort((a, b) => a.textSpan.start - b.textSpan.start);
|
|
|
|
expect(refs[0].isDefinition).toBe(true);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should find rename locations', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
2021-01-15 13:47:39 -05:00
|
|
|
expect(renameLocations.length).toBe(3);
|
|
|
|
assertFileNames(renameLocations, ['template.ng.html']);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
assertTextSpans(renameLocations, ['hero']);
|
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
});
|
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('when cursor is on renamed variable', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let file: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const files = {
|
|
|
|
'app.ts': `
|
2020-11-19 16:31:34 -05:00
|
|
|
import {Component} from '@angular/core';
|
|
|
|
|
2021-02-08 18:23:41 -05:00
|
|
|
@Component({template: '<div *ngFor="let hero of heroes; let iRef = index">{{iRef}}</div>'})
|
2020-11-19 16:31:34 -05:00
|
|
|
export class AppCmp {
|
|
|
|
heroes: string[] = [];
|
2021-02-08 18:23:41 -05:00
|
|
|
}`
|
|
|
|
};
|
|
|
|
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
|
|
|
file = project.openFile('app.ts');
|
|
|
|
file.moveCursorToText('{{iR¦ef}}');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
it('should find references', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(refs.length).toBe(2);
|
|
|
|
assertFileNames(refs, ['app.ts']);
|
|
|
|
assertTextSpans(refs, ['iRef']);
|
|
|
|
|
|
|
|
// Get the declaration by finding the reference that appears first in the template
|
2021-02-08 18:23:41 -05:00
|
|
|
refs.sort((a, b) => a.textSpan.start - b.textSpan.start);
|
|
|
|
expect(refs[0].isDefinition).toBe(true);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should find rename locations', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(renameLocations.length).toBe(2);
|
|
|
|
assertFileNames(renameLocations, ['app.ts']);
|
|
|
|
assertTextSpans(renameLocations, ['iRef']);
|
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
});
|
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('when cursor is on initializer of variable', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let file: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const files = {
|
|
|
|
'example-directive.ts': `
|
2020-11-19 16:31:34 -05:00
|
|
|
import {Directive, Input} from '@angular/core';
|
|
|
|
|
|
|
|
export class ExampleContext<T> {
|
|
|
|
constructor(readonly $implicit: T, readonly identifier: string) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Directive({ selector: '[example]' })
|
|
|
|
export class ExampleDirective<T> {
|
|
|
|
@Input() set example(v: T) { }
|
|
|
|
static ngTemplateContextGuard<T>(dir: ExampleDirective<T>, ctx: unknown):
|
|
|
|
ctx is ExampleContext<T> {
|
|
|
|
return true;
|
|
|
|
}
|
2021-02-08 18:23:41 -05:00
|
|
|
}`,
|
|
|
|
'app.ts': `
|
2020-11-19 16:31:34 -05:00
|
|
|
import {Component, NgModule} from '@angular/core';
|
|
|
|
import {ExampleDirective} from './example-directive';
|
|
|
|
|
2021-02-08 18:23:41 -05:00
|
|
|
@Component({template: '<div *example="state; let id = identifier">{{id}}</div>'})
|
2020-11-19 16:31:34 -05:00
|
|
|
export class AppCmp {
|
|
|
|
state = {};
|
|
|
|
}
|
|
|
|
|
|
|
|
@NgModule({declarations: [AppCmp, ExampleDirective]})
|
2021-02-08 18:23:41 -05:00
|
|
|
export class AppModule {}`
|
|
|
|
};
|
|
|
|
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = env.addProject('test', files);
|
|
|
|
file = project.openFile('app.ts');
|
|
|
|
file.moveCursorToText('identif¦ier');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
env.expectNoSourceDiagnostics();
|
2021-02-08 18:23:41 -05:00
|
|
|
project.expectNoTemplateDiagnostics('app.ts', 'AppCmp');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should find references', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(file)!;
|
2021-05-03 14:08:24 -04:00
|
|
|
expect(refs.length).toBe(2);
|
|
|
|
assertFileNames(refs, ['app.ts', 'example-directive.ts']);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
assertTextSpans(refs, ['identifier']);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should find rename locations', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(renameLocations.length).toBe(2);
|
|
|
|
assertFileNames(renameLocations, ['app.ts', 'example-directive.ts']);
|
|
|
|
assertTextSpans(renameLocations, ['identifier']);
|
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
});
|
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('when cursor is on property read of variable', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let file: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const files = {
|
|
|
|
'app.ts': `
|
2020-11-19 16:31:34 -05:00
|
|
|
import {Component} from '@angular/core';
|
|
|
|
|
2021-02-08 18:23:41 -05:00
|
|
|
@Component({template: '<div *ngFor="let hero of heroes">{{hero.name}}</div>'})
|
2020-11-19 16:31:34 -05:00
|
|
|
export class AppCmp {
|
|
|
|
heroes: Array<{name: string}> = [];
|
2021-02-08 18:23:41 -05:00
|
|
|
}`
|
|
|
|
};
|
|
|
|
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
|
|
|
file = project.openFile('app.ts');
|
|
|
|
file.moveCursorToText('hero.na¦me');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should find references', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(file)!;
|
2021-05-03 14:08:24 -04:00
|
|
|
expect(refs.length).toBe(2);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
assertFileNames(refs, ['app.ts']);
|
|
|
|
assertTextSpans(refs, ['name']);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should find rename locations', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(renameLocations.length).toBe(2);
|
|
|
|
assertFileNames(renameLocations, ['app.ts']);
|
|
|
|
assertTextSpans(renameLocations, ['name']);
|
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('pipes', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const prefixPipe = `
|
2020-11-19 16:31:34 -05:00
|
|
|
import {Pipe, PipeTransform} from '@angular/core';
|
|
|
|
|
|
|
|
@Pipe({ name: 'prefixPipe' })
|
|
|
|
export class PrefixPipe implements PipeTransform {
|
|
|
|
transform(value: string, prefix: string): string;
|
|
|
|
transform(value: number, prefix: number): number;
|
|
|
|
transform(value: string|number, prefix: string|number): string|number {
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
}`;
|
|
|
|
|
2021-01-22 12:03:37 -05:00
|
|
|
for (const checkTypeOfPipes of [true, false]) {
|
|
|
|
describe(`when cursor is on pipe name, checkTypeOfPipes: ${checkTypeOfPipes}`, () => {
|
|
|
|
let file: OpenBuffer;
|
|
|
|
beforeEach(() => {
|
|
|
|
const files = {
|
|
|
|
'app.ts': `
|
2020-11-19 16:31:34 -05:00
|
|
|
import {Component} from '@angular/core';
|
|
|
|
|
2021-02-08 18:23:41 -05:00
|
|
|
@Component({template: '{{birthday | prefixPipe: "MM/dd/yy"}}'})
|
2020-11-19 16:31:34 -05:00
|
|
|
export class AppCmp {
|
|
|
|
birthday = '';
|
|
|
|
}
|
2021-02-08 18:23:41 -05:00
|
|
|
`,
|
2021-01-22 12:03:37 -05:00
|
|
|
'prefix-pipe.ts': prefixPipe
|
|
|
|
};
|
2021-02-08 18:23:41 -05:00
|
|
|
|
2021-01-22 12:03:37 -05:00
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
|
|
|
file = project.openFile('app.ts');
|
|
|
|
file.moveCursorToText('prefi¦xPipe:');
|
|
|
|
});
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
|
2021-01-22 12:03:37 -05:00
|
|
|
it('should find references', () => {
|
|
|
|
const refs = getReferencesAtPosition(file)!;
|
|
|
|
expect(refs.length).toBe(5);
|
|
|
|
assertFileNames(refs, ['index.d.ts', 'prefix-pipe.ts', 'app.ts']);
|
|
|
|
assertTextSpans(refs, ['transform', 'prefixPipe']);
|
|
|
|
});
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
|
2021-01-22 12:03:37 -05:00
|
|
|
it('should find rename locations', () => {
|
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
|
|
|
expect(renameLocations.length).toBe(2);
|
|
|
|
assertFileNames(renameLocations, ['prefix-pipe.ts', 'app.ts']);
|
|
|
|
assertTextSpans(renameLocations, ['prefixPipe']);
|
|
|
|
});
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
|
2021-01-22 12:03:37 -05:00
|
|
|
it('should get rename info', () => {
|
|
|
|
const result = file.getRenameInfo() as ts.RenameInfoSuccess;
|
|
|
|
expect(result.canRename).toEqual(true);
|
|
|
|
expect(result.displayName).toEqual('prefixPipe');
|
|
|
|
});
|
feat(language-service): Enable renaming of pipes (#40523)
This commit updates the logic in the LS renaming to handle renaming of
pipes, both from the name expression in the pipe metadata as well as
from the template.
The approach here is to introduce a new concept for renaming: an
"indirect" rename. In this type of rename, we find rename locations
in with the native TS Language Service using a different node than the
one we are renaming. Using pipes as an example, if we want to rename the
pipe name from the string literal expression, we use the transform
method to find rename locations rather than the string literal itself
(which will not return any results because it's just a string).
So the general approach is:
* Determine the details about the requested rename location, i.e. the
targeted template node and symbol for a template rename, or the TS
node for a rename outside a template.
* Using the details of the location, determine if the node is attempting
to rename something that is an indirect rename (pipes, selectors,
bindings). Other renames are considered "direct" and we use whatever
results the native TSLS returns for the rename locations.
* In the case of indirect renames, we throw out results that do not
appear in the templates (in this case, the shim files). These results will be
for the "indirect" rename that we don't want to touch, but are only
using to find template results.
* Create an additional rename result for the string literal expression
that is used for the input/output alias, the pipe name, or the
selector.
Note that renaming is moving towards being much more accurate in its
results than "find references". When the approach for renaming
stabilizes, we may want to then port the changes back to being shared
with the approach for retrieving references.
PR Close #40523
2021-01-20 20:54:20 -05:00
|
|
|
});
|
2021-01-22 12:03:37 -05:00
|
|
|
}
|
feat(language-service): Enable renaming of pipes (#40523)
This commit updates the logic in the LS renaming to handle renaming of
pipes, both from the name expression in the pipe metadata as well as
from the template.
The approach here is to introduce a new concept for renaming: an
"indirect" rename. In this type of rename, we find rename locations
in with the native TS Language Service using a different node than the
one we are renaming. Using pipes as an example, if we want to rename the
pipe name from the string literal expression, we use the transform
method to find rename locations rather than the string literal itself
(which will not return any results because it's just a string).
So the general approach is:
* Determine the details about the requested rename location, i.e. the
targeted template node and symbol for a template rename, or the TS
node for a rename outside a template.
* Using the details of the location, determine if the node is attempting
to rename something that is an indirect rename (pipes, selectors,
bindings). Other renames are considered "direct" and we use whatever
results the native TSLS returns for the rename locations.
* In the case of indirect renames, we throw out results that do not
appear in the templates (in this case, the shim files). These results will be
for the "indirect" rename that we don't want to touch, but are only
using to find template results.
* Create an additional rename result for the string literal expression
that is used for the input/output alias, the pipe name, or the
selector.
Note that renaming is moving towards being much more accurate in its
results than "find references". When the approach for renaming
stabilizes, we may want to then port the changes back to being shared
with the approach for retrieving references.
PR Close #40523
2021-01-20 20:54:20 -05:00
|
|
|
|
|
|
|
describe('when cursor is on pipe name expression', () => {
|
|
|
|
it('finds rename locations and rename info', () => {
|
|
|
|
const files = {
|
|
|
|
'/app.ts': `
|
|
|
|
import {Component} from '@angular/core';
|
|
|
|
|
|
|
|
@Component({template: '{{birthday | prefixPipe: "MM/dd/yy"}}'})
|
|
|
|
export class AppCmp {
|
|
|
|
birthday = '';
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
'prefix-pipe.ts': prefixPipe
|
|
|
|
};
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
|
|
|
const file = project.openFile('app.ts');
|
|
|
|
file.moveCursorToText('prefi¦xPipe:');
|
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
|
|
|
expect(renameLocations.length).toBe(2);
|
|
|
|
assertFileNames(renameLocations, ['prefix-pipe.ts', 'app.ts']);
|
|
|
|
assertTextSpans(renameLocations, ['prefixPipe']);
|
|
|
|
|
|
|
|
const result = file.getRenameInfo() as ts.RenameInfoSuccess;
|
|
|
|
expect(result.canRename).toEqual(true);
|
|
|
|
expect(result.displayName).toEqual('prefixPipe');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('finds rename locations in base class', () => {
|
|
|
|
const files = {
|
|
|
|
'/base_pipe.ts': `
|
|
|
|
import {Pipe, PipeTransform} from '@angular/core';
|
|
|
|
|
|
|
|
@Pipe({ name: 'basePipe' })
|
|
|
|
export class BasePipe implements PipeTransform {
|
|
|
|
transform(value: string, prefix: string): string;
|
|
|
|
transform(value: number, prefix: number): number;
|
|
|
|
transform(value: string|number, prefix: string|number): string|number {
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
}`,
|
|
|
|
'prefix_pipe.ts': prefixPipe,
|
|
|
|
'app.ts': `
|
|
|
|
import {Component} from '@angular/core';
|
|
|
|
|
|
|
|
@Component({template: '{{"a" | prefixPipe: "MM/dd/yy"}}'})
|
|
|
|
export class AppCmp { }
|
|
|
|
`
|
|
|
|
};
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
|
|
|
const file = project.openFile('prefix_pipe.ts');
|
|
|
|
file.moveCursorToText(`'prefi¦xPipe'`);
|
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
|
|
|
expect(renameLocations.length).toBe(2);
|
|
|
|
assertFileNames(renameLocations, ['prefix_pipe.ts', 'app.ts']);
|
|
|
|
assertTextSpans(renameLocations, ['prefixPipe']);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
});
|
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('when cursor is on pipe argument', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let file: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const files = {
|
|
|
|
'prefix-pipe.ts': prefixPipe,
|
|
|
|
'app.ts': `
|
2020-11-19 16:31:34 -05:00
|
|
|
import {Component} from '@angular/core';
|
|
|
|
|
2021-02-08 18:23:41 -05:00
|
|
|
@Component({template: '{{birthday | prefixPipe: prefix}}'})
|
2020-11-19 16:31:34 -05:00
|
|
|
export class AppCmp {
|
|
|
|
birthday = '';
|
|
|
|
prefix = '';
|
|
|
|
}
|
2021-02-08 18:23:41 -05:00
|
|
|
`
|
|
|
|
};
|
|
|
|
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
|
|
|
file = project.openFile('app.ts');
|
|
|
|
file.moveCursorToText('prefixPipe: pr¦efix');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should find references', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(file)!;
|
2021-05-03 14:08:24 -04:00
|
|
|
expect(refs.length).toBe(2);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
assertFileNames(refs, ['app.ts']);
|
|
|
|
assertTextSpans(refs, ['prefix']);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should find rename locations', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(renameLocations.length).toBe(2);
|
|
|
|
assertFileNames(renameLocations, ['app.ts']);
|
|
|
|
assertTextSpans(renameLocations, ['prefix']);
|
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('inputs', () => {
|
|
|
|
const dirFileContents = `
|
|
|
|
import {Directive, Input} from '@angular/core';
|
|
|
|
|
|
|
|
@Directive({selector: '[string-model]'})
|
|
|
|
export class StringModel {
|
|
|
|
@Input() model!: string;
|
|
|
|
@Input('alias') aliasedModel!: string;
|
|
|
|
}`;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('when cursor is on the input in the template', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let file: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const files = {
|
|
|
|
'string-model.ts': dirFileContents,
|
|
|
|
'app.ts': `
|
2020-11-19 16:31:34 -05:00
|
|
|
import {Component} from '@angular/core';
|
|
|
|
|
2021-02-08 18:23:41 -05:00
|
|
|
@Component({template: '<div string-model [model]="title"></div>'})
|
2020-11-19 16:31:34 -05:00
|
|
|
export class AppCmp {
|
|
|
|
title = 'title';
|
2021-02-08 18:23:41 -05:00
|
|
|
}`
|
|
|
|
};
|
|
|
|
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
|
|
|
file = project.openFile('app.ts');
|
|
|
|
file.moveCursorToText('[mod¦el]');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should find references', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(file)!;
|
2021-05-03 14:08:24 -04:00
|
|
|
expect(refs.length).toEqual(2);
|
|
|
|
assertFileNames(refs, ['string-model.ts', 'app.ts']);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
assertTextSpans(refs, ['model']);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should find rename locations', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(renameLocations.length).toEqual(2);
|
|
|
|
assertFileNames(renameLocations, ['string-model.ts', 'app.ts']);
|
|
|
|
assertTextSpans(renameLocations, ['model']);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('when cursor is on an input that maps to multiple directives', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let file: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const files = {
|
|
|
|
'other-dir.ts': `
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
import {Directive, Input} from '@angular/core';
|
|
|
|
|
|
|
|
@Directive({selector: '[string-model]'})
|
|
|
|
export class OtherDir {
|
feat(language-service): Enable renaming of pipes (#40523)
This commit updates the logic in the LS renaming to handle renaming of
pipes, both from the name expression in the pipe metadata as well as
from the template.
The approach here is to introduce a new concept for renaming: an
"indirect" rename. In this type of rename, we find rename locations
in with the native TS Language Service using a different node than the
one we are renaming. Using pipes as an example, if we want to rename the
pipe name from the string literal expression, we use the transform
method to find rename locations rather than the string literal itself
(which will not return any results because it's just a string).
So the general approach is:
* Determine the details about the requested rename location, i.e. the
targeted template node and symbol for a template rename, or the TS
node for a rename outside a template.
* Using the details of the location, determine if the node is attempting
to rename something that is an indirect rename (pipes, selectors,
bindings). Other renames are considered "direct" and we use whatever
results the native TSLS returns for the rename locations.
* In the case of indirect renames, we throw out results that do not
appear in the templates (in this case, the shim files). These results will be
for the "indirect" rename that we don't want to touch, but are only
using to find template results.
* Create an additional rename result for the string literal expression
that is used for the input/output alias, the pipe name, or the
selector.
Note that renaming is moving towards being much more accurate in its
results than "find references". When the approach for renaming
stabilizes, we may want to then port the changes back to being shared
with the approach for retrieving references.
PR Close #40523
2021-01-20 20:54:20 -05:00
|
|
|
@Input('model') otherDirAliasedInput!: any;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
}
|
2021-02-08 18:23:41 -05:00
|
|
|
`,
|
|
|
|
'string-model.ts': dirFileContents,
|
|
|
|
'app.ts': `
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
import {Component} from '@angular/core';
|
|
|
|
|
2021-02-08 18:23:41 -05:00
|
|
|
@Component({template: '<div string-model [model]="title"></div>'})
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
export class AppCmp {
|
|
|
|
title = 'title';
|
2021-02-08 18:23:41 -05:00
|
|
|
}`
|
|
|
|
};
|
|
|
|
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
|
|
|
file = project.openFile('app.ts');
|
|
|
|
file.moveCursorToText('[mod¦el]');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
2021-01-21 18:28:42 -05:00
|
|
|
it('should find references', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(refs.length).toEqual(3);
|
feat(language-service): Enable renaming of pipes (#40523)
This commit updates the logic in the LS renaming to handle renaming of
pipes, both from the name expression in the pipe metadata as well as
from the template.
The approach here is to introduce a new concept for renaming: an
"indirect" rename. In this type of rename, we find rename locations
in with the native TS Language Service using a different node than the
one we are renaming. Using pipes as an example, if we want to rename the
pipe name from the string literal expression, we use the transform
method to find rename locations rather than the string literal itself
(which will not return any results because it's just a string).
So the general approach is:
* Determine the details about the requested rename location, i.e. the
targeted template node and symbol for a template rename, or the TS
node for a rename outside a template.
* Using the details of the location, determine if the node is attempting
to rename something that is an indirect rename (pipes, selectors,
bindings). Other renames are considered "direct" and we use whatever
results the native TSLS returns for the rename locations.
* In the case of indirect renames, we throw out results that do not
appear in the templates (in this case, the shim files). These results will be
for the "indirect" rename that we don't want to touch, but are only
using to find template results.
* Create an additional rename result for the string literal expression
that is used for the input/output alias, the pipe name, or the
selector.
Note that renaming is moving towards being much more accurate in its
results than "find references". When the approach for renaming
stabilizes, we may want to then port the changes back to being shared
with the approach for retrieving references.
PR Close #40523
2021-01-20 20:54:20 -05:00
|
|
|
assertFileNames(refs, ['string-model.ts', 'app.ts', 'other-dir.ts']);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
assertTextSpans(refs, ['model', 'otherDirAliasedInput']);
|
|
|
|
});
|
|
|
|
|
|
|
|
// TODO(atscott): This test fails because template symbol builder only returns one binding.
|
|
|
|
// The result is that rather than returning `undefined` because we don't handle alias inputs,
|
|
|
|
// we return the rename locations for the first binding.
|
feat(language-service): Enable renaming of pipes (#40523)
This commit updates the logic in the LS renaming to handle renaming of
pipes, both from the name expression in the pipe metadata as well as
from the template.
The approach here is to introduce a new concept for renaming: an
"indirect" rename. In this type of rename, we find rename locations
in with the native TS Language Service using a different node than the
one we are renaming. Using pipes as an example, if we want to rename the
pipe name from the string literal expression, we use the transform
method to find rename locations rather than the string literal itself
(which will not return any results because it's just a string).
So the general approach is:
* Determine the details about the requested rename location, i.e. the
targeted template node and symbol for a template rename, or the TS
node for a rename outside a template.
* Using the details of the location, determine if the node is attempting
to rename something that is an indirect rename (pipes, selectors,
bindings). Other renames are considered "direct" and we use whatever
results the native TSLS returns for the rename locations.
* In the case of indirect renames, we throw out results that do not
appear in the templates (in this case, the shim files). These results will be
for the "indirect" rename that we don't want to touch, but are only
using to find template results.
* Create an additional rename result for the string literal expression
that is used for the input/output alias, the pipe name, or the
selector.
Note that renaming is moving towards being much more accurate in its
results than "find references". When the approach for renaming
stabilizes, we may want to then port the changes back to being shared
with the approach for retrieving references.
PR Close #40523
2021-01-20 20:54:20 -05:00
|
|
|
it('should find rename locations', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(renameLocations).toBeUndefined();
|
feat(language-service): Enable renaming of pipes (#40523)
This commit updates the logic in the LS renaming to handle renaming of
pipes, both from the name expression in the pipe metadata as well as
from the template.
The approach here is to introduce a new concept for renaming: an
"indirect" rename. In this type of rename, we find rename locations
in with the native TS Language Service using a different node than the
one we are renaming. Using pipes as an example, if we want to rename the
pipe name from the string literal expression, we use the transform
method to find rename locations rather than the string literal itself
(which will not return any results because it's just a string).
So the general approach is:
* Determine the details about the requested rename location, i.e. the
targeted template node and symbol for a template rename, or the TS
node for a rename outside a template.
* Using the details of the location, determine if the node is attempting
to rename something that is an indirect rename (pipes, selectors,
bindings). Other renames are considered "direct" and we use whatever
results the native TSLS returns for the rename locations.
* In the case of indirect renames, we throw out results that do not
appear in the templates (in this case, the shim files). These results will be
for the "indirect" rename that we don't want to touch, but are only
using to find template results.
* Create an additional rename result for the string literal expression
that is used for the input/output alias, the pipe name, or the
selector.
Note that renaming is moving towards being much more accurate in its
results than "find references". When the approach for renaming
stabilizes, we may want to then port the changes back to being shared
with the approach for retrieving references.
PR Close #40523
2021-01-20 20:54:20 -05:00
|
|
|
// TODO(atscott): The below assertions are the correct ones if we were supporting aliases
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
// expect(renameLocations.length).toEqual(3);
|
|
|
|
// assertFileNames(renameLocations, ['string-model.ts', 'app.ts', 'other-dir']);
|
|
|
|
// assertTextSpans(renameLocations, ['model']);
|
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
});
|
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('should work when cursor is on text attribute input', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let file: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const files = {
|
|
|
|
'string-model.ts': dirFileContents,
|
|
|
|
'app.ts': `
|
2020-11-19 16:31:34 -05:00
|
|
|
import {Component} from '@angular/core';
|
|
|
|
|
2021-02-08 18:23:41 -05:00
|
|
|
@Component({template: '<div string-model model="title"></div>'})
|
2020-11-19 16:31:34 -05:00
|
|
|
export class AppCmp {
|
|
|
|
title = 'title';
|
2021-02-08 18:23:41 -05:00
|
|
|
}`
|
|
|
|
};
|
|
|
|
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
|
|
|
file = project.openFile('app.ts');
|
|
|
|
file.moveCursorToText('mod¦el="title"');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should work for text attributes', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(file)!;
|
2021-05-03 14:08:24 -04:00
|
|
|
expect(refs.length).toEqual(2);
|
|
|
|
assertFileNames(refs, ['string-model.ts', 'app.ts']);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
assertTextSpans(refs, ['model']);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should find rename locations', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(renameLocations.length).toEqual(2);
|
|
|
|
assertFileNames(renameLocations, ['string-model.ts', 'app.ts']);
|
|
|
|
assertTextSpans(renameLocations, ['model']);
|
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
});
|
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('when cursor is on the class member input', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let file: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const files = {
|
|
|
|
'string-model.ts': `
|
2020-11-19 16:31:34 -05:00
|
|
|
import {Directive, Input} from '@angular/core';
|
|
|
|
|
|
|
|
@Directive({selector: '[string-model]'})
|
|
|
|
export class StringModel {
|
2021-02-08 18:23:41 -05:00
|
|
|
@Input() model!: string;
|
|
|
|
}`,
|
|
|
|
'app.ts': `
|
2020-11-19 16:31:34 -05:00
|
|
|
import {Component} from '@angular/core';
|
|
|
|
|
|
|
|
@Component({template: '<div string-model model="title"></div>'})
|
|
|
|
export class AppCmp {
|
|
|
|
title = 'title';
|
2021-02-08 18:23:41 -05:00
|
|
|
}`
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
};
|
2021-02-08 18:23:41 -05:00
|
|
|
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
|
|
|
file = project.openFile('string-model.ts');
|
|
|
|
file.moveCursorToText('@Input() mod¦el!');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should work from the TS input declaration', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(file)!;
|
2021-05-03 14:08:24 -04:00
|
|
|
expect(refs.length).toEqual(2);
|
|
|
|
assertFileNames(refs, ['app.ts', 'string-model.ts']);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
assertTextSpans(refs, ['model']);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should find rename locations', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(renameLocations.length).toEqual(2);
|
|
|
|
assertFileNames(renameLocations, ['app.ts', 'string-model.ts']);
|
|
|
|
assertTextSpans(renameLocations, ['model']);
|
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
});
|
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('when cursor is on input referenced somewhere in the class functions', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let file: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const files = {
|
|
|
|
'other-dir.ts': `
|
2020-11-19 16:31:34 -05:00
|
|
|
import {Directive, Input} from '@angular/core';
|
|
|
|
import {StringModel} from './string-model';
|
|
|
|
|
|
|
|
@Directive({selector: '[other-dir]'})
|
|
|
|
export class OtherDir {
|
|
|
|
@Input() stringModelRef!: StringModel;
|
|
|
|
|
|
|
|
doSomething() {
|
2021-02-08 18:23:41 -05:00
|
|
|
console.log(this.stringModelRef.model);
|
2020-11-19 16:31:34 -05:00
|
|
|
}
|
2021-02-08 18:23:41 -05:00
|
|
|
}`,
|
|
|
|
'string-model.ts': `
|
2020-11-19 16:31:34 -05:00
|
|
|
import {Directive, Input} from '@angular/core';
|
|
|
|
|
|
|
|
@Directive({selector: '[string-model]'})
|
|
|
|
export class StringModel {
|
|
|
|
@Input() model!: string;
|
|
|
|
}`,
|
2021-02-08 18:23:41 -05:00
|
|
|
'app.ts': `
|
2020-11-19 16:31:34 -05:00
|
|
|
import {Component} from '@angular/core';
|
|
|
|
|
|
|
|
@Component({template: '<div string-model other-dir model="title"></div>'})
|
|
|
|
export class AppCmp {
|
|
|
|
title = 'title';
|
2021-02-08 18:23:41 -05:00
|
|
|
}`
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
};
|
2021-02-08 18:23:41 -05:00
|
|
|
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
|
|
|
file = project.openFile('other-dir.ts');
|
|
|
|
file.moveCursorToText('this.stringModelRef.mod¦el');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should find references', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(file)!;
|
2021-05-03 14:08:24 -04:00
|
|
|
expect(refs.length).toEqual(3);
|
|
|
|
assertFileNames(refs, ['app.ts', 'string-model.ts', 'other-dir.ts']);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
assertTextSpans(refs, ['model']);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should find rename locations', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(renameLocations.length).toEqual(3);
|
|
|
|
assertFileNames(renameLocations, ['app.ts', 'string-model.ts', 'other-dir.ts']);
|
|
|
|
assertTextSpans(renameLocations, ['model']);
|
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
});
|
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('when cursor is on an aliased input', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let file: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const files = {
|
|
|
|
'string-model.ts': dirFileContents,
|
|
|
|
'app.ts': `
|
2020-11-19 16:31:34 -05:00
|
|
|
import {Component} from '@angular/core';
|
|
|
|
|
2021-02-08 18:23:41 -05:00
|
|
|
@Component({template: '<div string-model [alias]="title"></div>'})
|
2020-11-19 16:31:34 -05:00
|
|
|
export class AppCmp {
|
|
|
|
title = 'title';
|
2021-02-08 18:23:41 -05:00
|
|
|
}`
|
|
|
|
};
|
|
|
|
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
|
|
|
file = project.openFile('app.ts');
|
|
|
|
file.moveCursorToText('[al¦ias]');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should find references', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(file)!;
|
2021-05-03 14:08:24 -04:00
|
|
|
expect(refs.length).toEqual(2);
|
|
|
|
assertFileNames(refs, ['string-model.ts', 'app.ts']);
|
|
|
|
assertTextSpans(refs, ['aliasedModel', 'alias']);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should find rename locations', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(renameLocations).toBeUndefined();
|
|
|
|
// TODO(atscott): add support for renaming alias outputs
|
|
|
|
// expect(renameLocations.length).toEqual(2);
|
|
|
|
// assertFileNames(renameLocations, ['string-model.ts', 'app.ts']);
|
|
|
|
// assertTextSpans(renameLocations, ['alias']);
|
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('outputs', () => {
|
|
|
|
const dirFile = `
|
|
|
|
import {Directive, Output, EventEmitter} from '@angular/core';
|
|
|
|
|
|
|
|
@Directive({selector: '[string-model]'})
|
|
|
|
export class StringModel {
|
|
|
|
@Output() modelChange = new EventEmitter<string>();
|
|
|
|
@Output('alias') aliasedModelChange = new EventEmitter<string>();
|
|
|
|
}`;
|
|
|
|
|
|
|
|
function generateAppFile(template: string) {
|
|
|
|
return `
|
|
|
|
import {Component, NgModule} from '@angular/core';
|
|
|
|
import {StringModel} from './string-model';
|
|
|
|
|
|
|
|
@Component({template: '${template}'})
|
|
|
|
export class AppCmp {
|
|
|
|
setTitle(s: string) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
@NgModule({declarations: [AppCmp, StringModel]})
|
|
|
|
export class AppModule {}`;
|
|
|
|
}
|
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('when cursor is on output key in template', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let file: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const appFile =
|
|
|
|
generateAppFile(`<div string-model (modelChange)="setTitle($event)"></div>`);
|
|
|
|
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = env.addProject('test', {'app.ts': appFile, 'string-model.ts': dirFile});
|
|
|
|
file = project.openFile('app.ts');
|
|
|
|
file.moveCursorToText('(mod¦elChange)');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should find references', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(file)!;
|
2021-05-03 14:08:24 -04:00
|
|
|
expect(refs.length).toEqual(2);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
assertTextSpans(refs, ['modelChange']);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should find rename locations', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(renameLocations.length).toEqual(2);
|
|
|
|
assertTextSpans(renameLocations, ['modelChange']);
|
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
});
|
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('when cursor is on alias output key', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let file: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const appFile = generateAppFile(`<div string-model (alias)="setTitle($event)"></div>`);
|
|
|
|
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = env.addProject('test', {'app.ts': appFile, 'string-model.ts': dirFile});
|
|
|
|
file = project.openFile('app.ts');
|
|
|
|
file.moveCursorToText('(a¦lias)');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should find references', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(file)!;
|
2021-05-03 14:08:24 -04:00
|
|
|
expect(refs.length).toEqual(2);
|
|
|
|
assertTextSpans(refs, ['aliasedModelChange', 'alias']);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should find rename locations', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(renameLocations).toBeUndefined();
|
|
|
|
// TODO(atscott): add support for renaming alias outputs
|
|
|
|
// expect(renameLocations.length).toEqual(2);
|
|
|
|
// assertTextSpans(renameLocations, ['alias']);
|
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2020-12-17 17:43:53 -05:00
|
|
|
it('should get references to both input and output for two-way binding', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const files = {
|
|
|
|
'dir.ts': `
|
2020-12-17 17:43:53 -05:00
|
|
|
import {Directive, Input, Output} from '@angular/core';
|
|
|
|
|
|
|
|
@Directive({selector: '[string-model]'})
|
|
|
|
export class StringModel {
|
|
|
|
@Input() model!: any;
|
|
|
|
@Output() modelChange!: any;
|
2021-02-08 18:23:41 -05:00
|
|
|
}`,
|
|
|
|
'app.ts': `
|
|
|
|
import {Component} from '@angular/core';
|
|
|
|
|
|
|
|
@Component({template: '<div string-model [(model)]="title"></div>'})
|
|
|
|
export class AppCmp {
|
|
|
|
title = 'title';
|
2020-12-17 17:43:53 -05:00
|
|
|
}`
|
2021-02-08 18:23:41 -05:00
|
|
|
|
2020-12-17 17:43:53 -05:00
|
|
|
};
|
|
|
|
|
2021-02-08 18:23:41 -05:00
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
|
|
|
const file = project.openFile('app.ts');
|
|
|
|
file.moveCursorToText('[(mod¦el)]');
|
2020-12-17 17:43:53 -05:00
|
|
|
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(file)!;
|
2021-01-21 18:28:42 -05:00
|
|
|
expect(refs.length).toEqual(3);
|
2021-05-03 14:08:24 -04:00
|
|
|
assertFileNames(refs, ['dir.ts', 'app.ts']);
|
|
|
|
assertTextSpans(refs, ['model', 'modelChange']);
|
2020-12-17 17:43:53 -05:00
|
|
|
});
|
|
|
|
|
2020-11-19 16:31:34 -05:00
|
|
|
describe('directives', () => {
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('when cursor is on the directive class', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let file: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const files = {
|
|
|
|
'dir.ts': `
|
2020-11-19 16:31:34 -05:00
|
|
|
import {Directive} from '@angular/core';
|
|
|
|
|
|
|
|
@Directive({selector: '[dir]'})
|
2021-02-08 18:23:41 -05:00
|
|
|
export class Dir {}`,
|
|
|
|
'app.ts': `
|
2020-11-19 16:31:34 -05:00
|
|
|
import {Component, NgModule} from '@angular/core';
|
|
|
|
import {Dir} from './dir';
|
|
|
|
|
|
|
|
@Component({template: '<div dir></div>'})
|
|
|
|
export class AppCmp {
|
|
|
|
}
|
|
|
|
|
|
|
|
@NgModule({declarations: [AppCmp, Dir]})
|
|
|
|
export class AppModule {}
|
2021-02-08 18:23:41 -05:00
|
|
|
`
|
|
|
|
};
|
|
|
|
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = env.addProject('test', files);
|
|
|
|
file = project.openFile('dir.ts');
|
|
|
|
file.moveCursorToText('export class Di¦r {}');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should find references', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
// 4 references are: class declaration, template usage, app import and use in declarations
|
|
|
|
// list.
|
2021-05-03 14:08:24 -04:00
|
|
|
expect(refs.length).toBe(4);
|
|
|
|
assertTextSpans(refs, ['<div dir>', 'Dir']);
|
|
|
|
assertFileNames(refs, ['app.ts', 'dir.ts']);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should find rename locations', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(renameLocations).toBeUndefined();
|
|
|
|
// TODO(atscott): We should handle this case, but exclude the template results
|
|
|
|
// expect(renameLocations.length).toBe(3);
|
|
|
|
// assertTextSpans(renameLocations, ['Dir']);
|
|
|
|
// assertFileNames(renameLocations, ['app.ts', 'dir.ts']);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('when cursor is on an attribute', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let file: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
beforeEach(() => {
|
|
|
|
const dirFile = `
|
2020-12-09 13:09:55 -05:00
|
|
|
import {Directive} from '@angular/core';
|
|
|
|
|
|
|
|
@Directive({selector: '[dir]'})
|
|
|
|
export class Dir {}`;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
const dirFile2 = `
|
2020-12-09 13:09:55 -05:00
|
|
|
import {Directive} from '@angular/core';
|
|
|
|
|
|
|
|
@Directive({selector: '[dir]'})
|
|
|
|
export class Dir2 {}`;
|
2021-02-08 18:23:41 -05:00
|
|
|
const appFile = `
|
2020-12-09 13:09:55 -05:00
|
|
|
import {Component, NgModule} from '@angular/core';
|
|
|
|
import {Dir} from './dir';
|
|
|
|
import {Dir2} from './dir2';
|
|
|
|
|
2021-02-08 18:23:41 -05:00
|
|
|
@Component({template: '<div dir></div>'})
|
2020-12-09 13:09:55 -05:00
|
|
|
export class AppCmp {
|
|
|
|
}
|
|
|
|
|
|
|
|
@NgModule({declarations: [AppCmp, Dir, Dir2]})
|
|
|
|
export class AppModule {}
|
2021-02-08 18:23:41 -05:00
|
|
|
`;
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project =
|
|
|
|
env.addProject('test', {'app.ts': appFile, 'dir.ts': dirFile, 'dir2.ts': dirFile2});
|
|
|
|
file = project.openFile('app.ts');
|
|
|
|
file.moveCursorToText('<div di¦r></div>');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('gets references to all matching directives', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(file)!;
|
2021-01-21 18:28:42 -05:00
|
|
|
expect(refs.length).toBe(7);
|
2021-05-03 14:08:24 -04:00
|
|
|
assertTextSpans(refs, ['<div dir>', 'Dir', 'Dir2']);
|
|
|
|
assertFileNames(refs, ['app.ts', 'dir.ts', 'dir2.ts']);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('finds rename locations for all matching directives', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(renameLocations).toBeUndefined();
|
|
|
|
// TODO(atscott): We could consider supporting rename for directive selectors in the future
|
|
|
|
// expect(renameLocations.length).toBe(3);
|
|
|
|
// assertTextSpans(renameLocations, ['dir']);
|
|
|
|
// assertFileNames(renameLocations, ['app.ts', 'dir.ts', 'dir2.ts']);
|
|
|
|
});
|
2020-12-09 13:09:55 -05:00
|
|
|
});
|
2020-12-10 14:13:11 -05:00
|
|
|
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('when cursor is on generic directive selector in template', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let file: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const files = {
|
|
|
|
'app.ts': `
|
2020-12-10 14:13:11 -05:00
|
|
|
import {Component, NgModule} from '@angular/core';
|
|
|
|
|
2021-02-08 18:23:41 -05:00
|
|
|
@Component({template: '<div *ngFor="let item of items"></div>'})
|
2020-12-10 14:13:11 -05:00
|
|
|
export class AppCmp {
|
|
|
|
items = [];
|
|
|
|
}
|
2021-02-08 18:23:41 -05:00
|
|
|
`
|
|
|
|
};
|
|
|
|
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
|
|
|
file = project.openFile('app.ts');
|
|
|
|
file.moveCursorToText('*ngF¦or');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should be able to request references', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(file)!;
|
2021-05-03 14:08:24 -04:00
|
|
|
expect(refs.length).toBe(6);
|
|
|
|
assertTextSpans(refs, ['<div *ngFor="let item of items"></div>', 'NgForOf']);
|
|
|
|
assertFileNames(refs, ['index.d.ts', 'app.ts']);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should not support rename if directive is in a dts file', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(file);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(renameLocations).toBeUndefined();
|
|
|
|
});
|
2020-12-10 14:13:11 -05:00
|
|
|
});
|
2020-12-09 13:09:55 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
describe('components', () => {
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
describe('when cursor is on component class', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let file: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
beforeEach(() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const myComp = `
|
2020-12-09 13:09:55 -05:00
|
|
|
import {Component} from '@angular/core';
|
|
|
|
|
|
|
|
@Component({selector: 'my-comp', template: ''})
|
2021-02-08 18:23:41 -05:00
|
|
|
export class MyComp {}`;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
const appFile = `
|
2020-12-09 13:09:55 -05:00
|
|
|
import {Component, NgModule} from '@angular/core';
|
|
|
|
import {MyComp} from './comp';
|
|
|
|
|
|
|
|
@Component({template: '<my-comp></my-comp>'})
|
|
|
|
export class AppCmp {
|
|
|
|
}
|
|
|
|
|
|
|
|
@NgModule({declarations: [AppCmp, MyComp]})
|
|
|
|
export class AppModule {}
|
|
|
|
`;
|
2021-02-08 18:23:41 -05:00
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = env.addProject('test', {'comp.ts': myComp, 'app.ts': appFile});
|
|
|
|
file = project.openFile('comp.ts');
|
|
|
|
file.moveCursorToText('MyCo¦mp');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('finds references', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
// 4 references are: class declaration, template usage, app import and use in declarations
|
|
|
|
// list.
|
2021-05-03 14:08:24 -04:00
|
|
|
expect(refs.length).toBe(4);
|
|
|
|
assertTextSpans(refs, ['<my-comp>', 'MyComp']);
|
|
|
|
assertFileNames(refs, ['app.ts', 'comp.ts']);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('gets rename locations', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(renameLocations).toBeUndefined();
|
|
|
|
// TODO(atscott): If we register as an exclusive provider for TS, we may need to return
|
|
|
|
// results here and should exclude the template results.
|
|
|
|
// expect(renameLocations.length).toBe(3);
|
|
|
|
// assertTextSpans(renameLocations, ['MyComp']);
|
|
|
|
// assertFileNames(renameLocations, ['app.ts', 'comp.ts']);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('when cursor is on the element tag', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
let file: OpenBuffer;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
beforeEach(() => {
|
|
|
|
const compFile = `
|
2020-12-09 13:09:55 -05:00
|
|
|
import {Component} from '@angular/core';
|
|
|
|
|
|
|
|
@Component({selector: 'my-comp', template: ''})
|
|
|
|
export class MyComp {}`;
|
2021-02-08 18:23:41 -05:00
|
|
|
const app = `
|
2020-12-09 13:09:55 -05:00
|
|
|
import {Component, NgModule} from '@angular/core';
|
|
|
|
import {MyComp} from './comp';
|
|
|
|
|
2021-02-08 18:23:41 -05:00
|
|
|
@Component({template: '<my-comp></my-comp>'})
|
2020-12-09 13:09:55 -05:00
|
|
|
export class AppCmp {
|
|
|
|
}
|
|
|
|
|
|
|
|
@NgModule({declarations: [AppCmp, MyComp]})
|
|
|
|
export class AppModule {}
|
2021-02-08 18:23:41 -05:00
|
|
|
`;
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = env.addProject('test', {'app.ts': app, 'comp.ts': compFile});
|
|
|
|
file = project.openFile('app.ts');
|
|
|
|
file.moveCursorToText('<my-c¦omp></my-comp>');
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('gets references', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const refs = getReferencesAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
// 4 references are: class declaration, template usage, app import and use in declarations
|
|
|
|
// list.
|
2021-05-03 14:08:24 -04:00
|
|
|
expect(refs.length).toBe(4);
|
|
|
|
assertTextSpans(refs, ['<my-comp>', 'MyComp']);
|
|
|
|
assertFileNames(refs, ['app.ts', 'comp.ts']);
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('finds rename locations', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const renameLocations = getRenameLocationsAtPosition(file)!;
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
expect(renameLocations).toBeUndefined();
|
|
|
|
// TODO(atscott): We may consider supporting rename of component selector in the future
|
|
|
|
// expect(renameLocations.length).toBe(2);
|
|
|
|
// assertTextSpans(renameLocations, ['my-comp']);
|
|
|
|
// assertFileNames(renameLocations, ['app.ts', 'comp.ts']);
|
|
|
|
});
|
2020-12-09 13:09:55 -05:00
|
|
|
});
|
2020-11-19 16:31:34 -05:00
|
|
|
});
|
|
|
|
|
2020-12-01 17:55:57 -05:00
|
|
|
describe('get rename info', () => {
|
|
|
|
it('indicates inability to rename when cursor is outside template and in a string literal',
|
|
|
|
() => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const comp = `
|
2020-12-01 17:55:57 -05:00
|
|
|
import {Component} from '@angular/core';
|
|
|
|
|
|
|
|
@Component({selector: 'my-comp', template: ''})
|
|
|
|
export class MyComp {
|
2021-02-08 18:23:41 -05:00
|
|
|
myProp = 'cannot rename me';
|
|
|
|
}`;
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', {'my-comp.ts': comp});
|
2020-12-01 17:55:57 -05:00
|
|
|
env.expectNoSourceDiagnostics();
|
2021-02-08 18:23:41 -05:00
|
|
|
|
|
|
|
const file = project.openFile('my-comp.ts');
|
|
|
|
file.moveCursorToText('cannot rena¦me me');
|
|
|
|
const result = file.getRenameInfo();
|
2020-12-01 17:55:57 -05:00
|
|
|
expect(result.canRename).toEqual(false);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('gets rename info when cursor is outside template', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const comp = `
|
2020-12-01 17:55:57 -05:00
|
|
|
import {Component, Input} from '@angular/core';
|
|
|
|
|
|
|
|
@Component({name: 'my-comp', template: ''})
|
|
|
|
export class MyComp {
|
2021-02-08 18:23:41 -05:00
|
|
|
@Input() myProp!: string;
|
|
|
|
}`;
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', {'my-comp.ts': comp});
|
2020-12-01 17:55:57 -05:00
|
|
|
env.expectNoSourceDiagnostics();
|
2021-02-08 18:23:41 -05:00
|
|
|
|
|
|
|
const file = project.openFile('my-comp.ts');
|
|
|
|
file.moveCursorToText('m¦yProp!');
|
|
|
|
const result = file.getRenameInfo() as ts.RenameInfoSuccess;
|
2020-12-01 17:55:57 -05:00
|
|
|
expect(result.canRename).toEqual(true);
|
|
|
|
expect(result.displayName).toEqual('myProp');
|
|
|
|
expect(result.kind).toEqual('property');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('gets rename info on keyed read', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const text = `
|
2020-12-01 17:55:57 -05:00
|
|
|
import {Component} from '@angular/core';
|
|
|
|
|
2021-02-08 18:23:41 -05:00
|
|
|
@Component({name: 'my-comp', template: '{{ myObj["myProp"] }}'})
|
2020-12-01 17:55:57 -05:00
|
|
|
export class MyComp {
|
|
|
|
readonly myObj = {'myProp': 'hello world'};
|
2021-02-08 18:23:41 -05:00
|
|
|
}`;
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', {'my-comp.ts': text});
|
2020-12-01 17:55:57 -05:00
|
|
|
env.expectNoSourceDiagnostics();
|
2021-02-08 18:23:41 -05:00
|
|
|
const file = project.openFile('my-comp.ts');
|
|
|
|
file.moveCursorToText('myObj["my¦Prop"]');
|
|
|
|
|
|
|
|
const result = file.getRenameInfo() as ts.RenameInfoSuccess;
|
2020-12-01 17:55:57 -05:00
|
|
|
expect(result.canRename).toEqual(true);
|
|
|
|
expect(result.displayName).toEqual('myProp');
|
|
|
|
expect(result.kind).toEqual('property');
|
2021-01-19 11:40:00 -05:00
|
|
|
expect(text.substring(
|
|
|
|
result.triggerSpan.start, result.triggerSpan.start + result.triggerSpan.length))
|
|
|
|
.toBe('myProp');
|
|
|
|
// re-queries also work
|
2021-02-08 18:23:41 -05:00
|
|
|
const {triggerSpan, displayName} = file.getRenameInfo() as ts.RenameInfoSuccess;
|
2021-01-19 11:40:00 -05:00
|
|
|
expect(displayName).toEqual('myProp');
|
|
|
|
expect(text.substring(triggerSpan.start, triggerSpan.start + triggerSpan.length))
|
|
|
|
.toBe('myProp');
|
2020-12-01 17:55:57 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('gets rename info when cursor is on a directive input in a template', () => {
|
2021-02-08 18:23:41 -05:00
|
|
|
const files = {
|
|
|
|
'dir.ts': `
|
2020-12-01 17:55:57 -05:00
|
|
|
import {Directive, Input} from '@angular/core';
|
|
|
|
@Directive({selector: '[dir]'})
|
|
|
|
export class MyDir {
|
|
|
|
@Input() dir!: any;
|
2021-02-08 18:23:41 -05:00
|
|
|
}`,
|
|
|
|
'my-comp.ts': `
|
2020-12-01 17:55:57 -05:00
|
|
|
import {Component, Input} from '@angular/core';
|
|
|
|
|
2021-02-08 18:23:41 -05:00
|
|
|
@Component({name: 'my-comp', template: '<div dir="something"></div>'})
|
2020-12-01 17:55:57 -05:00
|
|
|
export class MyComp {
|
|
|
|
@Input() myProp!: string;
|
2021-02-08 18:23:41 -05:00
|
|
|
}`
|
|
|
|
};
|
|
|
|
|
|
|
|
env = LanguageServiceTestEnv.setup();
|
|
|
|
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
|
2020-12-01 17:55:57 -05:00
|
|
|
env.expectNoSourceDiagnostics();
|
2021-02-08 18:23:41 -05:00
|
|
|
|
|
|
|
const file = project.openFile('my-comp.ts');
|
|
|
|
file.moveCursorToText('di¦r="something"');
|
|
|
|
const result = file.getRenameInfo() as ts.RenameInfoSuccess;
|
2020-12-01 17:55:57 -05:00
|
|
|
expect(result.canRename).toEqual(true);
|
|
|
|
expect(result.displayName).toEqual('dir');
|
|
|
|
expect(result.kind).toEqual('property');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2021-02-08 18:23:41 -05:00
|
|
|
function getReferencesAtPosition(file: OpenBuffer) {
|
2020-11-19 16:31:34 -05:00
|
|
|
env.expectNoSourceDiagnostics();
|
2021-02-08 18:23:41 -05:00
|
|
|
const result = file.getReferencesAtPosition();
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
return result?.map((item) => humanizeDocumentSpanLike(item, env));
|
2020-11-19 16:31:34 -05:00
|
|
|
}
|
|
|
|
|
2021-02-08 18:23:41 -05:00
|
|
|
function getRenameLocationsAtPosition(file: OpenBuffer) {
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
env.expectNoSourceDiagnostics();
|
2021-02-08 18:23:41 -05:00
|
|
|
const result = file.fineRenameLocations();
|
feat(language-service): initial implementation for `findRenameLocations` (#40140)
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close #40140
2020-11-30 14:16:48 -05:00
|
|
|
return result?.map((item) => humanizeDocumentSpanLike(item, env));
|
2020-11-19 16:31:34 -05:00
|
|
|
}
|
|
|
|
});
|