refactor(compiler): make OutputAst contain the moduleName, not the filePath (#16832).

The goal of this change is to simplify the emitters,
as we will soon create a new one to emit TypeScript nodes directly.
This commit is contained in:
Tobias Bosch
2017-05-16 16:30:37 -07:00
committed by Chuck Jazdzewski
parent 3b28c75d1f
commit 6123b9c0c6
28 changed files with 589 additions and 774 deletions

View File

@ -8,6 +8,8 @@
import {AotSummaryResolver, AotSummaryResolverHost, CompileSummaryKind, CompileTypeSummary, ResolvedStaticSymbol, StaticSymbol, StaticSymbolCache, StaticSymbolResolver} from '@angular/compiler';
import {deserializeSummaries, serializeSummaries} from '@angular/compiler/src/aot/summary_serializer';
import * as o from '@angular/compiler/src/output/output_ast';
import {OutputContext} from '@angular/compiler/src/util';
import * as path from 'path';
import {MockStaticSymbolResolverHost, MockSummaryResolver} from './static_symbol_resolver_spec';
@ -32,7 +34,9 @@ export function main() {
const mockSummaryResolver = new MockSummaryResolver([]);
const symbolResolver = new StaticSymbolResolver(
new MockStaticSymbolResolverHost({}), symbolCache, mockSummaryResolver);
return serializeSummaries(mockSummaryResolver, symbolResolver, symbols, []).json;
return serializeSummaries(
createMockOutputContext(), mockSummaryResolver, symbolResolver, symbols, [])
.json;
}
it('should load serialized summary files', () => {
@ -108,4 +112,8 @@ export class MockAotSummaryResolverHost implements AotSummaryResolverHost {
isSourceFile(filePath: string) { return !filePath.endsWith('.d.ts'); }
loadSummary(filePath: string): string { return this.summaries[filePath]; }
}
export function createMockOutputContext(): OutputContext {
return {statements: [], genFilePath: 'someGenFilePath', importExpr: () => o.NULL_EXPR};
}

View File

@ -11,7 +11,7 @@ import {deserializeSummaries, serializeSummaries} from '@angular/compiler/src/ao
import {summaryFileName} from '@angular/compiler/src/aot/util';
import {MockStaticSymbolResolverHost} from './static_symbol_resolver_spec';
import {MockAotSummaryResolverHost} from './summary_resolver_spec';
import {MockAotSummaryResolverHost, createMockOutputContext} from './summary_resolver_spec';
export function main() {
@ -43,7 +43,7 @@ export function main() {
it('should serialize various data correctly', () => {
init();
const serializedData = serializeSummaries(
summaryResolver, symbolResolver,
createMockOutputContext(), summaryResolver, symbolResolver,
[
{
symbol: symbolCache.get('/tmp/some_values.ts', 'Values'),
@ -105,34 +105,35 @@ export function main() {
it('should automatically add exported directives / pipes of NgModules that are not source files',
() => {
init();
const externalSerialized = serializeSummaries(summaryResolver, symbolResolver, [], [
{
summary: {
summaryKind: CompileSummaryKind.Pipe,
type: {
reference: symbolCache.get('/tmp/external.ts', 'SomeExternalPipe'),
}
} as any,
metadata: null as any
},
{
summary: {
summaryKind: CompileSummaryKind.Directive,
type: {
reference: symbolCache.get('/tmp/external.ts', 'SomeExternalDir'),
const externalSerialized =
serializeSummaries(createMockOutputContext(), summaryResolver, symbolResolver, [], [
{
summary: {
summaryKind: CompileSummaryKind.Pipe,
type: {
reference: symbolCache.get('/tmp/external.ts', 'SomeExternalPipe'),
}
} as any,
metadata: null as any
},
providers: [],
viewProviders: [],
} as any,
metadata: null as any
}
]);
{
summary: {
summaryKind: CompileSummaryKind.Directive,
type: {
reference: symbolCache.get('/tmp/external.ts', 'SomeExternalDir'),
},
providers: [],
viewProviders: [],
} as any,
metadata: null as any
}
]);
init({
'/tmp/external.ngsummary.json': externalSerialized.json,
});
const serialized = serializeSummaries(
summaryResolver, symbolResolver, [], [{
createMockOutputContext(), summaryResolver, symbolResolver, [], [{
summary: <any>{
summaryKind: CompileSummaryKind.NgModule,
type: {reference: symbolCache.get('/tmp/some_module.ts', 'SomeModule')},
@ -162,7 +163,7 @@ export function main() {
() => {
init();
const externalSerialized = serializeSummaries(
summaryResolver, symbolResolver,
createMockOutputContext(), summaryResolver, symbolResolver,
[
{
symbol: symbolCache.get('/tmp/external.ts', 'PROVIDERS'),
@ -194,7 +195,7 @@ export function main() {
{__symbolic: 'module', version: 3, metadata: {'external': 'b'}}
});
const serialized = serializeSummaries(
summaryResolver, symbolResolver, [{
createMockOutputContext(), summaryResolver, symbolResolver, [{
symbol: symbolCache.get('/tmp/test.ts', 'main'),
metadata: {
local: symbolCache.get('/tmp/local.ts', 'local'),
@ -229,7 +230,7 @@ export function main() {
it('should create "importAs" names for non source symbols', () => {
init();
const serialized = serializeSummaries(
summaryResolver, symbolResolver, [{
createMockOutputContext(), summaryResolver, symbolResolver, [{
symbol: symbolCache.get('/tmp/test.ts', 'main'),
metadata: [
symbolCache.get('/tmp/external.d.ts', 'lib'),

View File

@ -18,7 +18,7 @@ export function main() {
const fileB = new ParseSourceFile('b0b1b2b3b4b5b6b7b8b9', 'b.js');
let ctx: EmitterVisitorContext;
beforeEach(() => { ctx = EmitterVisitorContext.createRoot([]); });
beforeEach(() => { ctx = EmitterVisitorContext.createRoot(); });
it('should add source files to the source map', () => {
ctx.print(createSourceSpan(fileA, 0), 'o0');

View File

@ -10,7 +10,6 @@ import {StaticSymbol} from '@angular/compiler/src/aot/static_symbol';
import {CompileIdentifierMetadata} from '@angular/compiler/src/compile_metadata';
import {JavaScriptEmitter} from '@angular/compiler/src/output/js_emitter';
import * as o from '@angular/compiler/src/output/output_ast';
import {ImportResolver} from '@angular/compiler/src/output/path_util';
import {SourceMap} from '@angular/compiler/src/output/source_map';
import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '@angular/compiler/src/parse_util';
@ -19,31 +18,16 @@ import {extractSourceMap, originalPositionFor} from './source_map_util';
const someGenFilePath = 'somePackage/someGenFile';
const someSourceFilePath = 'somePackage/someSourceFile';
class SimpleJsImportGenerator implements ImportResolver {
fileNameToModuleName(importedUrlStr: string, moduleUrlStr: string): string {
return importedUrlStr;
}
getImportAs(symbol: StaticSymbol): StaticSymbol|null { return null; }
getTypeArity(symbol: StaticSymbol): number|null { return null; }
}
export function main() {
describe('JavaScriptEmitter', () => {
let importResolver: ImportResolver;
let emitter: JavaScriptEmitter;
let someVar: o.ReadVarExpr;
beforeEach(() => {
importResolver = new SimpleJsImportGenerator();
emitter = new JavaScriptEmitter(importResolver);
});
beforeEach(() => { emitter = new JavaScriptEmitter(); });
function emitSourceMap(
stmt: o.Statement | o.Statement[], exportedVars: string[] | null = null,
preamble?: string): SourceMap {
function emitSourceMap(stmt: o.Statement | o.Statement[], preamble?: string): SourceMap {
const stmts = Array.isArray(stmt) ? stmt : [stmt];
const source = emitter.emitStatements(
someSourceFilePath, someGenFilePath, stmts, exportedVars || [], preamble);
const source = emitter.emitStatements(someSourceFilePath, someGenFilePath, stmts, preamble);
return extractSourceMap(source) !;
}
@ -54,7 +38,7 @@ export function main() {
const endLocation = new ParseLocation(source, 7, 0, 6);
const sourceSpan = new ParseSourceSpan(startLocation, endLocation);
const someVar = o.variable('someVar', null, sourceSpan);
const sm = emitSourceMap(someVar.toStmt(), [], '/* MyPreamble \n */');
const sm = emitSourceMap(someVar.toStmt(), '/* MyPreamble \n */');
expect(sm.sources).toEqual([someSourceFilePath, 'in.js']);
expect(sm.sourcesContent).toEqual([' ', ';;;var']);

View File

@ -7,10 +7,8 @@
*/
import {StaticSymbol} from '@angular/compiler/src/aot/static_symbol';
import {CompileIdentifierMetadata} from '@angular/compiler/src/compile_metadata';
import {JavaScriptEmitter} from '@angular/compiler/src/output/js_emitter';
import * as o from '@angular/compiler/src/output/output_ast';
import {ImportResolver} from '@angular/compiler/src/output/path_util';
import {stripSourceMapAndNewLine} from './abstract_emitter_spec';
@ -18,20 +16,9 @@ const someGenFilePath = 'somePackage/someGenFile';
const someSourceFilePath = 'somePackage/someSourceFile';
const anotherModuleUrl = 'somePackage/someOtherPath';
const sameModuleIdentifier: CompileIdentifierMetadata = {
reference: new StaticSymbol(someGenFilePath, 'someLocalId', [])
};
const externalModuleIdentifier: CompileIdentifierMetadata = {
reference: new StaticSymbol(anotherModuleUrl, 'someExternalId', [])
};
const sameModuleIdentifier = new o.ExternalReference(null, 'someLocalId', null);
class SimpleJsImportGenerator implements ImportResolver {
fileNameToModuleName(importedUrlStr: string, moduleUrlStr: string): string {
return importedUrlStr;
}
getImportAs(symbol: StaticSymbol): StaticSymbol|null { return null; }
getTypeArity(symbol: StaticSymbol): number|null { return null; }
}
const externalModuleIdentifier = new o.ExternalReference(anotherModuleUrl, 'someExternalId', null);
export function main() {
// Note supported features of our OutputAstin JavaScript / ES5:
@ -39,29 +26,26 @@ export function main() {
// - declaring fields
describe('JavaScriptEmitter', () => {
let importResolver: ImportResolver;
let emitter: JavaScriptEmitter;
let someVar: o.ReadVarExpr;
beforeEach(() => {
importResolver = new SimpleJsImportGenerator();
emitter = new JavaScriptEmitter(importResolver);
emitter = new JavaScriptEmitter();
someVar = o.variable('someVar');
});
function emitStmt(
stmt: o.Statement, exportedVars: string[] | null = null, preamble?: string): string {
const source = emitter.emitStatements(
someSourceFilePath, someGenFilePath, [stmt], exportedVars || [], preamble);
function emitStmt(stmt: o.Statement, preamble?: string): string {
const source = emitter.emitStatements(someSourceFilePath, someGenFilePath, [stmt], preamble);
return stripSourceMapAndNewLine(source);
}
it('should declare variables', () => {
expect(emitStmt(someVar.set(o.literal(1)).toDeclStmt())).toEqual(`var someVar = 1;`);
expect(emitStmt(someVar.set(o.literal(1)).toDeclStmt(), ['someVar'])).toEqual([
'var someVar = 1;',
`Object.defineProperty(exports, 'someVar', { get: function() { return someVar; }});`
].join('\n'));
expect(emitStmt(someVar.set(o.literal(1)).toDeclStmt(null, [o.StmtModifier.Exported])))
.toEqual([
'var someVar = 1;',
`Object.defineProperty(exports, 'someVar', { get: function() { return someVar; }});`
].join('\n'));
});
it('should read and write variables', () => {
@ -144,16 +128,6 @@ export function main() {
].join('\n'));
});
it('should support `importAs` for external identifiers', () => {
spyOn(importResolver, 'getImportAs')
.and.returnValue(new StaticSymbol('somePackage/importAsModule', 'importAsName', []));
expect(emitStmt(o.importExpr(externalModuleIdentifier).toStmt())).toEqual([
`var i0 = re` +
`quire('somePackage/importAsModule');`,
`i0.importAsName;`
].join('\n'));
});
it('should support operators', () => {
const lhs = o.variable('lhs');
const rhs = o.variable('rhs');
@ -193,10 +167,11 @@ export function main() {
it('should support function statements', () => {
expect(emitStmt(new o.DeclareFunctionStmt('someFn', [], [
]))).toEqual(['function someFn() {', '}'].join('\n'));
expect(emitStmt(new o.DeclareFunctionStmt('someFn', [], []), ['someFn'])).toEqual([
'function someFn() {', '}',
`Object.defineProperty(exports, 'someFn', { get: function() { return someFn; }});`
].join('\n'));
expect(emitStmt(new o.DeclareFunctionStmt('someFn', [], [], null, [o.StmtModifier.Exported])))
.toEqual([
'function someFn() {', '}',
`Object.defineProperty(exports, 'someFn', { get: function() { return someFn; }});`
].join('\n'));
expect(emitStmt(new o.DeclareFunctionStmt('someFn', [], [
new o.ReturnStatement(o.literal(1))
]))).toEqual(['function someFn() {', ' return 1;', '}'].join('\n'));
@ -240,7 +215,8 @@ export function main() {
it('should support declaring classes', () => {
expect(emitStmt(new o.ClassStmt('SomeClass', null !, [], [], null !, [
]))).toEqual(['function SomeClass() {', '}'].join('\n'));
expect(emitStmt(new o.ClassStmt('SomeClass', null !, [], [], null !, []), ['SomeClass']))
expect(emitStmt(new o.ClassStmt(
'SomeClass', null !, [], [], null !, [], [o.StmtModifier.Exported])))
.toEqual([
'function SomeClass() {', '}',
`Object.defineProperty(exports, 'SomeClass', { get: function() { return SomeClass; }});`
@ -319,7 +295,7 @@ export function main() {
});
it('should support a preamble', () => {
expect(emitStmt(o.variable('a').toStmt(), [], '/* SomePreamble */')).toBe([
expect(emitStmt(o.variable('a').toStmt(), '/* SomePreamble */')).toBe([
'/* SomePreamble */', 'a;'
].join('\n'));
});

View File

@ -9,7 +9,6 @@
import {ParseLocation, ParseSourceFile} from '@angular/compiler';
import {StaticSymbol} from '@angular/compiler/src/aot/static_symbol';
import * as o from '@angular/compiler/src/output/output_ast';
import {ImportResolver} from '@angular/compiler/src/output/path_util';
import {SourceMap} from '@angular/compiler/src/output/source_map';
import {TypeScriptEmitter} from '@angular/compiler/src/output/ts_emitter';
import {ParseSourceSpan} from '@angular/compiler/src/parse_util';
@ -19,36 +18,23 @@ import {extractSourceMap, originalPositionFor} from './source_map_util';
const someGenFilePath = 'somePackage/someGenFile';
const someSourceFilePath = 'somePackage/someSourceFile';
class SimpleJsImportGenerator implements ImportResolver {
fileNameToModuleName(importedUrlStr: string, moduleUrlStr: string): string {
return importedUrlStr;
}
getImportAs(symbol: StaticSymbol): StaticSymbol|null { return null; }
getTypeArity(symbol: StaticSymbol): number|null { return null; }
}
export function main() {
// Not supported features of our OutputAst in TS:
// - real `const` like in Dart
// - final fields
describe('TypeScriptEmitter', () => {
let importResolver: ImportResolver;
let emitter: TypeScriptEmitter;
let someVar: o.ReadVarExpr;
beforeEach(() => {
importResolver = new SimpleJsImportGenerator();
emitter = new TypeScriptEmitter(importResolver);
emitter = new TypeScriptEmitter();
someVar = o.variable('someVar');
});
function emitSourceMap(
stmt: o.Statement | o.Statement[], exportedVars: string[] | null = null,
preamble?: string): SourceMap {
function emitSourceMap(stmt: o.Statement | o.Statement[], preamble?: string): SourceMap {
const stmts = Array.isArray(stmt) ? stmt : [stmt];
const source = emitter.emitStatements(
someSourceFilePath, someGenFilePath, stmts, exportedVars || [], preamble);
const source = emitter.emitStatements(someSourceFilePath, someGenFilePath, stmts, preamble);
return extractSourceMap(source) !;
}
@ -59,7 +45,7 @@ export function main() {
const endLocation = new ParseLocation(source, 7, 0, 6);
const sourceSpan = new ParseSourceSpan(startLocation, endLocation);
const someVar = o.variable('someVar', null, sourceSpan);
const sm = emitSourceMap(someVar.toStmt(), [], '/* MyPreamble \n */');
const sm = emitSourceMap(someVar.toStmt(), '/* MyPreamble \n */');
expect(sm.sources).toEqual([someSourceFilePath, 'in.js']);
expect(sm.sourcesContent).toEqual([' ', ';;;var']);

View File

@ -7,9 +7,7 @@
*/
import {StaticSymbol} from '@angular/compiler/src/aot/static_symbol';
import {CompileIdentifierMetadata} from '@angular/compiler/src/compile_metadata';
import * as o from '@angular/compiler/src/output/output_ast';
import {ImportResolver} from '@angular/compiler/src/output/path_util';
import {TypeScriptEmitter} from '@angular/compiler/src/output/ts_emitter';
import {stripSourceMapAndNewLine} from './abstract_emitter_spec';
@ -18,21 +16,9 @@ const someGenFilePath = 'somePackage/someGenFile';
const someSourceFilePath = 'somePackage/someSourceFile';
const anotherModuleUrl = 'somePackage/someOtherPath';
const sameModuleIdentifier: CompileIdentifierMetadata = {
reference: new StaticSymbol(someGenFilePath, 'someLocalId', [])
};
const sameModuleIdentifier = new o.ExternalReference(null, 'someLocalId', null);
const externalModuleIdentifier: CompileIdentifierMetadata = {
reference: new StaticSymbol(anotherModuleUrl, 'someExternalId', [])
};
class SimpleJsImportGenerator implements ImportResolver {
fileNameToModuleName(importedUrlStr: string, moduleUrlStr: string): string {
return importedUrlStr;
}
getImportAs(symbol: StaticSymbol): StaticSymbol|null { return null; }
getTypeArity(symbol: StaticSymbol): number|null { return null; }
}
const externalModuleIdentifier = new o.ExternalReference(anotherModuleUrl, 'someExternalId', null);
export function main() {
// Not supported features of our OutputAst in TS:
@ -40,22 +26,17 @@ export function main() {
// - final fields
describe('TypeScriptEmitter', () => {
let importResolver: ImportResolver;
let emitter: TypeScriptEmitter;
let someVar: o.ReadVarExpr;
beforeEach(() => {
importResolver = new SimpleJsImportGenerator();
emitter = new TypeScriptEmitter(importResolver);
emitter = new TypeScriptEmitter();
someVar = o.variable('someVar', null, null);
});
function emitStmt(
stmt: o.Statement | o.Statement[], exportedVars: string[] | null = null,
preamble?: string): string {
function emitStmt(stmt: o.Statement | o.Statement[], preamble?: string): string {
const stmts = Array.isArray(stmt) ? stmt : [stmt];
const source = emitter.emitStatements(
someSourceFilePath, someGenFilePath, stmts, exportedVars || [], preamble);
const source = emitter.emitStatements(someSourceFilePath, someGenFilePath, stmts, preamble);
return stripSourceMapAndNewLine(source);
}
@ -63,7 +44,7 @@ export function main() {
expect(emitStmt(someVar.set(o.literal(1)).toDeclStmt())).toEqual(`var someVar:any = 1;`);
expect(emitStmt(someVar.set(o.literal(1)).toDeclStmt(null, [o.StmtModifier.Final])))
.toEqual(`const someVar:any = 1;`);
expect(emitStmt(someVar.set(o.literal(1)).toDeclStmt(), ['someVar']))
expect(emitStmt(someVar.set(o.literal(1)).toDeclStmt(null, [o.StmtModifier.Exported])))
.toEqual(`export var someVar:any = 1;`);
expect(emitStmt(someVar.set(o.literal(1)).toDeclStmt(o.INT_TYPE)))
.toEqual(`var someVar:number = 1;`);
@ -74,8 +55,9 @@ export function main() {
describe('declare variables with ExternExpressions as values', () => {
it('should create no reexport if the identifier is in the same module', () => {
// identifier is in the same module -> no reexport
expect(emitStmt(someVar.set(o.importExpr(sameModuleIdentifier)).toDeclStmt(), ['someVar']))
.toEqual('export var someVar:any = someLocalId;');
expect(emitStmt(someVar.set(o.importExpr(sameModuleIdentifier)).toDeclStmt(null, [
o.StmtModifier.Exported
]))).toEqual('export var someVar:any = someLocalId;');
});
it('should create no reexport if the variable is not exported', () => {
@ -85,31 +67,17 @@ export function main() {
});
it('should create no reexport if the variable is typed', () => {
expect(emitStmt(
someVar.set(o.importExpr(externalModuleIdentifier)).toDeclStmt(o.DYNAMIC_TYPE),
['someVar']))
expect(emitStmt(someVar.set(o.importExpr(externalModuleIdentifier))
.toDeclStmt(o.DYNAMIC_TYPE, [o.StmtModifier.Exported])))
.toEqual([
`import * as i0 from 'somePackage/someOtherPath';`,
`export var someVar:any = i0.someExternalId;`
].join('\n'));
});
it('should create no reexport if the identifier has members', () => {
const externalModuleIdentifierWithMembers: CompileIdentifierMetadata = {
reference: new StaticSymbol(anotherModuleUrl, 'someExternalId', ['a'])
};
expect(emitStmt(
someVar.set(o.importExpr(externalModuleIdentifierWithMembers)).toDeclStmt(),
['someVar']))
.toEqual([
`import * as i0 from 'somePackage/someOtherPath';`,
`export var someVar:any = i0.someExternalId.a;`
].join('\n'));
});
it('should create a reexport', () => {
expect(
emitStmt(someVar.set(o.importExpr(externalModuleIdentifier)).toDeclStmt(), ['someVar']))
expect(emitStmt(someVar.set(o.importExpr(externalModuleIdentifier))
.toDeclStmt(null, [o.StmtModifier.Exported])))
.toEqual([
`export {someExternalId as someVar} from 'somePackage/someOtherPath';`, ``
].join('\n'));
@ -117,30 +85,19 @@ export function main() {
it('should create multiple reexports from the same file', () => {
const someVar2 = o.variable('someVar2');
const externalModuleIdentifier2: CompileIdentifierMetadata = {
reference: new StaticSymbol(anotherModuleUrl, 'someExternalId2', [])
};
expect(emitStmt(
[
someVar.set(o.importExpr(externalModuleIdentifier)).toDeclStmt(),
someVar2.set(o.importExpr(externalModuleIdentifier2)).toDeclStmt()
],
['someVar', 'someVar2']))
const externalModuleIdentifier2 =
new o.ExternalReference(anotherModuleUrl, 'someExternalId2', null);
expect(emitStmt([
someVar.set(o.importExpr(externalModuleIdentifier))
.toDeclStmt(null, [o.StmtModifier.Exported]),
someVar2.set(o.importExpr(externalModuleIdentifier2))
.toDeclStmt(null, [o.StmtModifier.Exported])
]))
.toEqual([
`export {someExternalId as someVar,someExternalId2 as someVar2} from 'somePackage/someOtherPath';`,
``
].join('\n'));
});
it('should use `importAs` for reexports', () => {
spyOn(importResolver, 'getImportAs')
.and.returnValue(new StaticSymbol('somePackage/importAsModule', 'importAsName', []));
expect(
emitStmt(someVar.set(o.importExpr(externalModuleIdentifier)).toDeclStmt(), ['someVar']))
.toEqual([
`export {importAsName as someVar} from 'somePackage/importAsModule';`, ``
].join('\n'));
});
});
it('should read and write variables', () => {
@ -230,14 +187,6 @@ export function main() {
].join('\n'));
});
it('should support `importAs` for external identifiers', () => {
spyOn(importResolver, 'getImportAs')
.and.returnValue(new StaticSymbol('somePackage/importAsModule', 'importAsName', []));
expect(emitStmt(o.importExpr(externalModuleIdentifier).toStmt())).toEqual([
`import * as i0 from 'somePackage/importAsModule';`, `i0.importAsName;`
].join('\n'));
});
it('should support operators', () => {
const lhs = o.variable('lhs');
const rhs = o.variable('rhs');
@ -277,9 +226,8 @@ export function main() {
it('should support function statements', () => {
expect(emitStmt(new o.DeclareFunctionStmt('someFn', [], [
]))).toEqual(['function someFn():void {', '}'].join('\n'));
expect(emitStmt(new o.DeclareFunctionStmt('someFn', [], []), ['someFn'])).toEqual([
'export function someFn():void {', '}'
].join('\n'));
expect(emitStmt(new o.DeclareFunctionStmt('someFn', [], [], null, [o.StmtModifier.Exported])))
.toEqual(['export function someFn():void {', '}'].join('\n'));
expect(emitStmt(new o.DeclareFunctionStmt(
'someFn', [], [new o.ReturnStatement(o.literal(1))], o.INT_TYPE)))
.toEqual(['function someFn():number {', ' return 1;', '}'].join('\n'));
@ -324,8 +272,9 @@ export function main() {
it('should support declaring classes', () => {
expect(emitStmt(new o.ClassStmt('SomeClass', null !, [], [], null !, [
]))).toEqual(['class SomeClass {', '}'].join('\n'));
expect(emitStmt(new o.ClassStmt('SomeClass', null !, [], [], null !, []), ['SomeClass']))
.toEqual(['export class SomeClass {', '}'].join('\n'));
expect(emitStmt(new o.ClassStmt('SomeClass', null !, [], [], null !, [], [
o.StmtModifier.Exported
]))).toEqual(['export class SomeClass {', '}'].join('\n'));
expect(emitStmt(new o.ClassStmt('SomeClass', o.variable('SomeSuperClass'), [], [], null !, [
]))).toEqual(['class SomeClass extends SomeSuperClass {', '}'].join('\n'));
});
@ -439,16 +388,6 @@ export function main() {
].join('\n'));
});
it('should support `importAs` for external types', () => {
spyOn(importResolver, 'getImportAs')
.and.returnValue(new StaticSymbol('somePackage/importAsModule', 'importAsName', []));
const writeVarExpr = o.variable('a').set(o.NULL_EXPR);
expect(emitStmt(writeVarExpr.toDeclStmt(o.importType(externalModuleIdentifier)))).toEqual([
`import * as i0 from 'somePackage/importAsModule';`,
`var a:i0.importAsName = (null as any);`
].join('\n'));
});
it('should support expression types', () => {
expect(
emitStmt(o.variable('a').set(o.NULL_EXPR).toDeclStmt(o.expressionType(o.variable('b')))))
@ -479,7 +418,7 @@ export function main() {
});
it('should support a preamble', () => {
expect(emitStmt(o.variable('a').toStmt(), [], '/* SomePreamble */')).toBe([
expect(emitStmt(o.variable('a').toStmt(), '/* SomePreamble */')).toBe([
'/* SomePreamble */', 'a;'
].join('\n'));
});