fix(tsc-wrapped): generate metadata for exports without module specifier
fixes #13327
This commit is contained in:
parent
ee2ac025ef
commit
40d8d9c3e3
|
@ -175,6 +175,7 @@ describe('CompilerHost', () => {
|
||||||
foo: {__symbolic: 'class'},
|
foo: {__symbolic: 'class'},
|
||||||
Bar: {__symbolic: 'class', members: {ngOnInit: [{__symbolic: 'method'}]}},
|
Bar: {__symbolic: 'class', members: {ngOnInit: [{__symbolic: 'method'}]}},
|
||||||
BarChild: {__symbolic: 'class', extends: {__symbolic: 'reference', name: 'Bar'}},
|
BarChild: {__symbolic: 'class', extends: {__symbolic: 'reference', name: 'Bar'}},
|
||||||
|
ReExport: {__symbolic: 'reference', module: './lib/utils2', name: 'ReExport'},
|
||||||
},
|
},
|
||||||
exports: [{from: './lib/utils2', export: ['Export']}],
|
exports: [{from: './lib/utils2', export: ['Export']}],
|
||||||
}
|
}
|
||||||
|
@ -212,7 +213,11 @@ const FILES: Entry = {
|
||||||
},
|
},
|
||||||
'metadata_versions': {
|
'metadata_versions': {
|
||||||
'v1.d.ts': `
|
'v1.d.ts': `
|
||||||
|
import {ReExport} from './lib/utils2';
|
||||||
|
export {ReExport};
|
||||||
|
|
||||||
export {Export} from './lib/utils2';
|
export {Export} from './lib/utils2';
|
||||||
|
|
||||||
export declare class Bar {
|
export declare class Bar {
|
||||||
ngOnInit() {}
|
ngOnInit() {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
|
|
||||||
import {Evaluator, errorSymbol, isPrimitive} from './evaluator';
|
import {Evaluator, errorSymbol, isPrimitive} from './evaluator';
|
||||||
import {ClassMetadata, ConstructorMetadata, FunctionMetadata, MemberMetadata, MetadataEntry, MetadataError, MetadataMap, MetadataObject, MetadataSymbolicBinaryExpression, MetadataSymbolicCallExpression, MetadataSymbolicExpression, MetadataSymbolicIfExpression, MetadataSymbolicIndexExpression, MetadataSymbolicPrefixExpression, MetadataSymbolicReferenceExpression, MetadataSymbolicSelectExpression, MetadataSymbolicSpreadExpression, MetadataValue, MethodMetadata, ModuleExportMetadata, ModuleMetadata, VERSION, isClassMetadata, isConstructorMetadata, isFunctionMetadata, isMetadataError, isMetadataGlobalReferenceExpression, isMetadataSymbolicExpression, isMetadataSymbolicReferenceExpression, isMetadataSymbolicSelectExpression, isMethodMetadata} from './schema';
|
import {ClassMetadata, ConstructorMetadata, FunctionMetadata, MemberMetadata, MetadataEntry, MetadataError, MetadataMap, MetadataSymbolicBinaryExpression, MetadataSymbolicCallExpression, MetadataSymbolicExpression, MetadataSymbolicIfExpression, MetadataSymbolicIndexExpression, MetadataSymbolicPrefixExpression, MetadataSymbolicReferenceExpression, MetadataSymbolicSelectExpression, MetadataSymbolicSpreadExpression, MetadataValue, MethodMetadata, ModuleExportMetadata, ModuleMetadata, VERSION, isClassMetadata, isConstructorMetadata, isFunctionMetadata, isMetadataError, isMetadataGlobalReferenceExpression, isMetadataSymbolicExpression, isMetadataSymbolicReferenceExpression, isMetadataSymbolicSelectExpression, isMethodMetadata} from './schema';
|
||||||
import {Symbols} from './symbols';
|
import {Symbols} from './symbols';
|
||||||
|
|
||||||
|
|
||||||
|
@ -234,6 +234,7 @@ export class MetadataCollector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ts.SyntaxKind.FunctionDeclaration:
|
case ts.SyntaxKind.FunctionDeclaration:
|
||||||
if (!(node.flags & ts.NodeFlags.Export)) {
|
if (!(node.flags & ts.NodeFlags.Export)) {
|
||||||
// Report references to this function as an error.
|
// Report references to this function as an error.
|
||||||
|
@ -249,22 +250,36 @@ export class MetadataCollector {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ts.forEachChild(sourceFile, node => {
|
ts.forEachChild(sourceFile, node => {
|
||||||
switch (node.kind) {
|
switch (node.kind) {
|
||||||
case ts.SyntaxKind.ExportDeclaration:
|
case ts.SyntaxKind.ExportDeclaration:
|
||||||
// Record export declarations
|
// Record export declarations
|
||||||
const exportDeclaration = <ts.ExportDeclaration>node;
|
const exportDeclaration = <ts.ExportDeclaration>node;
|
||||||
const moduleSpecifier = exportDeclaration.moduleSpecifier;
|
const {moduleSpecifier, exportClause} = exportDeclaration;
|
||||||
|
|
||||||
|
if (!moduleSpecifier) {
|
||||||
|
// no module specifier -> export {propName as name};
|
||||||
|
if (exportClause) {
|
||||||
|
exportClause.elements.forEach(spec => {
|
||||||
|
const name = spec.name.text;
|
||||||
|
const propNode = spec.propertyName || spec.name;
|
||||||
|
const value: MetadataValue = evaluator.evaluateNode(propNode);
|
||||||
|
if (!metadata) metadata = {};
|
||||||
|
metadata[name] = recordEntry(value, node);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (moduleSpecifier && moduleSpecifier.kind == ts.SyntaxKind.StringLiteral) {
|
if (moduleSpecifier && moduleSpecifier.kind == ts.SyntaxKind.StringLiteral) {
|
||||||
// Ignore exports that don't have string literals as exports.
|
// Ignore exports that don't have string literals as exports.
|
||||||
// This is allowed by the syntax but will be flagged as an error by the type checker.
|
// This is allowed by the syntax but will be flagged as an error by the type checker.
|
||||||
const from = (<ts.StringLiteral>moduleSpecifier).text;
|
const from = (<ts.StringLiteral>moduleSpecifier).text;
|
||||||
const moduleExport: ModuleExportMetadata = {from};
|
const moduleExport: ModuleExportMetadata = {from};
|
||||||
if (exportDeclaration.exportClause) {
|
if (exportClause) {
|
||||||
moduleExport.export = exportDeclaration.exportClause.elements.map(
|
moduleExport.export = exportClause.elements.map(
|
||||||
element => element.propertyName ?
|
spec => spec.propertyName ? {name: spec.propertyName.text, as: spec.name.text} :
|
||||||
{name: element.propertyName.text, as: element.name.text} :
|
spec.name.text);
|
||||||
element.name.text);
|
|
||||||
}
|
}
|
||||||
if (!exports) exports = [];
|
if (!exports) exports = [];
|
||||||
exports.push(moduleExport);
|
exports.push(moduleExport);
|
||||||
|
@ -281,6 +296,7 @@ export class MetadataCollector {
|
||||||
}
|
}
|
||||||
// Otherwise don't record metadata for the class.
|
// Otherwise don't record metadata for the class.
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ts.SyntaxKind.FunctionDeclaration:
|
case ts.SyntaxKind.FunctionDeclaration:
|
||||||
// Record functions that return a single value. Record the parameter
|
// Record functions that return a single value. Record the parameter
|
||||||
// names substitution will be performed by the StaticReflector.
|
// names substitution will be performed by the StaticReflector.
|
||||||
|
@ -297,6 +313,7 @@ export class MetadataCollector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ts.SyntaxKind.EnumDeclaration:
|
case ts.SyntaxKind.EnumDeclaration:
|
||||||
if (node.flags & ts.NodeFlags.Export) {
|
if (node.flags & ts.NodeFlags.Export) {
|
||||||
const enumDeclaration = <ts.EnumDeclaration>node;
|
const enumDeclaration = <ts.EnumDeclaration>node;
|
||||||
|
@ -332,7 +349,7 @@ export class MetadataCollector {
|
||||||
} else {
|
} else {
|
||||||
nextDefaultValue =
|
nextDefaultValue =
|
||||||
recordEntry(errorSym('Unsuppported enum member name', member.name), node);
|
recordEntry(errorSym('Unsuppported enum member name', member.name), node);
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
if (writtenMembers) {
|
if (writtenMembers) {
|
||||||
if (!metadata) metadata = {};
|
if (!metadata) metadata = {};
|
||||||
|
@ -340,6 +357,7 @@ export class MetadataCollector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ts.SyntaxKind.VariableStatement:
|
case ts.SyntaxKind.VariableStatement:
|
||||||
const variableStatement = <ts.VariableStatement>node;
|
const variableStatement = <ts.VariableStatement>node;
|
||||||
for (const variableDeclaration of variableStatement.declarationList.declarations) {
|
for (const variableDeclaration of variableStatement.declarationList.declarations) {
|
||||||
|
@ -373,7 +391,7 @@ export class MetadataCollector {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Destructuring (or binding) declarations are not supported,
|
// Destructuring (or binding) declarations are not supported,
|
||||||
// var {<identifier>[, <identifer>]+} = <expression>;
|
// var {<identifier>[, <identifier>]+} = <expression>;
|
||||||
// or
|
// or
|
||||||
// var [<identifier>[, <identifier}+] = <expression>;
|
// var [<identifier>[, <identifier}+] = <expression>;
|
||||||
// are not supported.
|
// are not supported.
|
||||||
|
|
|
@ -39,6 +39,7 @@ describe('Collector', () => {
|
||||||
'local-symbol-ref-func-dynamic.ts',
|
'local-symbol-ref-func-dynamic.ts',
|
||||||
'private-enum.ts',
|
'private-enum.ts',
|
||||||
're-exports.ts',
|
're-exports.ts',
|
||||||
|
're-exports-2.ts',
|
||||||
'static-field-reference.ts',
|
'static-field-reference.ts',
|
||||||
'static-method.ts',
|
'static-method.ts',
|
||||||
'static-method-call.ts',
|
'static-method-call.ts',
|
||||||
|
@ -527,6 +528,23 @@ describe('Collector', () => {
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should be able to collect exports with no module specifier', () => {
|
||||||
|
const source = program.getSourceFile('/re-exports-2.ts');
|
||||||
|
const metadata = collector.getMetadata(source);
|
||||||
|
expect(metadata.metadata).toEqual({
|
||||||
|
OtherModule: {__symbolic: 'reference', module: './static-field-reference', name: 'Foo'},
|
||||||
|
MyOtherModule: {__symbolic: 'reference', module: './static-field', name: 'MyModule'},
|
||||||
|
// TODO(vicb): support exported symbols - https://github.com/angular/angular/issues/13473
|
||||||
|
MyClass: {
|
||||||
|
__symbolic: 'error',
|
||||||
|
message: 'Reference to non-exported class',
|
||||||
|
line: 3,
|
||||||
|
character: 4,
|
||||||
|
context: {className: 'MyClass'}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should collect an error symbol if collecting a reference to a non-exported symbol', () => {
|
it('should collect an error symbol if collecting a reference to a non-exported symbol', () => {
|
||||||
const source = program.getSourceFile('/local-symbol-ref.ts');
|
const source = program.getSourceFile('/local-symbol-ref.ts');
|
||||||
const metadata = collector.getMetadata(source);
|
const metadata = collector.getMetadata(source);
|
||||||
|
@ -983,6 +1001,12 @@ const FILES: Directory = {
|
||||||
export {Foo as OtherModule} from './static-field-reference';
|
export {Foo as OtherModule} from './static-field-reference';
|
||||||
export * from 'angular2/core';
|
export * from 'angular2/core';
|
||||||
`,
|
`,
|
||||||
|
're-exports-2.ts': `
|
||||||
|
import {MyModule} from './static-field';
|
||||||
|
import {Foo as OtherModule} from './static-field-reference';
|
||||||
|
class MyClass {}
|
||||||
|
export {OtherModule, MyModule as MyOtherModule, MyClass};
|
||||||
|
`,
|
||||||
'local-symbol-ref.ts': `
|
'local-symbol-ref.ts': `
|
||||||
import {Component, Validators} from 'angular2/core';
|
import {Component, Validators} from 'angular2/core';
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue