Skip to content
Permalink
Browse files

fix(compiler-cli): create LiteralLikeNode for String and Number liter…

…al (#27536)

Typescript 3.2 introduced BigInt type, and consequently the
implementation for checkExpressionWorker() in checkers.ts is refactored.

For NumberLiteral and StringLiteral types, 'text' filed must be present
in the Node type, therefore they must be LiteralLikeNode instead of
Node.

PR Close #27536
  • Loading branch information...
kyliau authored and mhevery committed Dec 14, 2018
1 parent 17e702b commit 2c9b6c0c1f2dde14f2d079f04f4807c5e5b6d8d8
@@ -718,13 +718,20 @@ function getBuiltinTypeFromTs(kind: BuiltinType, context: TypeContext): ts.Type
checker.getTypeAtLocation(setParents(<ts.Node>{kind: ts.SyntaxKind.NullKeyword}, node));
break;
case BuiltinType.Number:
const numeric = <ts.Node>{kind: ts.SyntaxKind.NumericLiteral};
const numeric = <ts.LiteralLikeNode>{
kind: ts.SyntaxKind.NumericLiteral,
text: node.getText(),
};
setParents(<any>{kind: ts.SyntaxKind.ExpressionStatement, expression: numeric}, node);
type = checker.getTypeAtLocation(numeric);
break;
case BuiltinType.String:
type = checker.getTypeAtLocation(
setParents(<ts.Node>{kind: ts.SyntaxKind.NoSubstitutionTemplateLiteral}, node));
type = checker.getTypeAtLocation(setParents(
<ts.LiteralLikeNode>{
kind: ts.SyntaxKind.NoSubstitutionTemplateLiteral,
text: node.getText(),
},
node));
break;
case BuiltinType.Undefined:
type = checker.getTypeAtLocation(setParents(
@@ -12,7 +12,7 @@ import {EmittingCompilerHost, MockAotCompilerHost, MockCompilerHost, MockData, M
import {ReflectorHost} from '@angular/language-service/src/reflector_host';
import * as ts from 'typescript';

import {Symbol, SymbolQuery, SymbolTable} from '../../src/diagnostics/symbols';
import {BuiltinType, Symbol, SymbolQuery, SymbolTable} from '../../src/diagnostics/symbols';
import {getSymbolQuery, toSymbolTableFactory} from '../../src/diagnostics/typescript_symbols';
import {CompilerOptions} from '../../src/transformers/api';
import {Directory} from '../mocks';
@@ -55,6 +55,29 @@ describe('symbol query', () => {
const symbol = query.getTypeSymbol(unknownType);
expect(symbol).toBeUndefined();
});

it('should return correct built-in types', () => {
const tests: Array<[BuiltinType, boolean, ts.TypeFlags?]> = [
// builtinType, throws, want
[BuiltinType.Any, false, ts.TypeFlags.Any],
[BuiltinType.Boolean, false, ts.TypeFlags.BooleanLiteral],
[BuiltinType.Null, false, ts.TypeFlags.Null],
[BuiltinType.Number, false, ts.TypeFlags.NumberLiteral],
[BuiltinType.String, false, ts.TypeFlags.StringLiteral],
[BuiltinType.Undefined, false, ts.TypeFlags.Undefined],
[BuiltinType.Unbound, true],
[BuiltinType.Other, true],
];
for (const [builtinType, throws, want] of tests) {
if (throws) {
expect(() => query.getBuiltinType(builtinType)).toThrow();
} else {
const symbol = query.getBuiltinType(builtinType);
const got: ts.TypeFlags = (symbol as any).tsType.flags;
expect(got).toBe(want !);
}
}
});
});

describe('toSymbolTableFactory(tsVersion)', () => {
@@ -145,9 +145,7 @@ describe('ngc transformer command-line', () => {

const exitCode = main(['-p', basePath], errorSpy);
expect(errorSpy).toHaveBeenCalledWith(
`test.ts(1,9): error TS2305: Module '"` + path.join(basePath, 'empty-deps') +
`"' has no exported member 'MyClass'.` +
'\n');
`test.ts(1,9): error TS2305: Module '"./empty-deps"' has no exported member 'MyClass'.\n`);
expect(exitCode).toEqual(1);
});

@@ -874,7 +872,7 @@ describe('ngc transformer command-line', () => {
write('mymodule.ts', `
import {Component, NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';
export function foo(): string {
console.log('side-effect');
return 'test';
@@ -149,6 +149,15 @@ describe('diagnostics', () => {
});
});

it('should not report an error for sub-types of number', () => {
const code =
` @Component({template: \`<div *ngIf="something === 123"></div>\`}) export class MyComponent { something: 123 | 456; }`;
addCode(code, fileName => {
const diagnostics = ngService.getDiagnostics(fileName);
expectOnlyModuleDiagnostics(diagnostics);
});
});

it('should report a warning if an event results in a callable expression', () => {
const code =
` @Component({template: \`<div (click)="onClick"></div>\`}) export class MyComponent { onClick() { } }`;

0 comments on commit 2c9b6c0

Please sign in to comment.
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.