fix(language-service): Fix completions for input/output with alias (#28904)

This PR fixes a bug in autocompletion for @Input/@Output decorator with
an alias. The current implementation ignores the alias.

Credit for this work is attributed to @edgardmessias
The original work fixed the bug, but was lacking test.

PR Close #27959

PR Close #28904
This commit is contained in:
Keen Yee Liau 2019-01-30 10:34:36 -08:00 committed by Ben Lesh
parent 43181ea568
commit ad4a9bf03f
3 changed files with 32 additions and 4 deletions

View File

@ -173,8 +173,9 @@ function getAttributeInfosForElement(
matcher.match(elementSelector, selector => {
let directive = selectorMap.get(selector);
if (directive) {
attrs.push(...Object.keys(directive.inputs).map(name => ({name, input: true})));
attrs.push(...Object.keys(directive.outputs).map(name => ({name, output: true})));
const {inputs, outputs} = directive;
attrs.push(...Object.keys(inputs).map(name => ({name: inputs[name], input: true})));
attrs.push(...Object.keys(outputs).map(name => ({name: outputs[name], output: true})));
}
});

View File

@ -187,6 +187,27 @@ export class MyComponent {
contains('/app/my.component.ts', 'tree', 'children');
});
it('should work with input and output', () => {
addCode(
`
@Component({
selector: 'foo-component',
template: \`
<div string-model ~{stringMarker}="text"></div>
<div number-model ~{numberMarker}="value"></div>
\`,
})
export class FooComponent {
text: string;
value: number;
}
`,
(fileName) => {
contains(fileName, 'stringMarker', '[model]', '(model)');
contains(fileName, 'numberMarker', '[inputAlias]', '(outputAlias)');
});
});
function addCode(code: string, cb: (fileName: string, content?: string) => void) {
const fileName = '/app/app.component.ts';
const originalContent = mockHost.getFileContent(fileName);

View File

@ -44,7 +44,7 @@ import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { CaseIncompleteOpen, CaseMissingClosing, CaseUnknown, Pipes, TemplateReference, NoValueAttribute,
AttributeBinding, StringModel,PropertyBinding, EventBinding, TwoWayBinding, EmptyInterpolation,
AttributeBinding, StringModel, NumberModel, PropertyBinding, EventBinding, TwoWayBinding, EmptyInterpolation,
ForOfEmpty, ForLetIEqual, ForOfLetEmpty, ForUsingComponent, References, TestComponent} from './parsing-cases';
import { WrongFieldReference, WrongSubFieldReference, PrivateReference, ExpectNumericType, LowercasePipe } from './expression-cases';
import { UnknownPeople, UnknownEven, UnknownTrackBy } from './ng-for-cases';
@ -53,7 +53,7 @@ import { ShowIf } from './ng-if-cases';
@NgModule({
imports: [CommonModule, FormsModule],
declarations: [AppComponent, CaseIncompleteOpen, CaseMissingClosing, CaseUnknown, Pipes, TemplateReference, NoValueAttribute,
AttributeBinding, StringModel, PropertyBinding, EventBinding, TwoWayBinding, EmptyInterpolation, ForOfEmpty, ForOfLetEmpty,
AttributeBinding, StringModel, NumberModel, PropertyBinding, EventBinding, TwoWayBinding, EmptyInterpolation, ForOfEmpty, ForOfLetEmpty,
ForLetIEqual, ForUsingComponent, References, TestComponent, WrongFieldReference, WrongSubFieldReference, PrivateReference,
ExpectNumericType, UnknownPeople, UnknownEven, UnknownTrackBy, ShowIf, LowercasePipe]
})
@ -113,6 +113,12 @@ export class StringModel {
@Output() modelChanged: EventEmitter<string>;
}
@Directive({selector: '[number-model]'})
export class NumberModel {
@Input('inputAlias') model: number;
@Output('outputAlias') modelChanged: EventEmitter<number>;
}
interface Person {
name: string;
age: number