Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Jakefile
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ var compilerSources = [
"binder.ts",
"checker.ts",
"emitter.ts",
"program.ts",
"commandLineParser.ts",
"tsc.ts",
"diagnosticInformationMap.generated.ts"
Expand All @@ -56,6 +57,7 @@ var servicesSources = [
"binder.ts",
"checker.ts",
"emitter.ts",
"program.ts",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add "program.ts" to thedefinitionsRoots`.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

"diagnosticInformationMap.generated.ts"
].map(function (f) {
return path.join(compilerDirectory, f);
Expand Down Expand Up @@ -92,6 +94,7 @@ var definitionsRoots = [
"compiler/scanner.d.ts",
"compiler/parser.d.ts",
"compiler/checker.d.ts",
"compiler/program.d.ts",
"services/services.d.ts",
];

Expand Down
4 changes: 0 additions & 4 deletions src/compiler/binder.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
/// <reference path="types.ts"/>
/// <reference path="core.ts"/>
/// <reference path="scanner.ts"/>
/// <reference path="parser.ts"/>

module ts {

export const enum ModuleInstanceState {
NonInstantiated = 0,
Instantiated = 1,
Expand Down
181 changes: 76 additions & 105 deletions src/compiler/checker.ts

Large diffs are not rendered by default.

108 changes: 56 additions & 52 deletions src/compiler/emitter.ts

Large diffs are not rendered by default.

361 changes: 0 additions & 361 deletions src/compiler/parser.ts

Large diffs are not rendered by default.

408 changes: 408 additions & 0 deletions src/compiler/program.ts

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion src/compiler/scanner.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/// <reference path="types.ts"/>
/// <reference path="core.ts"/>
/// <reference path="diagnosticInformationMap.generated.ts"/>

Expand Down
13 changes: 3 additions & 10 deletions src/compiler/tsc.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
/// <reference path="core.ts"/>
/// <reference path="sys.ts"/>
/// <reference path="types.ts"/>
/// <reference path="scanner.ts"/>
/// <reference path="parser.ts"/>
/// <reference path="binder.ts"/>
/// <reference path="checker.ts"/>
/// <reference path="emitter.ts"/>
/// <reference path="program.ts"/>
/// <reference path="commandLineParser.ts"/>

module ts {
Expand Down Expand Up @@ -293,15 +286,15 @@ module ts {
var checker = program.getTypeChecker(/*fullTypeCheckMode*/ true);
var checkStart = new Date().getTime();
errors = checker.getDiagnostics();
if (checker.isEmitBlocked()) {
if (program.isEmitBlocked()) {
exitStatus = EmitReturnStatus.AllOutputGenerationSkipped;
}
else if (compilerOptions.noEmit) {
exitStatus = EmitReturnStatus.Succeeded;
}
else {
var emitStart = new Date().getTime();
var emitOutput = checker.emitFiles();
var emitOutput = program.emitFiles();
var emitErrors = emitOutput.diagnostics;
exitStatus = emitOutput.emitResultStatus;
var reportStart = new Date().getTime();
Expand Down
43 changes: 31 additions & 12 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
/// <reference path="core.ts"/>

module ts {
export interface Map<T> {
[index: string]: T;
Expand Down Expand Up @@ -248,7 +246,6 @@ module ts {
EnumMember,
// Top-level nodes
SourceFile,
Program,

// Synthesized list
SyntaxList,
Expand Down Expand Up @@ -925,15 +922,33 @@ module ts {
identifiers: Map<string>;
}

export interface Program {
export interface ScriptReferenceHost {
getCompilerOptions(): CompilerOptions;
getSourceFile(filename: string): SourceFile;
getCurrentDirectory(): string;
}

export interface Program extends ScriptReferenceHost {
getSourceFiles(): SourceFile[];
getCompilerOptions(): CompilerOptions;
getCompilerHost(): CompilerHost;

getDiagnostics(sourceFile?: SourceFile): Diagnostic[];
getGlobalDiagnostics(): Diagnostic[];
getTypeChecker(fullTypeCheckMode: boolean): TypeChecker;
getDeclarationDiagnostics(sourceFile: SourceFile): Diagnostic[];

// Gets a type checker that can be used to semantically analyze source fils in the program.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"files"

// The 'produceDiagnostics' flag determines if the checker will produce diagnostics while
// analyzing the code. It can be set to 'false' to make many type checking operaitons

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"operations"

// faster. With this flag set, the checker can avoid codepaths only necessary to produce
// diagnostics, but not necessary to answer semantic questions about the code.
//
// If 'produceDiagnostics' is false, then any calls to get diagnostics from the TypeChecker

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"getDiagnostics" "any diagnostics"

// will throw an invalid operation exception.
getTypeChecker(produceDiagnostics: boolean): TypeChecker;
getCommonSourceDirectory(): string;

emitFiles(targetSourceFile?: SourceFile): EmitResult;
isEmitBlocked(sourceFile?: SourceFile): boolean;
}

export interface SourceMapSpan {
Expand Down Expand Up @@ -973,16 +988,22 @@ module ts {
sourceMaps: SourceMapData[]; // Array of sourceMapData if compiler emitted sourcemaps
}

export interface TypeCheckerHost {
getCompilerOptions(): CompilerOptions;
getCompilerHost(): CompilerHost;

getSourceFiles(): SourceFile[];
getSourceFile(filename: string): SourceFile;
}

export interface TypeChecker {
getProgram(): Program;
getEmitResolver(): EmitResolver;
getDiagnostics(sourceFile?: SourceFile): Diagnostic[];
getDeclarationDiagnostics(sourceFile: SourceFile): Diagnostic[];
getGlobalDiagnostics(): Diagnostic[];
getNodeCount(): number;
getIdentifierCount(): number;
getSymbolCount(): number;
getTypeCount(): number;
emitFiles(targetSourceFile?: SourceFile): EmitResult;
getTypeOfSymbolAtLocation(symbol: Symbol, node: Node): Type;
getDeclaredTypeOfSymbol(symbol: Symbol): Type;
getPropertiesOfType(type: Type): Symbol[];
Expand All @@ -1006,7 +1027,7 @@ module ts {
isImplementationOfOverload(node: FunctionLikeDeclaration): boolean;
isUndefinedSymbol(symbol: Symbol): boolean;
isArgumentsSymbol(symbol: Symbol): boolean;
isEmitBlocked(sourceFile?: SourceFile): boolean;

// Returns the constant value of this enum member, or 'undefined' if the enum member has a computed value.
getEnumMemberValue(node: EnumMember): number;
isValidPropertyAccess(node: PropertyAccessExpression | QualifiedName, propertyName: string): boolean;
Expand Down Expand Up @@ -1088,7 +1109,6 @@ module ts {
}

export interface EmitResolver {
getProgram(): Program;
getLocalNameOfContainer(container: ModuleDeclaration | EnumDeclaration): string;
getExpressionNamePrefix(node: Identifier): string;
getExportAssignmentName(node: SourceFile): string;
Expand All @@ -1105,7 +1125,6 @@ module ts {
isEntityNameVisible(entityName: EntityName, enclosingDeclaration: Node): SymbolVisibilityResult;
// Returns the constant value this property access resolves to, or 'undefined' for a non-constant
getConstantValue(node: PropertyAccessExpression | ElementAccessExpression): number;
isEmitBlocked(sourceFile?: SourceFile): boolean;
isUnknownIdentifier(location: Node, name: string): boolean;
}

Expand Down
23 changes: 19 additions & 4 deletions src/compiler/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -691,11 +691,11 @@ module ts {
return undefined;
}

export function tryResolveScriptReference(program: Program, sourceFile: SourceFile, reference: FileReference) {
if (!program.getCompilerOptions().noResolve) {
export function tryResolveScriptReference(host: ScriptReferenceHost, sourceFile: SourceFile, reference: FileReference) {
if (!host.getCompilerOptions().noResolve) {
var referenceFileName = isRootedDiskPath(reference.filename) ? reference.filename : combinePaths(getDirectoryPath(sourceFile.filename), reference.filename);
referenceFileName = getNormalizedAbsolutePath(referenceFileName, program.getCompilerHost().getCurrentDirectory());
return program.getSourceFile(referenceFileName);
referenceFileName = getNormalizedAbsolutePath(referenceFileName, host.getCurrentDirectory());
return host.getSourceFile(referenceFileName);
}
}

Expand Down Expand Up @@ -790,6 +790,21 @@ module ts {
return false;
}

export function createEmitHostFromProgram(program: Program): EmitHost {
var compilerHost = program.getCompilerHost();
return {
getCanonicalFileName: compilerHost.getCanonicalFileName,
getCommonSourceDirectory: program.getCommonSourceDirectory,
getCompilerOptions: program.getCompilerOptions,
getCurrentDirectory: compilerHost.getCurrentDirectory,
getNewLine: compilerHost.getNewLine,
getSourceFile: program.getSourceFile,
getSourceFiles: program.getSourceFiles,
isEmitBlocked: program.isEmitBlocked,
writeFile: compilerHost.writeFile,
};
}

export function textSpanEnd(span: TextSpan) {
return span.start + span.length
}
Expand Down
14 changes: 7 additions & 7 deletions src/harness/compilerRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class CompilerBaselineRunner extends RunnerBase {
var rootDir: string;

var result: Harness.Compiler.CompilerResult;
var checker: ts.TypeChecker;
var program: ts.Program;
var options: ts.CompilerOptions;
// equivalent to the files that will be passed on the command line
var toBeCompiled: { unitName: string; content: string }[];
Expand Down Expand Up @@ -97,10 +97,10 @@ class CompilerBaselineRunner extends RunnerBase {
});
}

options = harnessCompiler.compileFiles(toBeCompiled, otherFiles, function (compileResult, _checker) {
options = harnessCompiler.compileFiles(toBeCompiled, otherFiles, function (compileResult, _program) {
result = compileResult;
// The checker will be used by typeWriter
checker = _checker;
// The program will be used by typeWriter
program = _program;
}, function (settings) {
harnessCompiler.setCompilerSettings(tcSettings);
});
Expand Down Expand Up @@ -138,7 +138,7 @@ class CompilerBaselineRunner extends RunnerBase {
lastUnit = undefined;
rootDir = undefined;
result = undefined;
checker = undefined;
program = undefined;
options = undefined;
toBeCompiled = undefined;
otherFiles = undefined;
Expand Down Expand Up @@ -267,10 +267,10 @@ class CompilerBaselineRunner extends RunnerBase {
// NEWTODO: Type baselines
if (result.errors.length === 0) {
Harness.Baseline.runBaseline('Correct expression types for ' + fileName, justName.replace(/\.ts/, '.types'), () => {
var allFiles = toBeCompiled.concat(otherFiles).filter(file => !!checker.getProgram().getSourceFile(file.unitName));
var allFiles = toBeCompiled.concat(otherFiles).filter(file => !!program.getSourceFile(file.unitName));
var typeLines: string[] = [];
var typeMap: { [fileName: string]: { [lineNum: number]: string[]; } } = {};
var walker = new TypeWriterWalker(checker);
var walker = new TypeWriterWalker(program);
allFiles.forEach(file => {
var codeLines = file.content.split('\n');
walker.getTypes(file.unitName).forEach(result => {
Expand Down
4 changes: 2 additions & 2 deletions src/harness/fourslash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2201,13 +2201,13 @@ module FourSlash {
ts.sys.useCaseSensitiveFileNames);
// TODO (drosen): We need to enforce checking on these tests.
var program = ts.createProgram([Harness.Compiler.fourslashFilename, fileName], { out: "fourslashTestOutput.js", noResolve: true, target: ts.ScriptTarget.ES3 }, host);
var checker = ts.createTypeChecker(program, /*fullTypeCheckMode*/ true);
var checker = ts.createTypeChecker(program, /*produceDiagnostics*/ true);

var errors = program.getDiagnostics().concat(checker.getDiagnostics());
if (errors.length > 0) {
throw new Error('Error compiling ' + fileName + ': ' + errors.map(e => e.messageText).join('\r\n'));
}
checker.emitFiles();
program.emitFiles();
result = result || ''; // Might have an empty fourslash file

// Compile and execute the test
Expand Down
12 changes: 5 additions & 7 deletions src/harness/harness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@

/// <reference path='..\services\services.ts' />
/// <reference path='..\services\shims.ts' />
/// <reference path='..\compiler\core.ts' />
/// <reference path='..\compiler\sys.ts' />
/// <reference path='external\mocha.d.ts'/>
/// <reference path='external\chai.d.ts'/>
/// <reference path='sourceMapRecorder.ts'/>
Expand Down Expand Up @@ -909,7 +907,7 @@ module Harness {

public compileFiles(inputFiles: { unitName: string; content: string }[],
otherFiles: { unitName: string; content: string }[],
onComplete: (result: CompilerResult, checker: ts.TypeChecker) => void,
onComplete: (result: CompilerResult, program: ts.Program) => void,
settingsCallback?: (settings: ts.CompilerOptions) => void,
options?: ts.CompilerOptions) {

Expand Down Expand Up @@ -1068,14 +1066,14 @@ module Harness {
options.target,
useCaseSensitiveFileNames));

var checker = program.getTypeChecker(/*fullTypeCheckMode*/ true);
var checker = program.getTypeChecker(/*produceDiagnostics*/ true);

var isEmitBlocked = checker.isEmitBlocked();
var isEmitBlocked = program.isEmitBlocked();

// only emit if there weren't parse errors
var emitResult: ts.EmitResult;
if (!isEmitBlocked) {
emitResult = checker.emitFiles();
emitResult = program.emitFiles();
}

var errors: HarnessDiagnostic[] = [];
Expand All @@ -1086,7 +1084,7 @@ module Harness {
this.lastErrors = errors;

var result = new CompilerResult(fileOutputs, errors, program, ts.sys.getCurrentDirectory(), emitResult ? emitResult.sourceMaps : undefined);
onComplete(result, checker);
onComplete(result, program);

// reset what newline means in case the last test changed it
ts.sys.newLine = '\r\n';
Expand Down
4 changes: 2 additions & 2 deletions src/harness/projectsRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,9 @@ class ProjectRunner extends RunnerBase {
var errors = program.getDiagnostics();
var sourceMapData: ts.SourceMapData[] = null;
if (!errors.length) {
var checker = program.getTypeChecker(/*fullTypeCheck*/ true);
var checker = program.getTypeChecker(/*produceDiagnostics:*/ true);
errors = checker.getDiagnostics();
var emitResult = checker.emitFiles();
var emitResult = program.emitFiles();
errors = ts.concatenate(errors, emitResult.diagnostics);
sourceMapData = emitResult.sourceMaps;

Expand Down
12 changes: 6 additions & 6 deletions src/harness/test262Runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class Test262BaselineRunner extends RunnerBase {
filename: string;
compilerResult: Harness.Compiler.CompilerResult;
inputFiles: { unitName: string; content: string }[];
checker: ts.TypeChecker;
program: ts.Program;
};

before(() => {
Expand All @@ -46,12 +46,12 @@ class Test262BaselineRunner extends RunnerBase {
filename: testFilename,
inputFiles: inputFiles,
compilerResult: undefined,
checker: undefined,
program: undefined,
};

Harness.Compiler.getCompiler().compileFiles([Test262BaselineRunner.helperFile].concat(inputFiles), /*otherFiles*/ [], (compilerResult, checker) => {
Harness.Compiler.getCompiler().compileFiles([Test262BaselineRunner.helperFile].concat(inputFiles), /*otherFiles*/ [], (compilerResult, program) => {
testState.compilerResult = compilerResult;
testState.checker = checker;
testState.program = program;
}, /*settingsCallback*/ undefined, Test262BaselineRunner.options);
});

Expand All @@ -78,13 +78,13 @@ class Test262BaselineRunner extends RunnerBase {
});

it('satisfies invariants', () => {
var sourceFile = testState.checker.getProgram().getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
var sourceFile = testState.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
Utils.assertInvariants(sourceFile, /*parent:*/ undefined);
});

it('has the expected AST',() => {
Harness.Baseline.runBaseline('has the expected AST', testState.filename + '.AST.txt',() => {
var sourceFile = testState.checker.getProgram().getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
var sourceFile = testState.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
return Utils.sourceFileToJSON(sourceFile);
}, false, Test262BaselineRunner.baselineOptions);
});
Expand Down
9 changes: 7 additions & 2 deletions src/harness/typeWriter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,16 @@ class TypeWriterWalker {
results: TypeWriterResult[];
currentSourceFile: ts.SourceFile;

constructor(public checker: ts.TypeChecker) {
private checker: ts.TypeChecker;

constructor(private program: ts.Program) {
// Consider getting both the diagnostics checker and the non-diagnostics checker to verify
// they are consistent.
this.checker = program.getTypeChecker(/*produceDiagnostics:*/ true);
}

public getTypes(fileName: string): TypeWriterResult[] {
var sourceFile = this.checker.getProgram().getSourceFile(fileName);
var sourceFile = this.program.getSourceFile(fileName);
this.currentSourceFile = sourceFile;
this.results = [];
this.visitNode(sourceFile);
Expand Down
Loading