Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
687d25a
initial changes
mhegazy Jun 30, 2015
c5c4835
visit nodes
mhegazy Jul 1, 2015
5865c02
Add error reporting
mhegazy Jul 4, 2015
96a2b7f
Do error reporting slightlly difrrentelly
mhegazy Jul 4, 2015
46ddcbf
Walk types
mhegazy Jul 7, 2015
e3444c1
use track symbol insted of walking types
mhegazy Jul 7, 2015
b010a19
remove old diagnostics reporting
mhegazy Jul 7, 2015
4e6948f
Remove isDeclarationVisible uses
mhegazy Jul 7, 2015
4f1c088
rename functions with write prefix to emit
mhegazy Jul 7, 2015
ccba296
clean up
mhegazy Jul 7, 2015
e05b983
Handel visibility correctelly
mhegazy Jul 7, 2015
f33e422
handel internals when collecting declarations
mhegazy Jul 7, 2015
820d77d
Wire trackSymbol to show errors correctelly
mhegazy Jul 7, 2015
655104e
Disable internal check for now untill all code is fixed
mhegazy Jul 7, 2015
7718b22
use custom indexOf instead of array.prototype.indexOf to allow runnin…
mhegazy Jul 7, 2015
86c9578
Accept symbol baselines
mhegazy Jul 7, 2015
ceee493
A few additional fixes
mhegazy Jul 8, 2015
34f0d54
rename functions
mhegazy Jul 8, 2015
672fb44
use namespaces instead of module
mhegazy Jul 9, 2015
6eb1df7
Ensure trackSymbol is only called for type symbols
mhegazy Jul 9, 2015
fc7325b
handel import clauses and export default expression
mhegazy Jul 9, 2015
c8a8ff5
Handel variableDeclarations and variableStatements
mhegazy Jul 9, 2015
0f46057
handel binding patterns
mhegazy Jul 9, 2015
cb964c1
Accept baseline for export default case
mhegazy Jul 10, 2015
50cf293
accept baselines
mhegazy Jul 10, 2015
0e28bee
Fix error reporting issues
mhegazy Jul 10, 2015
a27e6f2
handel expressions in heritage clauses
mhegazy Jul 10, 2015
6384dcf
Handel type paramter declarations correctelly
mhegazy Jul 10, 2015
ffde83c
reorder declarations
mhegazy Jul 10, 2015
99d4e46
clean up collection logic
mhegazy Jul 10, 2015
767e27f
Handel missing PropertyAccessExpression
mhegazy Jul 14, 2015
edaed88
Filter declarations from other files
mhegazy Jul 14, 2015
2f3c689
use forEachChild in visitNode
mhegazy Jul 14, 2015
d1ce92e
Do not collect import declarations
mhegazy Jul 14, 2015
6193c5a
Revert "Accept symbol baselines"
mhegazy Jul 14, 2015
1d92d8e
Update error messages and fix error reporting for computed property n…
mhegazy Jul 14, 2015
8209348
Accept baseline change
mhegazy Jul 14, 2015
d18b829
Accept baseline
mhegazy Jul 15, 2015
d47caa2
Handel inaccisible symbol errors
mhegazy Jul 16, 2015
57aae40
accept baselines
mhegazy Jul 16, 2015
b44fba3
remove unused code from checker
mhegazy Jul 16, 2015
1bf2d0a
Make trackSymbol optional and use an empty writer in visitNode
mhegazy Jul 16, 2015
0758e15
Remove unused interfaces, and simplify the writer logic
mhegazy Jul 16, 2015
4b2aa47
Reorganize how triple slash references are being emitted
mhegazy Jul 16, 2015
0f58d94
remove unsused variable
mhegazy Jul 17, 2015
ca07040
Consolidate emit logic in one place, and split the process into two p…
mhegazy Jul 20, 2015
98cd107
Switch to iterative model and clean up error reporting
mhegazy Jul 21, 2015
bd1347d
handel missing nodes in visitNode
mhegazy Jul 22, 2015
1f0520e
Only check if hasExportDeclarations on external modules
mhegazy Jul 22, 2015
859bd12
Do not create a new typewriter everytime
mhegazy Jul 22, 2015
33ace7a
Merge branch 'master' into declarations
Jul 27, 2015
ce8090a
remove unused property
Jul 27, 2015
fd01a64
Support @internal
Jul 28, 2015
a876104
make forEachTopLevelDeclaration generic
mhegazy Jul 28, 2015
ab42595
Fix #3912: emit declaration for binding elements correctelly
mhegazy Jul 28, 2015
ed2e5d9
move getLocalTargetOfAliasDeclaration back to the emitter
mhegazy Jul 29, 2015
f4da2fe
Merge branch 'master' into declarations
mhegazy Jul 29, 2015
4ec081c
rever sourceRoot change to tsconfig.json
mhegazy Jul 29, 2015
cbb4e2c
Merge branch 'master' into declarations
mhegazy Aug 9, 2015
3eb940b
Merge branch 'master' into declarations
mhegazy Sep 17, 2015
9ebf182
handel outFile flag
mhegazy Sep 21, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Prev Previous commit
Next Next commit
Consolidate emit logic in one place, and split the process into two p…
…hases preporcess and write
  • Loading branch information
mhegazy committed Jul 20, 2015
commit ca07040df2d452a135f78b32f29506b9f21e4dbd
2 changes: 1 addition & 1 deletion src/compiler/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -805,4 +805,4 @@ namespace ts {
Debug.assert(false, message);
}
}
}
}
252 changes: 150 additions & 102 deletions src/compiler/declarationEmitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,70 +2,57 @@

/* @internal */
namespace ts {
interface DeclarationEmit {
hasDeclarationDiagnostics: boolean;
output: string;
}

interface NodeLinks {
visibleChildren?: Node[];
visited?: boolean;
collected?: boolean;
hasExportDeclarations?: boolean;
}

export function getDeclarationDiagnostics(host: EmitHost, resolver: EmitResolver, targetSourceFile: SourceFile): Diagnostic[] {
let diagnostics: Diagnostic[] = [];
let jsFilePath = getOwnEmitOutputFilePath(targetSourceFile, host, ".js");
emitDeclarations(host, resolver, diagnostics, jsFilePath, targetSourceFile);
return diagnostics;
interface PreprocessResults {
sourceFiles: SourceFile[];
nodeLinks: NodeLinks[];
resolver: EmitResolver;
}

const emptyHandler = () => { };

function emitDeclarations(host: EmitHost, resolver: EmitResolver, diagnostics: Diagnostic[], jsFilePath: string, root?: SourceFile): DeclarationEmit {
function writeDeclarations(outputFileName: string, preprocessResults: PreprocessResults, host: EmitHost, diagnostics: Diagnostic[]): void {
let newLine = host.getNewLine();
let compilerOptions = host.getCompilerOptions();
let enclosingDeclaration: Node;
let currentSourceFile: SourceFile;

let resolver = preprocessResults.resolver;
let nodeLinks = preprocessResults.nodeLinks;

// setup the writer
let writer = createNewTextWriterWithSymbolWriter();
let write = writer.write;
let writeTextOfNode = writer.writeTextOfNode;
let writeLine = writer.writeLine;
let increaseIndent = writer.increaseIndent;
let decreaseIndent = writer.decreaseIndent;

let enclosingDeclaration: Node;
let currentSourceFile: SourceFile;
let hasDeclarationDiagnostics = false;
// Emit any triple-slash references
emitTripleSlashReferences(preprocessResults.sourceFiles);

let nodeLinks: NodeLinks[] = [];
function getNodeLinks(node: Node): NodeLinks {
let nodeId = getNodeId(node);
return nodeLinks[nodeId] || (nodeLinks[nodeId] = {});
for (let sourceFile of preprocessResults.sourceFiles) {
// emit the declarations from this file
emitSourceFile(sourceFile);
}

// Emit any triple-slash references
emitTripleSlashReferences(root);
// write the output to disk
writeFile(host, diagnostics, outputFileName, writer.getText(), compilerOptions.emitBOM);

if (root) {
// Emitting just a single file, so emit references in this file only
emitSourceFile(root);
}
else {
// Emit references corresponding to this file
forEach(host.getSourceFiles(), sourceFile => {
if (!isExternalModuleOrDeclarationFile(sourceFile)) {
emitSourceFile(sourceFile);
}
});
}
return;

return {
hasDeclarationDiagnostics,
output: writer.getText(),
};
function getNodeLinks(node: Node): NodeLinks {
let nodeId = getNodeId(node);
return nodeLinks[nodeId] || (nodeLinks[nodeId] = {});
}

function emitTripleSlashReferences(root: SourceFile) {
function emitTripleSlashReferences(sourceFiles: SourceFile[]) {
if (compilerOptions.noResolve) {
// Nothing to do
return;
Expand All @@ -74,17 +61,9 @@ namespace ts {
let emittedReferencedFiles: SourceFile[] = [];
let addedGlobalFileReference = false;

if (root) {
// Emitting just a single file, so emit references in this file only
emitTripleSlashReferncesInFile(root);
}
else {
// Emit references corresponding to this file
forEach(host.getSourceFiles(), sourceFile => {
if (!isExternalModuleOrDeclarationFile(sourceFile)) {
emitTripleSlashReferncesInFile(sourceFile);
}
});
// Emit references corresponding to this file
for (let sourceFile of sourceFiles) {
emitTripleSlashReferncesInFile(sourceFile);
}

return;
Expand All @@ -99,7 +78,7 @@ namespace ts {
}

let shouldEmitRefrence: boolean

if (isDeclarationFile(referencedFile) || shouldEmitToOwnFile(referencedFile, compilerOptions)) {
// If the reference file is a declaration file or an external module,
// we know there is going to be a .d.ts file matching it. Emit that reference
Expand Down Expand Up @@ -127,7 +106,7 @@ namespace ts {
: removeFileExtension(compilerOptions.out) + ".d.ts"; // Global out file

declFileName = getRelativePathToDirectoryOrUrl(
getDirectoryPath(normalizeSlashes(jsFilePath)),
getDirectoryPath(normalizeSlashes(outputFileName)),
declFileName,
host.getCurrentDirectory(),
host.getCanonicalFileName,
Expand Down Expand Up @@ -160,24 +139,6 @@ namespace ts {
return writer;
}

function createVoidSymbolWriter(trackTypeSymbol: (s: Symbol) => void, trackInaccesibleSymbol: (s: Symbol) => void): SymbolWriter {
return {
writeLine: emptyHandler,
writeKeyword: emptyHandler,
writeOperator: emptyHandler,
writePunctuation: emptyHandler,
writeSpace: emptyHandler,
writeStringLiteral: emptyHandler,
writeParameter: emptyHandler,
writeSymbol: emptyHandler,
decreaseIndent: emptyHandler,
increaseIndent: emptyHandler,
clear: emptyHandler,
trackTypeSymbol,
trackInaccesibleSymbol
};
}

function emitTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, type: TypeNode) {
write(": ");
if (type) {
Expand Down Expand Up @@ -800,15 +761,6 @@ namespace ts {
}
}

function getTypeAnnotationFromAccessor(getAccessor: AccessorDeclaration, setAccessor: AccessorDeclaration): TypeNode {
if (getAccessor && getAccessor.type) {
return getAccessor.type // Getter - return type
}
if (setAccessor && setAccessor.parameters.length > 0) {
return setAccessor.parameters[0].type;
}
}

function emitAccessorDeclaration(node: AccessorDeclaration) {
if (hasDynamicName(node)) {
return;
Expand Down Expand Up @@ -1063,6 +1015,56 @@ namespace ts {
}
}

function writeChildDeclarations(node: Node): void {
forEach(sortDeclarations(getNodeLinks(node).visibleChildren), emitNode);
}

function emitSourceFile(sourceFile: SourceFile): void {
currentSourceFile = sourceFile;
enclosingDeclaration = sourceFile;

// write the declarations
writeChildDeclarations(sourceFile);
}

function compareDeclarations(d1: Node, d2: Node): Comparison {
return compareValues(d1.pos, d2.pos) || Comparison.EqualTo;
}

function sortDeclarations(nodes: Node[]): Node[] {
return nodes && nodes.sort(compareDeclarations);
}
}

function preprocessDeclarations(sourceFiles: SourceFile[], resolver: EmitResolver, diagnostics: Diagnostic[], compilerOptions: CompilerOptions): PreprocessResults {
let currentSourceFile: SourceFile;
let nodeLinks: NodeLinks[] = [];

for (let sourceFile of sourceFiles) {
preprocessSourceFile(sourceFile);
}

return {
sourceFiles,
nodeLinks,
resolver
};

function getNodeLinks(node: Node): NodeLinks {
let nodeId = getNodeId(node);
return nodeLinks[nodeId] || (nodeLinks[nodeId] = {});
}

function hasInternalAnnotation(range: CommentRange) {
let text = currentSourceFile.text;
let comment = text.substring(range.pos, range.end);
return comment.indexOf("@internal") >= 0;
}

function isInternal(node: Node) {
return forEach(getLeadingCommentRanges(currentSourceFile.text, node.pos), hasInternalAnnotation)
}

function collectReferencedDeclarations(node: Node): void {
let currentErrorNode: Node;
let typeWriter = createVoidSymbolWriter(trackTypeSymbol, trackInaccesibleSymbol);
Expand All @@ -1081,6 +1083,24 @@ namespace ts {
}
}

function createVoidSymbolWriter(trackTypeSymbol: (s: Symbol) => void, trackInaccesibleSymbol: (s: Symbol) => void): SymbolWriter {
return {
writeLine: emptyHandler,
writeKeyword: emptyHandler,
writeOperator: emptyHandler,
writePunctuation: emptyHandler,
writeSpace: emptyHandler,
writeStringLiteral: emptyHandler,
writeParameter: emptyHandler,
writeSymbol: emptyHandler,
decreaseIndent: emptyHandler,
increaseIndent: emptyHandler,
clear: emptyHandler,
trackTypeSymbol,
trackInaccesibleSymbol
};
}

function visitNode(node: Node): void {
if (!node) return;

Expand Down Expand Up @@ -1440,8 +1460,6 @@ namespace ts {
function reportDeclarationAccessiblityMessage(referencedDeclaration: Declaration, errorNode: Node): void {
Debug.assert(referencedDeclaration.name && referencedDeclaration.name.kind === SyntaxKind.Identifier);

hasDeclarationDiagnostics = true;

let referencedDeclarationName = (<Identifier>referencedDeclaration.name).text;
let container = errorNode;

Expand Down Expand Up @@ -1534,7 +1552,6 @@ namespace ts {
}

function reportUnamedDeclarationMessage(errorNode: Node): void {
hasDeclarationDiagnostics = true;
let container = errorNode;

while (container) {
Expand Down Expand Up @@ -1654,37 +1671,68 @@ namespace ts {
links.visibleChildren.push(child);
}

function compareDeclarations(d1: Node, d2: Node): Comparison {
return compareValues(d1.pos, d2.pos) || Comparison.EqualTo;
}
function preprocessSourceFile(sourceFile: SourceFile): void {
currentSourceFile = sourceFile;

function sortDeclarations(nodes: Node[]): Node[] {
return nodes && nodes.sort(compareDeclarations);
// Collect all visible declarations
collectTopLevelChildDeclarations(sourceFile);
}
}

function writeChildDeclarations(node: Node): void {
forEach(sortDeclarations(getNodeLinks(node).visibleChildren), emitNode);
function forEachExpectedOutputFile(host: EmitHost, targetSourceFile: SourceFile, action: (name: string, sources: SourceFile[]) => void) {
let compilerOptions = host.getCompilerOptions();
if (targetSourceFile) {
// If we have a targetSourceFile (e.g calling emitter from language service to getEmitOutput)
// only emit the outputs of this file
if (shouldEmitToOwnFile(targetSourceFile, compilerOptions)) {
let outputFilePath = getOwnEmitOutputFilePath(targetSourceFile, host, ".d.ts");
action(outputFilePath, [targetSourceFile]);
return;
}
// Fall through to the --out case, i.e. shouldEmitToOwnFile()=== false
}
else {
// No targetSourceFile, we need to emit all files
for (let sourceFile of host.getSourceFiles()) {
if (shouldEmitToOwnFile(sourceFile, compilerOptions)) {
let outputFilePath = getOwnEmitOutputFilePath(sourceFile, host, ".d.ts");
action(outputFilePath, [sourceFile]);
}
}
}

function emitSourceFile(sourceFile: SourceFile): void {
currentSourceFile = sourceFile;
enclosingDeclaration = sourceFile;

// Collect all visible declarations
collectTopLevelChildDeclarations(sourceFile);
if (compilerOptions.out) {
// Emit any files that did not have their own output file
// all these files will emit to a single output file specified by compiler options.out
let outputFilePath = removeFileExtension(compilerOptions.out) + ".d.ts"
let sourceFiles = filter(host.getSourceFiles(), sourceFile => !isExternalModuleOrDeclarationFile(sourceFile));
action(outputFilePath, sourceFiles);;
}
}

// write the declarations
writeChildDeclarations(sourceFile);
export function getDeclarationDiagnostics(host: EmitHost, resolver: EmitResolver, targetSourceFile: SourceFile): Diagnostic[] {
let diagnostics: Diagnostic[] = [];
forEachExpectedOutputFile(host, targetSourceFile, (outputFileName, sourceFiles) => {
preprocessDeclarations(sourceFiles, resolver, diagnostics, host.getCompilerOptions());
});

if (targetSourceFile) {
return filter(diagnostics, d => d.file === targetSourceFile);
}
else {
return diagnostics;
}
}

/* @internal */
export function writeDeclarationFile(jsFilePath: string, sourceFile: SourceFile, host: EmitHost, resolver: EmitResolver, diagnostics: Diagnostic[]) {
let emitDeclarationResult = emitDeclarations(host, resolver, diagnostics, jsFilePath, sourceFile);
// TODO(shkamat): Should we not write any declaration file if any of them can produce error,
// or should we just not write this file like we are doing now
if (!emitDeclarationResult.hasDeclarationDiagnostics) {
writeFile(host, diagnostics, removeFileExtension(jsFilePath) + ".d.ts", emitDeclarationResult.output, host.getCompilerOptions().emitBOM);
}
export function emitDeclarations(host: EmitHost, resolver: EmitResolver, targetSourceFile: SourceFile, diagnostics: Diagnostic[]): void {
forEachExpectedOutputFile(host, targetSourceFile, (outputFileName, sourceFiles) => {
let fileDiagnostics: Diagnostic[] = [];
let preprocessResult = preprocessDeclarations(sourceFiles, resolver, fileDiagnostics, host.getCompilerOptions());
if (fileDiagnostics.length === 0) {
writeDeclarations(outputFileName, preprocessResult, host, fileDiagnostics);
}
diagnostics.push.apply(diagnostics, fileDiagnostics);
});
}
}
Loading