TypeWriter logic for identifiers

This commit is contained in:
Jason Freeman 2014-08-11 16:01:30 -07:00
parent 3c6c0353b3
commit 96fba4d867
3 changed files with 65 additions and 9 deletions

View file

@ -52,7 +52,6 @@ class CompilerBaselineRunner extends RunnerBase {
var rootDir = lastUnit.originalFilePath.indexOf('conformance') === -1 ? 'tests/cases/compiler/' : lastUnit.originalFilePath.substring(0, lastUnit.originalFilePath.lastIndexOf('/')) + '/';
var result: Harness.Compiler.CompilerResult;
var program: ts.Program;
var checker: ts.TypeChecker;
var options: ts.CompilerOptions;
// equivalent to the files that will be passed on the command line
@ -87,10 +86,9 @@ class CompilerBaselineRunner extends RunnerBase {
});
}
options = harnessCompiler.compileFiles(toBeCompiled, otherFiles, function (compileResult, _program, _checker) {
options = harnessCompiler.compileFiles(toBeCompiled, otherFiles, function (compileResult, _checker) {
result = compileResult;
// The program and checker will be used by typeWriter
program = _program;
// The checker will be used by typeWriter
checker = _checker;
}, function (settings) {
harnessCompiler.setCompilerSettings(tcSettings);
@ -262,7 +260,7 @@ class CompilerBaselineRunner extends RunnerBase {
var allFiles = toBeCompiled.concat(otherFiles);
var typeLines: string[] = [];
var typeMap: { [fileName: string]: { [lineNum: number]: string[]; } } = {};
var walker = new TypeWriterWalker(program, checker);
var walker = new TypeWriterWalker(checker);
allFiles.forEach(file => {
var codeLines = file.content.split('\n');
walker.getTypes(file.unitName).forEach(result => {

View file

@ -609,7 +609,7 @@ module Harness {
public compileFiles(inputFiles: { unitName: string; content: string }[],
otherFiles: { unitName: string; content?: string }[],
onComplete: (result: CompilerResult, program: ts.Program, checker: ts.TypeChecker) => void,
onComplete: (result: CompilerResult, checker: ts.TypeChecker) => void,
settingsCallback?: (settings: ts.CompilerOptions) => void,
options?: ts.CompilerOptions) {
@ -755,7 +755,7 @@ module Harness {
var result = new CompilerResult(fileOutputs, errors, []);
// Covert the source Map data into the baseline
result.updateSourceMapRecord(program, emitResult ? emitResult.sourceMaps : undefined);
onComplete(result, program, checker);
onComplete(result, checker);
// reset what newline means in case the last test changed it
sys.newLine = '\r\n';

View file

@ -7,9 +7,67 @@ interface TypeWriterResult {
}
class TypeWriterWalker {
constructor(public program: ts.Program, public checker: ts.TypeChecker) {
results: TypeWriterResult[];
currentSourceFile: ts.SourceFile;
constructor(public checker: ts.TypeChecker) {
}
public getTypes(fileName: string): TypeWriterResult[] {
return [];
var sourceFile = this.checker.getProgram().getSourceFile(fileName);
this.currentSourceFile = sourceFile;
this.results = [];
this.visitNode(sourceFile);
return this.results;
}
private visitNode(node: ts.Node): void {
if (node.kind === ts.SyntaxKind.Identifier) {
var identifier = <ts.Identifier>node;
if (!this.isLabel(identifier)) {
var type = this.getTypeOfIdentifier(identifier);
this.log(node, type);
}
}
else if (node.kind === ts.SyntaxKind.ThisKeyword) {
this.log(node, undefined);
}
else {
ts.forEachChild(node, child => this.visitNode(child));
}
}
private isLabel(identifier: ts.Identifier): boolean {
var parent = identifier.parent;
switch (parent.kind) {
case ts.SyntaxKind.ContinueStatement:
case ts.SyntaxKind.BreakStatement:
return (<ts.BreakOrContinueStatement>parent).label === identifier;
case ts.SyntaxKind.LabelledStatement:
return (<ts.LabelledStatement>parent).label === identifier;
}
return false;
}
private log(node: ts.Node, type: ts.Type): void {
var actualPos = ts.skipTrivia(this.currentSourceFile.text, node.pos);
var lineAndCharacter = this.currentSourceFile.getLineAndCharacterFromPosition(actualPos);
var name = ts.getSourceTextOfNodeFromSourceText(this.currentSourceFile.text, node);
this.results.push({
line: lineAndCharacter.line - 1,
column: lineAndCharacter.character,
syntaxKind: ts.SyntaxKind[node.kind],
identifierName: name,
type: this.checker.typeToString(type)
});
}
private getTypeOfIdentifier(node: ts.Identifier): ts.Type {
var identifierSymbol = this.checker.getSymbolInfo(node);
ts.Debug.assert(identifierSymbol, "symbol doesn't exist");
var type = this.checker.getTypeOfSymbol(identifierSymbol);
ts.Debug.assert(type, "type doesn't exist");
return type;
}
}