commit
5ecc28834e
3
Jakefile
3
Jakefile
|
@ -39,6 +39,7 @@ var compilerSources = [
|
|||
"binder.ts",
|
||||
"checker.ts",
|
||||
"emitter.ts",
|
||||
"program.ts",
|
||||
"commandLineParser.ts",
|
||||
"tsc.ts",
|
||||
"diagnosticInformationMap.generated.ts"
|
||||
|
@ -56,6 +57,7 @@ var servicesSources = [
|
|||
"binder.ts",
|
||||
"checker.ts",
|
||||
"emitter.ts",
|
||||
"program.ts",
|
||||
"diagnosticInformationMap.generated.ts"
|
||||
].map(function (f) {
|
||||
return path.join(compilerDirectory, f);
|
||||
|
@ -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",
|
||||
];
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -1,21 +1,11 @@
|
|||
/// <reference path="types.ts"/>
|
||||
/// <reference path="core.ts"/>
|
||||
/// <reference path="scanner.ts"/>
|
||||
/// <reference path="parser.ts"/>
|
||||
/// <reference path="binder.ts"/>
|
||||
/// <reference path="emitter.ts"/>
|
||||
/// <reference path="utilities.ts"/>
|
||||
|
||||
module ts {
|
||||
var nextSymbolId = 1;
|
||||
var nextNodeId = 1;
|
||||
var nextMergeId = 1;
|
||||
var nextMergeId = 1;
|
||||
|
||||
/// fullTypeCheck denotes if this instance of the typechecker will be used to get semantic diagnostics.
|
||||
/// If fullTypeCheck === true, then the typechecker should do every possible check to produce all errors
|
||||
/// If fullTypeCheck === false, the typechecker can take shortcuts and skip checks that only produce errors.
|
||||
/// NOTE: checks that somehow affect decisions being made during typechecking should be executed in both cases.
|
||||
export function createTypeChecker(program: Program, fullTypeCheck: boolean): TypeChecker {
|
||||
export function createTypeChecker(host: TypeCheckerHost, produceDiagnostics: boolean): TypeChecker {
|
||||
var Symbol = objectAllocator.getSymbolConstructor();
|
||||
var Type = objectAllocator.getTypeConstructor();
|
||||
var Signature = objectAllocator.getSignatureConstructor();
|
||||
|
@ -25,19 +15,17 @@ module ts {
|
|||
var emptyArray: any[] = [];
|
||||
var emptySymbols: SymbolTable = {};
|
||||
|
||||
var compilerOptions = program.getCompilerOptions();
|
||||
var compilerOptions = host.getCompilerOptions();
|
||||
var emitResolver = createResolver();
|
||||
|
||||
var checker: TypeChecker = {
|
||||
getProgram: () => program,
|
||||
getNodeCount: () => sum(program.getSourceFiles(), "nodeCount"),
|
||||
getIdentifierCount: () => sum(program.getSourceFiles(), "identifierCount"),
|
||||
getSymbolCount: () => sum(program.getSourceFiles(), "symbolCount"),
|
||||
getNodeCount: () => sum(host.getSourceFiles(), "nodeCount"),
|
||||
getIdentifierCount: () => sum(host.getSourceFiles(), "identifierCount"),
|
||||
getSymbolCount: () => sum(host.getSourceFiles(), "symbolCount"),
|
||||
getTypeCount: () => typeCount,
|
||||
isUndefinedSymbol: symbol => symbol === undefinedSymbol,
|
||||
isArgumentsSymbol: symbol => symbol === argumentsSymbol,
|
||||
emitFiles: invokeEmitter,
|
||||
getDiagnostics,
|
||||
getDeclarationDiagnostics,
|
||||
getGlobalDiagnostics,
|
||||
getTypeOfSymbolAtLocation,
|
||||
getDeclaredTypeOfSymbol,
|
||||
|
@ -63,8 +51,7 @@ module ts {
|
|||
getSignatureFromDeclaration,
|
||||
isImplementationOfOverload,
|
||||
getAliasedSymbol: resolveImport,
|
||||
hasEarlyErrors,
|
||||
isEmitBlocked,
|
||||
getEmitResolver: () => emitResolver,
|
||||
};
|
||||
|
||||
var undefinedSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "undefined");
|
||||
|
@ -284,7 +271,7 @@ module ts {
|
|||
return true;
|
||||
}
|
||||
|
||||
var sourceFiles = program.getSourceFiles();
|
||||
var sourceFiles = host.getSourceFiles();
|
||||
return sourceFiles.indexOf(file1) <= sourceFiles.indexOf(file2);
|
||||
}
|
||||
|
||||
|
@ -531,7 +518,7 @@ module ts {
|
|||
}
|
||||
while (true) {
|
||||
var filename = normalizePath(combinePaths(searchPath, moduleName));
|
||||
var sourceFile = program.getSourceFile(filename + ".ts") || program.getSourceFile(filename + ".d.ts");
|
||||
var sourceFile = host.getSourceFile(filename + ".ts") || host.getSourceFile(filename + ".d.ts");
|
||||
if (sourceFile || isRelative) break;
|
||||
var parentPath = getDirectoryPath(searchPath);
|
||||
if (parentPath === searchPath) break;
|
||||
|
@ -3435,7 +3422,7 @@ module ts {
|
|||
if (containingMessageChain) {
|
||||
errorInfo = concatenateDiagnosticMessageChains(containingMessageChain, errorInfo);
|
||||
}
|
||||
addDiagnostic(createDiagnosticForNodeFromMessageChain(errorNode, errorInfo, program.getCompilerHost().getNewLine()));
|
||||
addDiagnostic(createDiagnosticForNodeFromMessageChain(errorNode, errorInfo, host.getCompilerHost().getNewLine()));
|
||||
}
|
||||
return result !== Ternary.False;
|
||||
|
||||
|
@ -4208,7 +4195,7 @@ module ts {
|
|||
}
|
||||
|
||||
function reportErrorsFromWidening(declaration: Declaration, type: Type) {
|
||||
if (fullTypeCheck && compilerOptions.noImplicitAny && type.flags & TypeFlags.Unwidened) {
|
||||
if (produceDiagnostics && compilerOptions.noImplicitAny && type.flags & TypeFlags.Unwidened) {
|
||||
// Report implicit any error within type if possible, otherwise report error on declaration
|
||||
if (!reportWideningErrorsInType(type)) {
|
||||
reportImplicitAnyError(declaration, type);
|
||||
|
@ -6038,7 +6025,7 @@ module ts {
|
|||
// Pick the first candidate that matches the arity. This way we can get a contextual type for cases like:
|
||||
// declare function f(a: { xa: number; xb: number; });
|
||||
// f({ |
|
||||
if (!fullTypeCheck) {
|
||||
if (!produceDiagnostics) {
|
||||
for (var i = 0, n = candidates.length; i < n; i++) {
|
||||
if (hasCorrectArity(node, args, candidates[i])) {
|
||||
return candidates[i];
|
||||
|
@ -6343,7 +6330,7 @@ module ts {
|
|||
function checkTypeAssertion(node: TypeAssertion): Type {
|
||||
var exprType = checkExpression(node.expression);
|
||||
var targetType = getTypeFromTypeNode(node.type);
|
||||
if (fullTypeCheck && targetType !== unknownType) {
|
||||
if (produceDiagnostics && targetType !== unknownType) {
|
||||
var widenedType = getWidenedType(exprType);
|
||||
if (!(isTypeAssignableTo(targetType, widenedType))) {
|
||||
checkTypeAssignableTo(exprType, targetType, node, Diagnostics.Neither_type_0_nor_type_1_is_assignable_to_the_other);
|
||||
|
@ -6429,7 +6416,7 @@ module ts {
|
|||
// must have at least one return statement somewhere in its body.
|
||||
// An exception to this rule is if the function implementation consists of a single 'throw' statement.
|
||||
function checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(func: FunctionLikeDeclaration, returnType: Type): void {
|
||||
if (!fullTypeCheck) {
|
||||
if (!produceDiagnostics) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -6501,7 +6488,7 @@ module ts {
|
|||
}
|
||||
}
|
||||
|
||||
if (fullTypeCheck && node.kind !== SyntaxKind.MethodDeclaration && node.kind !== SyntaxKind.MethodSignature) {
|
||||
if (produceDiagnostics && node.kind !== SyntaxKind.MethodDeclaration && node.kind !== SyntaxKind.MethodSignature) {
|
||||
checkCollisionWithCapturedSuperVariable(node, (<FunctionExpression>node).name);
|
||||
checkCollisionWithCapturedThisVariable(node,(<FunctionExpression>node).name);
|
||||
}
|
||||
|
@ -6950,7 +6937,7 @@ module ts {
|
|||
}
|
||||
|
||||
function checkAssignmentOperator(valueType: Type): void {
|
||||
if (fullTypeCheck && operator >= SyntaxKind.FirstAssignment && operator <= SyntaxKind.LastAssignment) {
|
||||
if (produceDiagnostics && operator >= SyntaxKind.FirstAssignment && operator <= SyntaxKind.LastAssignment) {
|
||||
// TypeScript 1.0 spec (April 2014): 4.17
|
||||
// An assignment of the form
|
||||
// VarExpr = ValueExpr
|
||||
|
@ -7162,7 +7149,7 @@ module ts {
|
|||
}
|
||||
|
||||
checkSourceElement(node.constraint);
|
||||
if (fullTypeCheck) {
|
||||
if (produceDiagnostics) {
|
||||
checkTypeParameterHasIllegalReferencesInConstraint(node);
|
||||
checkTypeNameIsReserved(node.name, Diagnostics.Type_parameter_name_cannot_be_0);
|
||||
}
|
||||
|
@ -7212,7 +7199,7 @@ module ts {
|
|||
if (node.type) {
|
||||
checkSourceElement(node.type);
|
||||
}
|
||||
if (fullTypeCheck) {
|
||||
if (produceDiagnostics) {
|
||||
checkCollisionWithArgumentsInGeneratedCode(node);
|
||||
if (compilerOptions.noImplicitAny && !node.type) {
|
||||
switch (node.kind) {
|
||||
|
@ -7307,7 +7294,7 @@ module ts {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!fullTypeCheck) {
|
||||
if (!produceDiagnostics) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -7375,10 +7362,10 @@ module ts {
|
|||
}
|
||||
|
||||
function checkAccessorDeclaration(node: AccessorDeclaration) {
|
||||
// Grammar checking accessors
|
||||
checkGrammarDisallowedModifiersInBlockOrObjectLiteralExpression(node) || checkGrammarFunctionLikeDeclaration(node) || checkGrammarAccessor(node) || checkGrammarComputedPropertyName(node.name);
|
||||
if (produceDiagnostics) {
|
||||
// Grammar checking accessors
|
||||
checkGrammarFunctionLikeDeclaration(node) || checkGrammarAccessor(node) || checkGrammarComputedPropertyName(node.name);
|
||||
|
||||
if (fullTypeCheck) {
|
||||
if (node.kind === SyntaxKind.GetAccessor) {
|
||||
if (!isInAmbientContext(node) && nodeIsPresent(node.body) && !(bodyContainsAReturnStatement(<Block>node.body) || bodyContainsSingleThrowStatement(<Block>node.body))) {
|
||||
error(node.name, Diagnostics.A_get_accessor_must_return_a_value_or_consist_of_a_single_throw_statement);
|
||||
|
@ -7424,7 +7411,7 @@ module ts {
|
|||
for (var i = 0; i < len; i++) {
|
||||
checkSourceElement(node.typeArguments[i]);
|
||||
var constraint = getConstraintOfTypeParameter((<TypeReference>type).target.typeParameters[i]);
|
||||
if (fullTypeCheck && constraint) {
|
||||
if (produceDiagnostics && constraint) {
|
||||
var typeArgument = (<TypeReference>type).typeArguments[i];
|
||||
checkTypeAssignableTo(typeArgument, constraint, node, Diagnostics.Type_0_does_not_satisfy_the_constraint_1);
|
||||
}
|
||||
|
@ -7438,7 +7425,7 @@ module ts {
|
|||
|
||||
function checkTypeLiteral(node: TypeLiteralNode) {
|
||||
forEach(node.members, checkSourceElement);
|
||||
if (fullTypeCheck) {
|
||||
if (produceDiagnostics) {
|
||||
var type = getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node);
|
||||
checkIndexConstraints(type);
|
||||
checkTypeForDuplicateIndexSignatures(node);
|
||||
|
@ -7468,7 +7455,7 @@ module ts {
|
|||
}
|
||||
|
||||
function checkSpecializedSignatureDeclaration(signatureDeclarationNode: SignatureDeclaration): void {
|
||||
if (!fullTypeCheck) {
|
||||
if (!produceDiagnostics) {
|
||||
return;
|
||||
}
|
||||
var signature = getSignatureFromDeclaration(signatureDeclarationNode);
|
||||
|
@ -7524,7 +7511,7 @@ module ts {
|
|||
}
|
||||
|
||||
function checkFunctionOrConstructorSymbol(symbol: Symbol): void {
|
||||
if (!fullTypeCheck) {
|
||||
if (!produceDiagnostics) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -7734,7 +7721,7 @@ module ts {
|
|||
}
|
||||
|
||||
function checkExportsOnMergedDeclarations(node: Node): void {
|
||||
if (!fullTypeCheck) {
|
||||
if (!produceDiagnostics) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -7808,13 +7795,12 @@ module ts {
|
|||
}
|
||||
|
||||
function checkFunctionDeclaration(node: FunctionDeclaration): void {
|
||||
// Grammar Checking, check signature of function declaration as checkFunctionLikeDeclaration call checkGarmmarFunctionLikeDeclaration
|
||||
checkFunctionLikeDeclaration(node);
|
||||
if (produceDiagnostics) {
|
||||
checkFunctionLikeDeclaration(node) ||
|
||||
checkGrammarDisallowedModifiersInBlockOrObjectLiteralExpression(node) ||
|
||||
checkGrammarFunctionName(node.name) ||
|
||||
checkGrammarForGenerator(node);
|
||||
|
||||
//Grammar check other component of the functionDeclaration
|
||||
checkGrammarDisallowedModifiersInBlockOrObjectLiteralExpression(node) || checkGrammarFunctionName(node.name) || checkGrammarForGenerator(node);
|
||||
|
||||
if (fullTypeCheck) {
|
||||
checkCollisionWithCapturedSuperVariable(node, node.name);
|
||||
checkCollisionWithCapturedThisVariable(node, node.name);
|
||||
checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
|
||||
|
@ -8326,7 +8312,7 @@ module ts {
|
|||
}
|
||||
}
|
||||
|
||||
if (fullTypeCheck && clause.kind === SyntaxKind.CaseClause) {
|
||||
if (produceDiagnostics && clause.kind === SyntaxKind.CaseClause) {
|
||||
var caseClause = <CaseClause>clause;
|
||||
// TypeScript 1.0 spec (April 2014):5.9
|
||||
// In a 'switch' statement, each 'case' expression must be of a type that is assignable to or from the type of the 'switch' expression.
|
||||
|
@ -8486,7 +8472,7 @@ module ts {
|
|||
var node = typeParameterDeclarations[i];
|
||||
checkTypeParameter(node);
|
||||
|
||||
if (fullTypeCheck) {
|
||||
if (produceDiagnostics) {
|
||||
for (var j = 0; j < i; j++) {
|
||||
if (typeParameterDeclarations[j].symbol === node.symbol) {
|
||||
error(node.name, Diagnostics.Duplicate_identifier_0, declarationNameToString(node.name));
|
||||
|
@ -8515,7 +8501,7 @@ module ts {
|
|||
checkTypeReference(baseTypeNode);
|
||||
}
|
||||
if (type.baseTypes.length) {
|
||||
if (fullTypeCheck) {
|
||||
if (produceDiagnostics) {
|
||||
var baseType = type.baseTypes[0];
|
||||
checkTypeAssignableTo(type, baseType, node.name, Diagnostics.Class_0_incorrectly_extends_base_class_1);
|
||||
var staticBaseType = getTypeOfSymbol(baseType.symbol);
|
||||
|
@ -8536,7 +8522,7 @@ module ts {
|
|||
if (implementedTypeNodes) {
|
||||
forEach(implementedTypeNodes, typeRefNode => {
|
||||
checkTypeReference(typeRefNode);
|
||||
if (fullTypeCheck) {
|
||||
if (produceDiagnostics) {
|
||||
var t = getTypeFromTypeReferenceNode(typeRefNode);
|
||||
if (t !== unknownType) {
|
||||
var declaredType = (t.flags & TypeFlags.Reference) ? (<TypeReference>t).target : t;
|
||||
|
@ -8552,7 +8538,7 @@ module ts {
|
|||
}
|
||||
|
||||
forEach(node.members, checkSourceElement);
|
||||
if (fullTypeCheck) {
|
||||
if (produceDiagnostics) {
|
||||
checkIndexConstraints(type);
|
||||
checkTypeForDuplicateIndexSignatures(node);
|
||||
}
|
||||
|
@ -8694,7 +8680,7 @@ module ts {
|
|||
|
||||
var errorInfo = chainDiagnosticMessages(undefined, Diagnostics.Named_properties_0_of_types_1_and_2_are_not_identical, prop.name, typeName1, typeName2);
|
||||
errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Interface_0_cannot_simultaneously_extend_types_1_and_2, typeToString(type), typeName1, typeName2);
|
||||
addDiagnostic(createDiagnosticForNodeFromMessageChain(typeNode, errorInfo, program.getCompilerHost().getNewLine()));
|
||||
addDiagnostic(createDiagnosticForNodeFromMessageChain(typeNode, errorInfo, host.getCompilerHost().getNewLine()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8708,7 +8694,7 @@ module ts {
|
|||
checkGrammarModifiers(node) || checkGrammarInterfaceDeclaration(node);
|
||||
|
||||
checkTypeParameters(node.typeParameters);
|
||||
if (fullTypeCheck) {
|
||||
if (produceDiagnostics) {
|
||||
checkTypeNameIsReserved(node.name, Diagnostics.Interface_name_cannot_be_0);
|
||||
|
||||
checkExportsOnMergedDeclarations(node);
|
||||
|
@ -8735,7 +8721,7 @@ module ts {
|
|||
forEach(getInterfaceBaseTypeNodes(node), checkTypeReference);
|
||||
forEach(node.members, checkSourceElement);
|
||||
|
||||
if (fullTypeCheck) {
|
||||
if (produceDiagnostics) {
|
||||
checkTypeForDuplicateIndexSignatures(node);
|
||||
}
|
||||
}
|
||||
|
@ -8907,13 +8893,13 @@ module ts {
|
|||
}
|
||||
|
||||
function checkEnumDeclaration(node: EnumDeclaration) {
|
||||
// Grammar checking
|
||||
checkGrammarModifiers(node) || checkGrammarEnumDeclaration(node);
|
||||
|
||||
if (!fullTypeCheck) {
|
||||
if (!produceDiagnostics) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Grammar checking
|
||||
checkGrammarModifiers(node) || checkGrammarEnumDeclaration(node);
|
||||
|
||||
checkTypeNameIsReserved(node.name, Diagnostics.Enum_name_cannot_be_0);
|
||||
checkCollisionWithCapturedThisVariable(node, node.name);
|
||||
checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
|
||||
|
@ -8977,28 +8963,28 @@ module ts {
|
|||
}
|
||||
|
||||
function checkModuleDeclaration(node: ModuleDeclaration) {
|
||||
// Grammar checking
|
||||
if (!checkGrammarModifiers(node)) {
|
||||
if (!isInAmbientContext(node) && node.name.kind === SyntaxKind.StringLiteral) {
|
||||
grammarErrorOnNode(node.name, Diagnostics.Only_ambient_modules_can_use_quoted_names);
|
||||
}
|
||||
else if (node.name.kind === SyntaxKind.Identifier && node.body.kind === SyntaxKind.ModuleBlock) {
|
||||
var statements = (<ModuleBlock>node.body).statements;
|
||||
for (var i = 0, n = statements.length; i < n; i++) {
|
||||
var statement = statements[i];
|
||||
if (produceDiagnostics) {
|
||||
// Grammar checking
|
||||
if (!checkGrammarModifiers(node)) {
|
||||
if (!isInAmbientContext(node) && node.name.kind === SyntaxKind.StringLiteral) {
|
||||
grammarErrorOnNode(node.name, Diagnostics.Only_ambient_modules_can_use_quoted_names);
|
||||
}
|
||||
else if (node.name.kind === SyntaxKind.Identifier && node.body.kind === SyntaxKind.ModuleBlock) {
|
||||
var statements = (<ModuleBlock>node.body).statements;
|
||||
for (var i = 0, n = statements.length; i < n; i++) {
|
||||
var statement = statements[i];
|
||||
|
||||
if (statement.kind === SyntaxKind.ExportAssignment) {
|
||||
// Export assignments are not allowed in an internal module
|
||||
grammarErrorOnNode(statement, Diagnostics.An_export_assignment_cannot_be_used_in_an_internal_module);
|
||||
}
|
||||
else if (isExternalModuleImportDeclaration(statement)) {
|
||||
grammarErrorOnNode(getExternalModuleImportDeclarationExpression(statement), Diagnostics.Import_declarations_in_an_internal_module_cannot_reference_an_external_module);
|
||||
if (statement.kind === SyntaxKind.ExportAssignment) {
|
||||
// Export assignments are not allowed in an internal module
|
||||
grammarErrorOnNode(statement, Diagnostics.An_export_assignment_cannot_be_used_in_an_internal_module);
|
||||
}
|
||||
else if (isExternalModuleImportDeclaration(statement)) {
|
||||
grammarErrorOnNode(getExternalModuleImportDeclarationExpression(statement), Diagnostics.Import_declarations_in_an_internal_module_cannot_reference_an_external_module);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fullTypeCheck) {
|
||||
checkCollisionWithCapturedThisVariable(node, node.name);
|
||||
checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
|
||||
checkExportsOnMergedDeclarations(node);
|
||||
|
@ -9338,7 +9324,7 @@ module ts {
|
|||
}
|
||||
|
||||
function getSortedDiagnostics(): Diagnostic[]{
|
||||
Debug.assert(fullTypeCheck, "diagnostics are available only in the full typecheck mode");
|
||||
Debug.assert(produceDiagnostics, "diagnostics are available only in the full typecheck mode");
|
||||
|
||||
if (diagnosticsModified) {
|
||||
diagnostics.sort(compareDiagnostics);
|
||||
|
@ -9348,23 +9334,25 @@ module ts {
|
|||
return diagnostics;
|
||||
}
|
||||
|
||||
function getDiagnostics(sourceFile?: SourceFile): Diagnostic[]{
|
||||
function getDiagnostics(sourceFile?: SourceFile): Diagnostic[] {
|
||||
throwIfNonDiagnosticsProducing();
|
||||
if (sourceFile) {
|
||||
checkSourceFile(sourceFile);
|
||||
return filter(getSortedDiagnostics(), d => d.file === sourceFile);
|
||||
}
|
||||
forEach(program.getSourceFiles(), checkSourceFile);
|
||||
forEach(host.getSourceFiles(), checkSourceFile);
|
||||
return getSortedDiagnostics();
|
||||
}
|
||||
|
||||
function getDeclarationDiagnostics(targetSourceFile: SourceFile): Diagnostic[] {
|
||||
var resolver = createResolver();
|
||||
checkSourceFile(targetSourceFile);
|
||||
return ts.getDeclarationDiagnostics(program, resolver, targetSourceFile);
|
||||
function getGlobalDiagnostics(): Diagnostic[]{
|
||||
throwIfNonDiagnosticsProducing();
|
||||
return filter(getSortedDiagnostics(), d => !d.file);
|
||||
}
|
||||
|
||||
function getGlobalDiagnostics(): Diagnostic[] {
|
||||
return filter(getSortedDiagnostics(), d => !d.file);
|
||||
function throwIfNonDiagnosticsProducing() {
|
||||
if (!produceDiagnostics) {
|
||||
throw new Error("Trying to get diagnostics from a type checker that does not produce them.");
|
||||
}
|
||||
}
|
||||
|
||||
// Language service support
|
||||
|
@ -9869,16 +9857,6 @@ module ts {
|
|||
return getDiagnostics(sourceFile).length > 0 || getGlobalDiagnostics().length > 0;
|
||||
}
|
||||
|
||||
function isEmitBlocked(sourceFile?: SourceFile): boolean {
|
||||
return program.getDiagnostics(sourceFile).length !== 0 ||
|
||||
hasEarlyErrors(sourceFile) ||
|
||||
(compilerOptions.noEmitOnError && getDiagnostics(sourceFile).length !== 0);
|
||||
}
|
||||
|
||||
function hasEarlyErrors(sourceFile?: SourceFile): boolean {
|
||||
return forEach(getDiagnostics(sourceFile), d => d.isEarly);
|
||||
}
|
||||
|
||||
function isImportResolvedToValue(symbol: Symbol): boolean {
|
||||
var target = resolveImport(symbol);
|
||||
// const enums and modules that contain only const enums are not considered values from the emit perespective
|
||||
|
@ -9966,7 +9944,6 @@ module ts {
|
|||
|
||||
function createResolver(): EmitResolver {
|
||||
return {
|
||||
getProgram: () => program,
|
||||
getLocalNameOfContainer,
|
||||
getExpressionNamePrefix,
|
||||
getExportAssignmentName,
|
||||
|
@ -9975,7 +9952,6 @@ module ts {
|
|||
getEnumMemberValue,
|
||||
isTopLevelValueImportWithEntityName,
|
||||
hasSemanticErrors,
|
||||
isEmitBlocked,
|
||||
isDeclarationVisible,
|
||||
isImplementationOfOverload,
|
||||
writeTypeOfDeclaration,
|
||||
|
@ -9987,19 +9963,14 @@ module ts {
|
|||
};
|
||||
}
|
||||
|
||||
function invokeEmitter(targetSourceFile?: SourceFile) {
|
||||
var resolver = createResolver();
|
||||
return emitFiles(resolver, targetSourceFile);
|
||||
}
|
||||
|
||||
function initializeTypeChecker() {
|
||||
// Bind all source files and propagate errors
|
||||
forEach(program.getSourceFiles(), file => {
|
||||
forEach(host.getSourceFiles(), file => {
|
||||
bindSourceFile(file);
|
||||
forEach(file.semanticDiagnostics, addDiagnostic);
|
||||
});
|
||||
// Initialize global symbol table
|
||||
forEach(program.getSourceFiles(), file => {
|
||||
forEach(host.getSourceFiles(), file => {
|
||||
if (!isExternalModule(file)) {
|
||||
extendSymbolTable(globals, file.locals);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
/// <reference path="types.ts"/>
|
||||
/// <reference path="core.ts"/>
|
||||
/// <reference path="scanner.ts"/>
|
||||
/// <reference path="parser.ts"/>
|
||||
/// <reference path="binder.ts"/>
|
||||
/// <reference path="checker.ts"/>
|
||||
|
||||
module ts {
|
||||
interface EmitTextWriter {
|
||||
|
@ -316,17 +312,16 @@ module ts {
|
|||
};
|
||||
}
|
||||
|
||||
function getSourceFilePathInNewDir(sourceFile: SourceFile, program: Program, newDirPath: string) {
|
||||
var compilerHost = program.getCompilerHost();
|
||||
var sourceFilePath = getNormalizedAbsolutePath(sourceFile.filename, compilerHost.getCurrentDirectory());
|
||||
sourceFilePath = sourceFilePath.replace(program.getCommonSourceDirectory(), "");
|
||||
function getSourceFilePathInNewDir(sourceFile: SourceFile, host: EmitHost, newDirPath: string) {
|
||||
var sourceFilePath = getNormalizedAbsolutePath(sourceFile.filename, host.getCurrentDirectory());
|
||||
sourceFilePath = sourceFilePath.replace(host.getCommonSourceDirectory(), "");
|
||||
return combinePaths(newDirPath, sourceFilePath);
|
||||
}
|
||||
|
||||
function getOwnEmitOutputFilePath(sourceFile: SourceFile, program: Program, extension: string){
|
||||
var compilerOptions = program.getCompilerOptions();
|
||||
function getOwnEmitOutputFilePath(sourceFile: SourceFile, host: EmitHost, extension: string){
|
||||
var compilerOptions = host.getCompilerOptions();
|
||||
if (compilerOptions.outDir) {
|
||||
var emitOutputFilePathWithoutExtension = removeFileExtension(getSourceFilePathInNewDir(sourceFile, program, compilerOptions.outDir));
|
||||
var emitOutputFilePathWithoutExtension = removeFileExtension(getSourceFilePathInNewDir(sourceFile, host, compilerOptions.outDir));
|
||||
}
|
||||
else {
|
||||
var emitOutputFilePathWithoutExtension = removeFileExtension(sourceFile.filename);
|
||||
|
@ -335,16 +330,15 @@ module ts {
|
|||
return emitOutputFilePathWithoutExtension + extension;
|
||||
}
|
||||
|
||||
function writeFile(compilerHost: CompilerHost, diagnostics: Diagnostic[], filename: string, data: string, writeByteOrderMark: boolean) {
|
||||
compilerHost.writeFile(filename, data, writeByteOrderMark, hostErrorMessage => {
|
||||
function writeFile(host: EmitHost, diagnostics: Diagnostic[], filename: string, data: string, writeByteOrderMark: boolean) {
|
||||
host.writeFile(filename, data, writeByteOrderMark, hostErrorMessage => {
|
||||
diagnostics.push(createCompilerDiagnostic(Diagnostics.Could_not_write_file_0_Colon_1, filename, hostErrorMessage));
|
||||
});
|
||||
}
|
||||
|
||||
function emitDeclarations(program: Program, resolver: EmitResolver, diagnostics: Diagnostic[], jsFilePath: string, root?: SourceFile): DeclarationEmit {
|
||||
var newLine = program.getCompilerHost().getNewLine();
|
||||
var compilerOptions = program.getCompilerOptions();
|
||||
var compilerHost = program.getCompilerHost();
|
||||
function emitDeclarations(host: EmitHost, resolver: EmitResolver, diagnostics: Diagnostic[], jsFilePath: string, root?: SourceFile): DeclarationEmit {
|
||||
var newLine = host.getNewLine();
|
||||
var compilerOptions = host.getCompilerOptions();
|
||||
|
||||
var write: (s: string) => void;
|
||||
var writeLine: () => void;
|
||||
|
@ -1400,14 +1394,14 @@ module ts {
|
|||
var declFileName = referencedFile.flags & NodeFlags.DeclarationFile
|
||||
? referencedFile.filename // Declaration file, use declaration file name
|
||||
: shouldEmitToOwnFile(referencedFile, compilerOptions)
|
||||
? getOwnEmitOutputFilePath(referencedFile, program, ".d.ts") // Own output file so get the .d.ts file
|
||||
: removeFileExtension(compilerOptions.out) + ".d.ts";// Global out file
|
||||
? getOwnEmitOutputFilePath(referencedFile, host, ".d.ts") // Own output file so get the .d.ts file
|
||||
: removeFileExtension(compilerOptions.out) + ".d.ts";// Global out file
|
||||
|
||||
declFileName = getRelativePathToDirectoryOrUrl(
|
||||
getDirectoryPath(normalizeSlashes(jsFilePath)),
|
||||
declFileName,
|
||||
compilerHost.getCurrentDirectory(),
|
||||
compilerHost.getCanonicalFileName,
|
||||
host.getCurrentDirectory(),
|
||||
host.getCanonicalFileName,
|
||||
/*isAbsolutePathAnUrl*/ false);
|
||||
|
||||
referencePathsOutput += "/// <reference path=\"" + declFileName + "\" />" + newLine;
|
||||
|
@ -1418,7 +1412,7 @@ module ts {
|
|||
if (!compilerOptions.noResolve) {
|
||||
var addedGlobalFileReference = false;
|
||||
forEach(root.referencedFiles, fileReference => {
|
||||
var referencedFile = tryResolveScriptReference(program, root, fileReference);
|
||||
var referencedFile = tryResolveScriptReference(host, root, fileReference);
|
||||
|
||||
// All the references that are not going to be part of same file
|
||||
if (referencedFile && ((referencedFile.flags & NodeFlags.DeclarationFile) || // This is a declare file reference
|
||||
|
@ -1438,12 +1432,12 @@ module ts {
|
|||
else {
|
||||
// Emit references corresponding to this file
|
||||
var emittedReferencedFiles: SourceFile[] = [];
|
||||
forEach(program.getSourceFiles(), sourceFile => {
|
||||
forEach(host.getSourceFiles(), sourceFile => {
|
||||
if (!isExternalModuleOrDeclarationFile(sourceFile)) {
|
||||
// Check what references need to be added
|
||||
if (!compilerOptions.noResolve) {
|
||||
forEach(sourceFile.referencedFiles, fileReference => {
|
||||
var referencedFile = tryResolveScriptReference(program, sourceFile, fileReference);
|
||||
var referencedFile = tryResolveScriptReference(host, sourceFile, fileReference);
|
||||
|
||||
// If the reference file is a declaration file or an external module, emit that reference
|
||||
if (referencedFile && (isExternalModuleOrDeclarationFile(referencedFile) &&
|
||||
|
@ -1468,21 +1462,31 @@ module ts {
|
|||
}
|
||||
}
|
||||
|
||||
export function getDeclarationDiagnostics(program: Program, resolver: EmitResolver, targetSourceFile: SourceFile): Diagnostic[] {
|
||||
export interface EmitHost extends ScriptReferenceHost {
|
||||
getSourceFiles(): SourceFile[];
|
||||
isEmitBlocked(sourceFile?: SourceFile): boolean;
|
||||
|
||||
getCommonSourceDirectory(): string;
|
||||
getCanonicalFileName(fileName: string): string;
|
||||
getNewLine(): string;
|
||||
|
||||
writeFile(filename: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void): void;
|
||||
}
|
||||
|
||||
export function getDeclarationDiagnostics(host: EmitHost, resolver: EmitResolver, targetSourceFile: SourceFile): Diagnostic[] {
|
||||
var diagnostics: Diagnostic[] = [];
|
||||
var jsFilePath = getOwnEmitOutputFilePath(targetSourceFile, program, ".js");
|
||||
emitDeclarations(program, resolver, diagnostics, jsFilePath, targetSourceFile);
|
||||
var jsFilePath = getOwnEmitOutputFilePath(targetSourceFile, host, ".js");
|
||||
emitDeclarations(host, resolver, diagnostics, jsFilePath, targetSourceFile);
|
||||
return diagnostics;
|
||||
}
|
||||
|
||||
// targetSourceFile is when users only want one file in entire project to be emitted. This is used in compilerOnSave feature
|
||||
export function emitFiles(resolver: EmitResolver, targetSourceFile?: SourceFile): EmitResult {
|
||||
var program = resolver.getProgram();
|
||||
var compilerHost = program.getCompilerHost();
|
||||
var compilerOptions = program.getCompilerOptions();
|
||||
export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile?: SourceFile): EmitResult {
|
||||
// var program = resolver.getProgram();
|
||||
var compilerOptions = host.getCompilerOptions();
|
||||
var sourceMapDataList: SourceMapData[] = compilerOptions.sourceMap ? [] : undefined;
|
||||
var diagnostics: Diagnostic[] = [];
|
||||
var newLine = program.getCompilerHost().getNewLine();
|
||||
var newLine = host.getNewLine();
|
||||
|
||||
function emitJavaScript(jsFilePath: string, root?: SourceFile) {
|
||||
var writer = createTextWriter(newLine);
|
||||
|
@ -1704,12 +1708,12 @@ module ts {
|
|||
// Add the file to tsFilePaths
|
||||
// If sourceroot option: Use the relative path corresponding to the common directory path
|
||||
// otherwise source locations relative to map file location
|
||||
var sourcesDirectoryPath = compilerOptions.sourceRoot ? program.getCommonSourceDirectory() : sourceMapDir;
|
||||
var sourcesDirectoryPath = compilerOptions.sourceRoot ? host.getCommonSourceDirectory() : sourceMapDir;
|
||||
|
||||
sourceMapData.sourceMapSources.push(getRelativePathToDirectoryOrUrl(sourcesDirectoryPath,
|
||||
node.filename,
|
||||
compilerHost.getCurrentDirectory(),
|
||||
compilerHost.getCanonicalFileName,
|
||||
host.getCurrentDirectory(),
|
||||
host.getCanonicalFileName,
|
||||
/*isAbsolutePathAnUrl*/ true));
|
||||
sourceMapSourceIndex = sourceMapData.sourceMapSources.length - 1;
|
||||
|
||||
|
@ -1805,7 +1809,7 @@ module ts {
|
|||
function writeJavaScriptAndSourceMapFile(emitOutput: string, writeByteOrderMark: boolean) {
|
||||
// Write source map file
|
||||
encodeLastRecordedSourceMapSpan();
|
||||
writeFile(compilerHost, diagnostics, sourceMapData.sourceMapFilePath, serializeSourceMapContents(
|
||||
writeFile(host, diagnostics, sourceMapData.sourceMapFilePath, serializeSourceMapContents(
|
||||
3,
|
||||
sourceMapData.sourceMapFile,
|
||||
sourceMapData.sourceMapSourceRoot,
|
||||
|
@ -1844,17 +1848,17 @@ module ts {
|
|||
if (root) { // emitting single module file
|
||||
// For modules or multiple emit files the mapRoot will have directory structure like the sources
|
||||
// So if src\a.ts and src\lib\b.ts are compiled together user would be moving the maps into mapRoot\a.js.map and mapRoot\lib\b.js.map
|
||||
sourceMapDir = getDirectoryPath(getSourceFilePathInNewDir(root, program, sourceMapDir));
|
||||
sourceMapDir = getDirectoryPath(getSourceFilePathInNewDir(root, host, sourceMapDir));
|
||||
}
|
||||
|
||||
if (!isRootedDiskPath(sourceMapDir) && !isUrl(sourceMapDir)) {
|
||||
// The relative paths are relative to the common directory
|
||||
sourceMapDir = combinePaths(program.getCommonSourceDirectory(), sourceMapDir);
|
||||
sourceMapDir = combinePaths(host.getCommonSourceDirectory(), sourceMapDir);
|
||||
sourceMapData.jsSourceMappingURL = getRelativePathToDirectoryOrUrl(
|
||||
getDirectoryPath(normalizePath(jsFilePath)), // get the relative sourceMapDir path based on jsFilePath
|
||||
combinePaths(sourceMapDir, sourceMapData.jsSourceMappingURL), // this is where user expects to see sourceMap
|
||||
compilerHost.getCurrentDirectory(),
|
||||
compilerHost.getCanonicalFileName,
|
||||
host.getCurrentDirectory(),
|
||||
host.getCanonicalFileName,
|
||||
/*isAbsolutePathAnUrl*/ true);
|
||||
}
|
||||
else {
|
||||
|
@ -1890,7 +1894,7 @@ module ts {
|
|||
}
|
||||
|
||||
function writeJavaScriptFile(emitOutput: string, writeByteOrderMark: boolean) {
|
||||
writeFile(compilerHost, diagnostics, jsFilePath, emitOutput, writeByteOrderMark);
|
||||
writeFile(host, diagnostics, jsFilePath, emitOutput, writeByteOrderMark);
|
||||
}
|
||||
|
||||
// Create a temporary variable with a unique unused name. The forLoopVariable parameter signals that the
|
||||
|
@ -4215,7 +4219,7 @@ module ts {
|
|||
emit(root);
|
||||
}
|
||||
else {
|
||||
forEach(program.getSourceFiles(), sourceFile => {
|
||||
forEach(host.getSourceFiles(), sourceFile => {
|
||||
if (!isExternalModuleOrDeclarationFile(sourceFile)) {
|
||||
emit(sourceFile);
|
||||
}
|
||||
|
@ -4227,7 +4231,7 @@ module ts {
|
|||
}
|
||||
|
||||
function writeDeclarationFile(jsFilePath: string, sourceFile: SourceFile) {
|
||||
var emitDeclarationResult = emitDeclarations(program, resolver, diagnostics, jsFilePath, sourceFile);
|
||||
var 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.reportedDeclarationError) {
|
||||
|
@ -4242,7 +4246,7 @@ module ts {
|
|||
}
|
||||
});
|
||||
declarationOutput += emitDeclarationResult.synchronousDeclarationOutput.substring(appliedSyncOutputPos);
|
||||
writeFile(compilerHost, diagnostics, removeFileExtension(jsFilePath) + ".d.ts", declarationOutput, compilerOptions.emitBOM);
|
||||
writeFile(host, diagnostics, removeFileExtension(jsFilePath) + ".d.ts", declarationOutput, compilerOptions.emitBOM);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4252,11 +4256,11 @@ module ts {
|
|||
if (targetSourceFile === undefined) {
|
||||
// No targetSourceFile is specified (e.g. calling emitter from batch compiler)
|
||||
hasSemanticErrors = resolver.hasSemanticErrors();
|
||||
isEmitBlocked = resolver.isEmitBlocked();
|
||||
isEmitBlocked = host.isEmitBlocked();
|
||||
|
||||
forEach(program.getSourceFiles(), sourceFile => {
|
||||
forEach(host.getSourceFiles(), sourceFile => {
|
||||
if (shouldEmitToOwnFile(sourceFile, compilerOptions)) {
|
||||
var jsFilePath = getOwnEmitOutputFilePath(sourceFile, program, ".js");
|
||||
var jsFilePath = getOwnEmitOutputFilePath(sourceFile, host, ".js");
|
||||
emitFile(jsFilePath, sourceFile);
|
||||
}
|
||||
});
|
||||
|
@ -4270,18 +4274,18 @@ module ts {
|
|||
if (shouldEmitToOwnFile(targetSourceFile, compilerOptions)) {
|
||||
// If shouldEmitToOwnFile returns true or targetSourceFile is an external module file, then emit targetSourceFile in its own output file
|
||||
hasSemanticErrors = resolver.hasSemanticErrors(targetSourceFile);
|
||||
isEmitBlocked = resolver.isEmitBlocked(targetSourceFile);
|
||||
isEmitBlocked = host.isEmitBlocked(targetSourceFile);
|
||||
|
||||
var jsFilePath = getOwnEmitOutputFilePath(targetSourceFile, program, ".js");
|
||||
var jsFilePath = getOwnEmitOutputFilePath(targetSourceFile, host, ".js");
|
||||
emitFile(jsFilePath, targetSourceFile);
|
||||
}
|
||||
else if (!isDeclarationFile(targetSourceFile) && compilerOptions.out) {
|
||||
// Otherwise, if --out is specified and targetSourceFile is not a declaration file,
|
||||
// Emit all, non-external-module file, into one single output file
|
||||
forEach(program.getSourceFiles(), sourceFile => {
|
||||
forEach(host.getSourceFiles(), sourceFile => {
|
||||
if (!shouldEmitToOwnFile(sourceFile, compilerOptions)) {
|
||||
hasSemanticErrors = hasSemanticErrors || resolver.hasSemanticErrors(sourceFile);
|
||||
isEmitBlocked = isEmitBlocked || resolver.isEmitBlocked(sourceFile);
|
||||
isEmitBlocked = isEmitBlocked || host.isEmitBlocked(sourceFile);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
/// <reference path="types.ts"/>
|
||||
/// <reference path="core.ts"/>
|
||||
/// <reference path="scanner.ts"/>
|
||||
/// <reference path="utilities.ts"/>
|
||||
|
||||
|
@ -261,79 +259,6 @@ module ts {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO (drosen, mhegazy): Move to a more appropriate file.
|
||||
export function createCompilerHost(options: CompilerOptions): CompilerHost {
|
||||
var currentDirectory: string;
|
||||
var existingDirectories: Map<boolean> = {};
|
||||
|
||||
function getCanonicalFileName(fileName: string): string {
|
||||
// if underlying system can distinguish between two files whose names differs only in cases then file name already in canonical form.
|
||||
// otherwise use toLowerCase as a canonical form.
|
||||
return sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
|
||||
}
|
||||
|
||||
// returned by CScript sys environment
|
||||
var unsupportedFileEncodingErrorCode = -2147024809;
|
||||
|
||||
function getSourceFile(filename: string, languageVersion: ScriptTarget, onError?: (message: string) => void): SourceFile {
|
||||
try {
|
||||
var text = sys.readFile(filename, options.charset);
|
||||
}
|
||||
catch (e) {
|
||||
if (onError) {
|
||||
onError(e.number === unsupportedFileEncodingErrorCode ?
|
||||
createCompilerDiagnostic(Diagnostics.Unsupported_file_encoding).messageText :
|
||||
e.message);
|
||||
}
|
||||
text = "";
|
||||
}
|
||||
|
||||
return text !== undefined ? createSourceFile(filename, text, languageVersion) : undefined;
|
||||
}
|
||||
|
||||
function writeFile(fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void) {
|
||||
function directoryExists(directoryPath: string): boolean {
|
||||
if (hasProperty(existingDirectories, directoryPath)) {
|
||||
return true;
|
||||
}
|
||||
if (sys.directoryExists(directoryPath)) {
|
||||
existingDirectories[directoryPath] = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function ensureDirectoriesExist(directoryPath: string) {
|
||||
if (directoryPath.length > getRootLength(directoryPath) && !directoryExists(directoryPath)) {
|
||||
var parentDirectory = getDirectoryPath(directoryPath);
|
||||
ensureDirectoriesExist(parentDirectory);
|
||||
sys.createDirectory(directoryPath);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
ensureDirectoriesExist(getDirectoryPath(normalizePath(fileName)));
|
||||
sys.writeFile(fileName, data, writeByteOrderMark);
|
||||
}
|
||||
catch (e) {
|
||||
if (onError) {
|
||||
onError(e.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
getSourceFile,
|
||||
getDefaultLibFilename: options => combinePaths(getDirectoryPath(normalizePath(sys.getExecutingFilePath())), options.target === ScriptTarget.ES6 ? "lib.es6.d.ts" : "lib.d.ts"),
|
||||
writeFile,
|
||||
getCurrentDirectory: () => currentDirectory || (currentDirectory = sys.getCurrentDirectory()),
|
||||
useCaseSensitiveFileNames: () => sys.useCaseSensitiveFileNames,
|
||||
getCanonicalFileName,
|
||||
getNewLine: () => sys.newLine
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
const enum ParsingContext {
|
||||
SourceElements, // Elements in source file
|
||||
ModuleElements, // Elements in module declaration
|
||||
|
@ -4852,290 +4777,4 @@ module ts {
|
|||
export function isAssignmentOperator(token: SyntaxKind): boolean {
|
||||
return token >= SyntaxKind.FirstAssignment && token <= SyntaxKind.LastAssignment;
|
||||
}
|
||||
|
||||
export function createProgram(rootNames: string[], options: CompilerOptions, host: CompilerHost): Program {
|
||||
var program: Program;
|
||||
var files: SourceFile[] = [];
|
||||
var filesByName: Map<SourceFile> = {};
|
||||
var errors: Diagnostic[] = [];
|
||||
var seenNoDefaultLib = options.noLib;
|
||||
var commonSourceDirectory: string;
|
||||
|
||||
forEach(rootNames, name => processRootFile(name, false));
|
||||
if (!seenNoDefaultLib) {
|
||||
processRootFile(host.getDefaultLibFilename(options), true);
|
||||
}
|
||||
verifyCompilerOptions();
|
||||
errors.sort(compareDiagnostics);
|
||||
program = {
|
||||
getSourceFile: getSourceFile,
|
||||
getSourceFiles: () => files,
|
||||
getCompilerOptions: () => options,
|
||||
getCompilerHost: () => host,
|
||||
getDiagnostics: getDiagnostics,
|
||||
getGlobalDiagnostics: getGlobalDiagnostics,
|
||||
getTypeChecker: fullTypeCheckMode => createTypeChecker(program, fullTypeCheckMode),
|
||||
getCommonSourceDirectory: () => commonSourceDirectory,
|
||||
};
|
||||
return program;
|
||||
|
||||
function getSourceFile(filename: string) {
|
||||
filename = host.getCanonicalFileName(filename);
|
||||
return hasProperty(filesByName, filename) ? filesByName[filename] : undefined;
|
||||
}
|
||||
|
||||
function getDiagnostics(sourceFile?: SourceFile): Diagnostic[] {
|
||||
return sourceFile ? filter(errors, e => e.file === sourceFile) : errors;
|
||||
}
|
||||
|
||||
function getGlobalDiagnostics(): Diagnostic[] {
|
||||
return filter(errors, e => !e.file);
|
||||
}
|
||||
|
||||
function hasExtension(filename: string): boolean {
|
||||
return getBaseFilename(filename).indexOf(".") >= 0;
|
||||
}
|
||||
|
||||
function processRootFile(filename: string, isDefaultLib: boolean) {
|
||||
processSourceFile(normalizePath(filename), isDefaultLib);
|
||||
}
|
||||
|
||||
function processSourceFile(filename: string, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number) {
|
||||
if (refEnd !== undefined && refPos !== undefined) {
|
||||
var start = refPos;
|
||||
var length = refEnd - refPos;
|
||||
}
|
||||
var diagnostic: DiagnosticMessage;
|
||||
if (hasExtension(filename)) {
|
||||
if (!options.allowNonTsExtensions && !fileExtensionIs(filename, ".ts")) {
|
||||
diagnostic = Diagnostics.File_0_must_have_extension_ts_or_d_ts;
|
||||
}
|
||||
else if (!findSourceFile(filename, isDefaultLib, refFile, refPos, refEnd)) {
|
||||
diagnostic = Diagnostics.File_0_not_found;
|
||||
}
|
||||
else if (refFile && host.getCanonicalFileName(filename) === host.getCanonicalFileName(refFile.filename)) {
|
||||
diagnostic = Diagnostics.A_file_cannot_have_a_reference_to_itself;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!(findSourceFile(filename + ".ts", isDefaultLib, refFile, refPos, refEnd) || findSourceFile(filename + ".d.ts", isDefaultLib, refFile, refPos, refEnd))) {
|
||||
diagnostic = Diagnostics.File_0_not_found;
|
||||
filename += ".ts";
|
||||
}
|
||||
}
|
||||
|
||||
if (diagnostic) {
|
||||
if (refFile) {
|
||||
errors.push(createFileDiagnostic(refFile, start, length, diagnostic, filename));
|
||||
}
|
||||
else {
|
||||
errors.push(createCompilerDiagnostic(diagnostic, filename));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get source file from normalized filename
|
||||
function findSourceFile(filename: string, isDefaultLib: boolean, refFile?: SourceFile, refStart?: number, refLength?: number): SourceFile {
|
||||
var canonicalName = host.getCanonicalFileName(filename);
|
||||
if (hasProperty(filesByName, canonicalName)) {
|
||||
// We've already looked for this file, use cached result
|
||||
return getSourceFileFromCache(filename, canonicalName, /*useAbsolutePath*/ false);
|
||||
}
|
||||
else {
|
||||
var normalizedAbsolutePath = getNormalizedAbsolutePath(filename, host.getCurrentDirectory());
|
||||
var canonicalAbsolutePath = host.getCanonicalFileName(normalizedAbsolutePath);
|
||||
if (hasProperty(filesByName, canonicalAbsolutePath)) {
|
||||
return getSourceFileFromCache(normalizedAbsolutePath, canonicalAbsolutePath, /*useAbsolutePath*/ true);
|
||||
}
|
||||
|
||||
// We haven't looked for this file, do so now and cache result
|
||||
var file = filesByName[canonicalName] = host.getSourceFile(filename, options.target, hostErrorMessage => {
|
||||
if (refFile) {
|
||||
errors.push(createFileDiagnostic(refFile, refStart, refLength,
|
||||
Diagnostics.Cannot_read_file_0_Colon_1, filename, hostErrorMessage));
|
||||
}
|
||||
else {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, filename, hostErrorMessage));
|
||||
}
|
||||
});
|
||||
if (file) {
|
||||
seenNoDefaultLib = seenNoDefaultLib || file.hasNoDefaultLib;
|
||||
|
||||
// Set the source file for normalized absolute path
|
||||
filesByName[canonicalAbsolutePath] = file;
|
||||
|
||||
if (!options.noResolve) {
|
||||
var basePath = getDirectoryPath(filename);
|
||||
processReferencedFiles(file, basePath);
|
||||
processImportedModules(file, basePath);
|
||||
}
|
||||
if (isDefaultLib) {
|
||||
files.unshift(file);
|
||||
}
|
||||
else {
|
||||
files.push(file);
|
||||
}
|
||||
forEach(file.getSyntacticDiagnostics(), e => {
|
||||
errors.push(e);
|
||||
});
|
||||
}
|
||||
}
|
||||
return file;
|
||||
|
||||
function getSourceFileFromCache(filename: string, canonicalName: string, useAbsolutePath: boolean): SourceFile {
|
||||
var file = filesByName[canonicalName];
|
||||
if (file && host.useCaseSensitiveFileNames()) {
|
||||
var sourceFileName = useAbsolutePath ? getNormalizedAbsolutePath(file.filename, host.getCurrentDirectory()) : file.filename;
|
||||
if (canonicalName !== sourceFileName) {
|
||||
errors.push(createFileDiagnostic(refFile, refStart, refLength,
|
||||
Diagnostics.Filename_0_differs_from_already_included_filename_1_only_in_casing, filename, sourceFileName));
|
||||
}
|
||||
}
|
||||
return file;
|
||||
}
|
||||
}
|
||||
|
||||
function processReferencedFiles(file: SourceFile, basePath: string) {
|
||||
forEach(file.referencedFiles, ref => {
|
||||
var referencedFilename = isRootedDiskPath(ref.filename) ? ref.filename : combinePaths(basePath, ref.filename);
|
||||
processSourceFile(normalizePath(referencedFilename), /* isDefaultLib */ false, file, ref.pos, ref.end);
|
||||
});
|
||||
}
|
||||
|
||||
function processImportedModules(file: SourceFile, basePath: string) {
|
||||
forEach(file.statements, node => {
|
||||
if (isExternalModuleImportDeclaration(node) &&
|
||||
getExternalModuleImportDeclarationExpression(node).kind === SyntaxKind.StringLiteral) {
|
||||
|
||||
var nameLiteral = <LiteralExpression>getExternalModuleImportDeclarationExpression(node);
|
||||
var moduleName = nameLiteral.text;
|
||||
if (moduleName) {
|
||||
var searchPath = basePath;
|
||||
while (true) {
|
||||
var searchName = normalizePath(combinePaths(searchPath, moduleName));
|
||||
if (findModuleSourceFile(searchName + ".ts", nameLiteral) || findModuleSourceFile(searchName + ".d.ts", nameLiteral)) {
|
||||
break;
|
||||
}
|
||||
|
||||
var parentPath = getDirectoryPath(searchPath);
|
||||
if (parentPath === searchPath) {
|
||||
break;
|
||||
}
|
||||
searchPath = parentPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (node.kind === SyntaxKind.ModuleDeclaration && (<ModuleDeclaration>node).name.kind === SyntaxKind.StringLiteral && (node.flags & NodeFlags.Ambient || isDeclarationFile(file))) {
|
||||
// TypeScript 1.0 spec (April 2014): 12.1.6
|
||||
// An AmbientExternalModuleDeclaration declares an external module.
|
||||
// This type of declaration is permitted only in the global module.
|
||||
// The StringLiteral must specify a top - level external module name.
|
||||
// Relative external module names are not permitted
|
||||
forEachChild((<ModuleDeclaration>node).body, node => {
|
||||
if (isExternalModuleImportDeclaration(node) &&
|
||||
getExternalModuleImportDeclarationExpression(node).kind === SyntaxKind.StringLiteral) {
|
||||
|
||||
var nameLiteral = <LiteralExpression>getExternalModuleImportDeclarationExpression(node);
|
||||
var moduleName = nameLiteral.text;
|
||||
if (moduleName) {
|
||||
// TypeScript 1.0 spec (April 2014): 12.1.6
|
||||
// An ExternalImportDeclaration in anAmbientExternalModuleDeclaration may reference other external modules
|
||||
// only through top - level external module names. Relative external module names are not permitted.
|
||||
var searchName = normalizePath(combinePaths(basePath, moduleName));
|
||||
var tsFile = findModuleSourceFile(searchName + ".ts", nameLiteral);
|
||||
if (!tsFile) {
|
||||
findModuleSourceFile(searchName + ".d.ts", nameLiteral);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function findModuleSourceFile(filename: string, nameLiteral: LiteralExpression) {
|
||||
return findSourceFile(filename, /* isDefaultLib */ false, file, nameLiteral.pos, nameLiteral.end - nameLiteral.pos);
|
||||
}
|
||||
}
|
||||
|
||||
function verifyCompilerOptions() {
|
||||
if (!options.sourceMap && (options.mapRoot || options.sourceRoot)) {
|
||||
// Error to specify --mapRoot or --sourceRoot without mapSourceFiles
|
||||
if (options.mapRoot) {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Option_mapRoot_cannot_be_specified_without_specifying_sourcemap_option));
|
||||
}
|
||||
if (options.sourceRoot) {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Option_sourceRoot_cannot_be_specified_without_specifying_sourcemap_option));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var firstExternalModule = forEach(files, f => isExternalModule(f) ? f : undefined);
|
||||
if (firstExternalModule && options.module === ModuleKind.None) {
|
||||
// We cannot use createDiagnosticFromNode because nodes do not have parents yet
|
||||
var externalModuleErrorSpan = getErrorSpanForNode(firstExternalModule.externalModuleIndicator);
|
||||
var errorStart = skipTrivia(firstExternalModule.text, externalModuleErrorSpan.pos);
|
||||
var errorLength = externalModuleErrorSpan.end - errorStart;
|
||||
errors.push(createFileDiagnostic(firstExternalModule, errorStart, errorLength, Diagnostics.Cannot_compile_external_modules_unless_the_module_flag_is_provided));
|
||||
}
|
||||
|
||||
// there has to be common source directory if user specified --outdir || --sourcRoot
|
||||
// if user specified --mapRoot, there needs to be common source directory if there would be multiple files being emitted
|
||||
if (options.outDir || // there is --outDir specified
|
||||
options.sourceRoot || // there is --sourceRoot specified
|
||||
(options.mapRoot && // there is --mapRoot Specified and there would be multiple js files generated
|
||||
(!options.out || firstExternalModule !== undefined))) {
|
||||
|
||||
var commonPathComponents: string[];
|
||||
forEach(files, sourceFile => {
|
||||
// Each file contributes into common source file path
|
||||
if (!(sourceFile.flags & NodeFlags.DeclarationFile)
|
||||
&& !fileExtensionIs(sourceFile.filename, ".js")) {
|
||||
var sourcePathComponents = getNormalizedPathComponents(sourceFile.filename, host.getCurrentDirectory());
|
||||
sourcePathComponents.pop(); // FileName is not part of directory
|
||||
if (commonPathComponents) {
|
||||
for (var i = 0; i < Math.min(commonPathComponents.length, sourcePathComponents.length); i++) {
|
||||
if (commonPathComponents[i] !== sourcePathComponents[i]) {
|
||||
if (i === 0) {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files));
|
||||
return;
|
||||
}
|
||||
|
||||
// New common path found that is 0 -> i-1
|
||||
commonPathComponents.length = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If the fileComponent path completely matched and less than already found update the length
|
||||
if (sourcePathComponents.length < commonPathComponents.length) {
|
||||
commonPathComponents.length = sourcePathComponents.length;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// first file
|
||||
commonPathComponents = sourcePathComponents;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
commonSourceDirectory = getNormalizedPathFromPathComponents(commonPathComponents);
|
||||
if (commonSourceDirectory) {
|
||||
// Make sure directory path ends with directory separator so this string can directly
|
||||
// used to replace with "" to get the relative path of the source file and the relative path doesn't
|
||||
// start with / making it rooted path
|
||||
commonSourceDirectory += directorySeparator;
|
||||
}
|
||||
}
|
||||
|
||||
if (options.noEmit) {
|
||||
if (options.out || options.outDir) {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Option_noEmit_cannot_be_specified_with_option_out_or_outDir));
|
||||
}
|
||||
|
||||
if (options.declaration) {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Option_noEmit_cannot_be_specified_with_option_declaration));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
408
src/compiler/program.ts
Normal file
408
src/compiler/program.ts
Normal file
|
@ -0,0 +1,408 @@
|
|||
/// <reference path="sys.ts" />
|
||||
/// <reference path="emitter.ts" />
|
||||
|
||||
module ts {
|
||||
export function createCompilerHost(options: CompilerOptions): CompilerHost {
|
||||
var currentDirectory: string;
|
||||
var existingDirectories: Map<boolean> = {};
|
||||
|
||||
function getCanonicalFileName(fileName: string): string {
|
||||
// if underlying system can distinguish between two files whose names differs only in cases then file name already in canonical form.
|
||||
// otherwise use toLowerCase as a canonical form.
|
||||
return sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
|
||||
}
|
||||
|
||||
// returned by CScript sys environment
|
||||
var unsupportedFileEncodingErrorCode = -2147024809;
|
||||
|
||||
function getSourceFile(filename: string, languageVersion: ScriptTarget, onError?: (message: string) => void): SourceFile {
|
||||
try {
|
||||
var text = sys.readFile(filename, options.charset);
|
||||
}
|
||||
catch (e) {
|
||||
if (onError) {
|
||||
onError(e.number === unsupportedFileEncodingErrorCode ?
|
||||
createCompilerDiagnostic(Diagnostics.Unsupported_file_encoding).messageText :
|
||||
e.message);
|
||||
}
|
||||
text = "";
|
||||
}
|
||||
|
||||
return text !== undefined ? createSourceFile(filename, text, languageVersion) : undefined;
|
||||
}
|
||||
|
||||
function writeFile(fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void) {
|
||||
function directoryExists(directoryPath: string): boolean {
|
||||
if (hasProperty(existingDirectories, directoryPath)) {
|
||||
return true;
|
||||
}
|
||||
if (sys.directoryExists(directoryPath)) {
|
||||
existingDirectories[directoryPath] = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function ensureDirectoriesExist(directoryPath: string) {
|
||||
if (directoryPath.length > getRootLength(directoryPath) && !directoryExists(directoryPath)) {
|
||||
var parentDirectory = getDirectoryPath(directoryPath);
|
||||
ensureDirectoriesExist(parentDirectory);
|
||||
sys.createDirectory(directoryPath);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
ensureDirectoriesExist(getDirectoryPath(normalizePath(fileName)));
|
||||
sys.writeFile(fileName, data, writeByteOrderMark);
|
||||
}
|
||||
catch (e) {
|
||||
if (onError) {
|
||||
onError(e.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
getSourceFile,
|
||||
getDefaultLibFilename: options => combinePaths(getDirectoryPath(normalizePath(sys.getExecutingFilePath())), options.target === ScriptTarget.ES6 ? "lib.es6.d.ts" : "lib.d.ts"),
|
||||
writeFile,
|
||||
getCurrentDirectory: () => currentDirectory || (currentDirectory = sys.getCurrentDirectory()),
|
||||
useCaseSensitiveFileNames: () => sys.useCaseSensitiveFileNames,
|
||||
getCanonicalFileName,
|
||||
getNewLine: () => sys.newLine
|
||||
};
|
||||
}
|
||||
|
||||
export function createProgram(rootNames: string[], options: CompilerOptions, host: CompilerHost): Program {
|
||||
var program: Program;
|
||||
var files: SourceFile[] = [];
|
||||
var filesByName: Map<SourceFile> = {};
|
||||
var errors: Diagnostic[] = [];
|
||||
var seenNoDefaultLib = options.noLib;
|
||||
var commonSourceDirectory: string;
|
||||
|
||||
forEach(rootNames, name => processRootFile(name, false));
|
||||
if (!seenNoDefaultLib) {
|
||||
processRootFile(host.getDefaultLibFilename(options), true);
|
||||
}
|
||||
verifyCompilerOptions();
|
||||
errors.sort(compareDiagnostics);
|
||||
|
||||
|
||||
var diagnosticsProducingTypeChecker: TypeChecker;
|
||||
var noDiagnosticsTypeChecker: TypeChecker;
|
||||
var emitHost: EmitHost;
|
||||
|
||||
program = {
|
||||
getSourceFile: getSourceFile,
|
||||
getSourceFiles: () => files,
|
||||
getCompilerOptions: () => options,
|
||||
getCompilerHost: () => host,
|
||||
getDiagnostics: getDiagnostics,
|
||||
getGlobalDiagnostics: getGlobalDiagnostics,
|
||||
getDeclarationDiagnostics: getDeclarationDiagnostics,
|
||||
getTypeChecker,
|
||||
getCommonSourceDirectory: () => commonSourceDirectory,
|
||||
emitFiles: invokeEmitter,
|
||||
isEmitBlocked,
|
||||
getCurrentDirectory: host.getCurrentDirectory,
|
||||
};
|
||||
return program;
|
||||
|
||||
function getEmitHost() {
|
||||
return emitHost || (emitHost = createEmitHostFromProgram(program));
|
||||
}
|
||||
|
||||
function hasEarlyErrors(sourceFile?: SourceFile): boolean {
|
||||
return forEach(getDiagnosticsProducingTypeChecker().getDiagnostics(sourceFile), d => d.isEarly);
|
||||
}
|
||||
|
||||
function isEmitBlocked(sourceFile?: SourceFile): boolean {
|
||||
return getDiagnostics(sourceFile).length !== 0 ||
|
||||
hasEarlyErrors(sourceFile) ||
|
||||
(options.noEmitOnError && getDiagnosticsProducingTypeChecker().getDiagnostics(sourceFile).length !== 0);
|
||||
}
|
||||
|
||||
function getDiagnosticsProducingTypeChecker() {
|
||||
return diagnosticsProducingTypeChecker || (diagnosticsProducingTypeChecker = createTypeChecker(program, /*produceDiagnostics:*/ true));
|
||||
}
|
||||
|
||||
function getTypeChecker(produceDiagnostics: boolean) {
|
||||
if (produceDiagnostics) {
|
||||
return getDiagnosticsProducingTypeChecker();
|
||||
}
|
||||
else {
|
||||
return noDiagnosticsTypeChecker || (noDiagnosticsTypeChecker = createTypeChecker(program, produceDiagnostics));
|
||||
}
|
||||
}
|
||||
|
||||
function getDeclarationDiagnostics(targetSourceFile: SourceFile): Diagnostic[]{
|
||||
var typeChecker = getDiagnosticsProducingTypeChecker();
|
||||
typeChecker.getDiagnostics(targetSourceFile);
|
||||
var resolver = typeChecker.getEmitResolver();
|
||||
return ts.getDeclarationDiagnostics(getEmitHost(), resolver, targetSourceFile);
|
||||
}
|
||||
|
||||
function invokeEmitter(targetSourceFile?: SourceFile) {
|
||||
var resolver = getDiagnosticsProducingTypeChecker().getEmitResolver();
|
||||
return emitFiles(resolver, getEmitHost(), targetSourceFile);
|
||||
} function getSourceFile(filename: string) {
|
||||
filename = host.getCanonicalFileName(filename);
|
||||
return hasProperty(filesByName, filename) ? filesByName[filename] : undefined;
|
||||
}
|
||||
|
||||
function getDiagnostics(sourceFile?: SourceFile): Diagnostic[] {
|
||||
return sourceFile ? filter(errors, e => e.file === sourceFile) : errors;
|
||||
}
|
||||
|
||||
function getGlobalDiagnostics(): Diagnostic[] {
|
||||
return filter(errors, e => !e.file);
|
||||
}
|
||||
|
||||
function hasExtension(filename: string): boolean {
|
||||
return getBaseFilename(filename).indexOf(".") >= 0;
|
||||
}
|
||||
|
||||
function processRootFile(filename: string, isDefaultLib: boolean) {
|
||||
processSourceFile(normalizePath(filename), isDefaultLib);
|
||||
}
|
||||
|
||||
function processSourceFile(filename: string, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number) {
|
||||
if (refEnd !== undefined && refPos !== undefined) {
|
||||
var start = refPos;
|
||||
var length = refEnd - refPos;
|
||||
}
|
||||
var diagnostic: DiagnosticMessage;
|
||||
if (hasExtension(filename)) {
|
||||
if (!options.allowNonTsExtensions && !fileExtensionIs(filename, ".ts")) {
|
||||
diagnostic = Diagnostics.File_0_must_have_extension_ts_or_d_ts;
|
||||
}
|
||||
else if (!findSourceFile(filename, isDefaultLib, refFile, refPos, refEnd)) {
|
||||
diagnostic = Diagnostics.File_0_not_found;
|
||||
}
|
||||
else if (refFile && host.getCanonicalFileName(filename) === host.getCanonicalFileName(refFile.filename)) {
|
||||
diagnostic = Diagnostics.A_file_cannot_have_a_reference_to_itself;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!(findSourceFile(filename + ".ts", isDefaultLib, refFile, refPos, refEnd) || findSourceFile(filename + ".d.ts", isDefaultLib, refFile, refPos, refEnd))) {
|
||||
diagnostic = Diagnostics.File_0_not_found;
|
||||
filename += ".ts";
|
||||
}
|
||||
}
|
||||
|
||||
if (diagnostic) {
|
||||
if (refFile) {
|
||||
errors.push(createFileDiagnostic(refFile, start, length, diagnostic, filename));
|
||||
}
|
||||
else {
|
||||
errors.push(createCompilerDiagnostic(diagnostic, filename));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get source file from normalized filename
|
||||
function findSourceFile(filename: string, isDefaultLib: boolean, refFile?: SourceFile, refStart?: number, refLength?: number): SourceFile {
|
||||
var canonicalName = host.getCanonicalFileName(filename);
|
||||
if (hasProperty(filesByName, canonicalName)) {
|
||||
// We've already looked for this file, use cached result
|
||||
return getSourceFileFromCache(filename, canonicalName, /*useAbsolutePath*/ false);
|
||||
}
|
||||
else {
|
||||
var normalizedAbsolutePath = getNormalizedAbsolutePath(filename, host.getCurrentDirectory());
|
||||
var canonicalAbsolutePath = host.getCanonicalFileName(normalizedAbsolutePath);
|
||||
if (hasProperty(filesByName, canonicalAbsolutePath)) {
|
||||
return getSourceFileFromCache(normalizedAbsolutePath, canonicalAbsolutePath, /*useAbsolutePath*/ true);
|
||||
}
|
||||
|
||||
// We haven't looked for this file, do so now and cache result
|
||||
var file = filesByName[canonicalName] = host.getSourceFile(filename, options.target, hostErrorMessage => {
|
||||
if (refFile) {
|
||||
errors.push(createFileDiagnostic(refFile, refStart, refLength,
|
||||
Diagnostics.Cannot_read_file_0_Colon_1, filename, hostErrorMessage));
|
||||
}
|
||||
else {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, filename, hostErrorMessage));
|
||||
}
|
||||
});
|
||||
if (file) {
|
||||
seenNoDefaultLib = seenNoDefaultLib || file.hasNoDefaultLib;
|
||||
|
||||
// Set the source file for normalized absolute path
|
||||
filesByName[canonicalAbsolutePath] = file;
|
||||
|
||||
if (!options.noResolve) {
|
||||
var basePath = getDirectoryPath(filename);
|
||||
processReferencedFiles(file, basePath);
|
||||
processImportedModules(file, basePath);
|
||||
}
|
||||
if (isDefaultLib) {
|
||||
files.unshift(file);
|
||||
}
|
||||
else {
|
||||
files.push(file);
|
||||
}
|
||||
forEach(file.getSyntacticDiagnostics(), e => {
|
||||
errors.push(e);
|
||||
});
|
||||
}
|
||||
}
|
||||
return file;
|
||||
|
||||
function getSourceFileFromCache(filename: string, canonicalName: string, useAbsolutePath: boolean): SourceFile {
|
||||
var file = filesByName[canonicalName];
|
||||
if (file && host.useCaseSensitiveFileNames()) {
|
||||
var sourceFileName = useAbsolutePath ? getNormalizedAbsolutePath(file.filename, host.getCurrentDirectory()) : file.filename;
|
||||
if (canonicalName !== sourceFileName) {
|
||||
errors.push(createFileDiagnostic(refFile, refStart, refLength,
|
||||
Diagnostics.Filename_0_differs_from_already_included_filename_1_only_in_casing, filename, sourceFileName));
|
||||
}
|
||||
}
|
||||
return file;
|
||||
}
|
||||
}
|
||||
|
||||
function processReferencedFiles(file: SourceFile, basePath: string) {
|
||||
forEach(file.referencedFiles, ref => {
|
||||
var referencedFilename = isRootedDiskPath(ref.filename) ? ref.filename : combinePaths(basePath, ref.filename);
|
||||
processSourceFile(normalizePath(referencedFilename), /* isDefaultLib */ false, file, ref.pos, ref.end);
|
||||
});
|
||||
}
|
||||
|
||||
function processImportedModules(file: SourceFile, basePath: string) {
|
||||
forEach(file.statements, node => {
|
||||
if (isExternalModuleImportDeclaration(node) &&
|
||||
getExternalModuleImportDeclarationExpression(node).kind === SyntaxKind.StringLiteral) {
|
||||
|
||||
var nameLiteral = <LiteralExpression>getExternalModuleImportDeclarationExpression(node);
|
||||
var moduleName = nameLiteral.text;
|
||||
if (moduleName) {
|
||||
var searchPath = basePath;
|
||||
while (true) {
|
||||
var searchName = normalizePath(combinePaths(searchPath, moduleName));
|
||||
if (findModuleSourceFile(searchName + ".ts", nameLiteral) || findModuleSourceFile(searchName + ".d.ts", nameLiteral)) {
|
||||
break;
|
||||
}
|
||||
|
||||
var parentPath = getDirectoryPath(searchPath);
|
||||
if (parentPath === searchPath) {
|
||||
break;
|
||||
}
|
||||
searchPath = parentPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (node.kind === SyntaxKind.ModuleDeclaration && (<ModuleDeclaration>node).name.kind === SyntaxKind.StringLiteral && (node.flags & NodeFlags.Ambient || isDeclarationFile(file))) {
|
||||
// TypeScript 1.0 spec (April 2014): 12.1.6
|
||||
// An AmbientExternalModuleDeclaration declares an external module.
|
||||
// This type of declaration is permitted only in the global module.
|
||||
// The StringLiteral must specify a top - level external module name.
|
||||
// Relative external module names are not permitted
|
||||
forEachChild((<ModuleDeclaration>node).body, node => {
|
||||
if (isExternalModuleImportDeclaration(node) &&
|
||||
getExternalModuleImportDeclarationExpression(node).kind === SyntaxKind.StringLiteral) {
|
||||
|
||||
var nameLiteral = <LiteralExpression>getExternalModuleImportDeclarationExpression(node);
|
||||
var moduleName = nameLiteral.text;
|
||||
if (moduleName) {
|
||||
// TypeScript 1.0 spec (April 2014): 12.1.6
|
||||
// An ExternalImportDeclaration in anAmbientExternalModuleDeclaration may reference other external modules
|
||||
// only through top - level external module names. Relative external module names are not permitted.
|
||||
var searchName = normalizePath(combinePaths(basePath, moduleName));
|
||||
var tsFile = findModuleSourceFile(searchName + ".ts", nameLiteral);
|
||||
if (!tsFile) {
|
||||
findModuleSourceFile(searchName + ".d.ts", nameLiteral);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function findModuleSourceFile(filename: string, nameLiteral: LiteralExpression) {
|
||||
return findSourceFile(filename, /* isDefaultLib */ false, file, nameLiteral.pos, nameLiteral.end - nameLiteral.pos);
|
||||
}
|
||||
}
|
||||
|
||||
function verifyCompilerOptions() {
|
||||
if (!options.sourceMap && (options.mapRoot || options.sourceRoot)) {
|
||||
// Error to specify --mapRoot or --sourceRoot without mapSourceFiles
|
||||
if (options.mapRoot) {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Option_mapRoot_cannot_be_specified_without_specifying_sourcemap_option));
|
||||
}
|
||||
if (options.sourceRoot) {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Option_sourceRoot_cannot_be_specified_without_specifying_sourcemap_option));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var firstExternalModule = forEach(files, f => isExternalModule(f) ? f : undefined);
|
||||
if (firstExternalModule && options.module === ModuleKind.None) {
|
||||
// We cannot use createDiagnosticFromNode because nodes do not have parents yet
|
||||
var externalModuleErrorSpan = getErrorSpanForNode(firstExternalModule.externalModuleIndicator);
|
||||
var errorStart = skipTrivia(firstExternalModule.text, externalModuleErrorSpan.pos);
|
||||
var errorLength = externalModuleErrorSpan.end - errorStart;
|
||||
errors.push(createFileDiagnostic(firstExternalModule, errorStart, errorLength, Diagnostics.Cannot_compile_external_modules_unless_the_module_flag_is_provided));
|
||||
}
|
||||
|
||||
// there has to be common source directory if user specified --outdir || --sourcRoot
|
||||
// if user specified --mapRoot, there needs to be common source directory if there would be multiple files being emitted
|
||||
if (options.outDir || // there is --outDir specified
|
||||
options.sourceRoot || // there is --sourceRoot specified
|
||||
(options.mapRoot && // there is --mapRoot Specified and there would be multiple js files generated
|
||||
(!options.out || firstExternalModule !== undefined))) {
|
||||
|
||||
var commonPathComponents: string[];
|
||||
forEach(files, sourceFile => {
|
||||
// Each file contributes into common source file path
|
||||
if (!(sourceFile.flags & NodeFlags.DeclarationFile)
|
||||
&& !fileExtensionIs(sourceFile.filename, ".js")) {
|
||||
var sourcePathComponents = getNormalizedPathComponents(sourceFile.filename, host.getCurrentDirectory());
|
||||
sourcePathComponents.pop(); // FileName is not part of directory
|
||||
if (commonPathComponents) {
|
||||
for (var i = 0; i < Math.min(commonPathComponents.length, sourcePathComponents.length); i++) {
|
||||
if (commonPathComponents[i] !== sourcePathComponents[i]) {
|
||||
if (i === 0) {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files));
|
||||
return;
|
||||
}
|
||||
|
||||
// New common path found that is 0 -> i-1
|
||||
commonPathComponents.length = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If the fileComponent path completely matched and less than already found update the length
|
||||
if (sourcePathComponents.length < commonPathComponents.length) {
|
||||
commonPathComponents.length = sourcePathComponents.length;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// first file
|
||||
commonPathComponents = sourcePathComponents;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
commonSourceDirectory = getNormalizedPathFromPathComponents(commonPathComponents);
|
||||
if (commonSourceDirectory) {
|
||||
// Make sure directory path ends with directory separator so this string can directly
|
||||
// used to replace with "" to get the relative path of the source file and the relative path doesn't
|
||||
// start with / making it rooted path
|
||||
commonSourceDirectory += directorySeparator;
|
||||
}
|
||||
}
|
||||
|
||||
if (options.noEmit) {
|
||||
if (options.out || options.outDir) {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Option_noEmit_cannot_be_specified_with_option_out_or_outDir));
|
||||
}
|
||||
|
||||
if (options.declaration) {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Option_noEmit_cannot_be_specified_with_option_declaration));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
/// <reference path="types.ts"/>
|
||||
/// <reference path="core.ts"/>
|
||||
/// <reference path="diagnosticInformationMap.generated.ts"/>
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
@ -293,7 +286,7 @@ 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) {
|
||||
|
@ -301,7 +294,7 @@ module ts {
|
|||
}
|
||||
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();
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
/// <reference path="core.ts"/>
|
||||
|
||||
module ts {
|
||||
export interface Map<T> {
|
||||
[index: string]: T;
|
||||
|
@ -248,7 +246,6 @@ module ts {
|
|||
EnumMember,
|
||||
// Top-level nodes
|
||||
SourceFile,
|
||||
Program,
|
||||
|
||||
// Synthesized list
|
||||
SyntaxList,
|
||||
|
@ -925,15 +922,33 @@ module ts {
|
|||
identifiers: Map<string>;
|
||||
}
|
||||
|
||||
export interface Program {
|
||||
getSourceFile(filename: string): SourceFile;
|
||||
getSourceFiles(): SourceFile[];
|
||||
export interface ScriptReferenceHost {
|
||||
getCompilerOptions(): CompilerOptions;
|
||||
getSourceFile(filename: string): SourceFile;
|
||||
getCurrentDirectory(): string;
|
||||
}
|
||||
|
||||
export interface Program extends ScriptReferenceHost {
|
||||
getSourceFiles(): SourceFile[];
|
||||
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.
|
||||
// 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
|
||||
// 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
|
||||
// will throw an invalid operation exception.
|
||||
getTypeChecker(produceDiagnostics: boolean): TypeChecker;
|
||||
getCommonSourceDirectory(): string;
|
||||
|
||||
emitFiles(targetSourceFile?: SourceFile): EmitResult;
|
||||
isEmitBlocked(sourceFile?: SourceFile): boolean;
|
||||
}
|
||||
|
||||
export interface SourceMapSpan {
|
||||
|
@ -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[];
|
||||
|
@ -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;
|
||||
|
@ -1088,7 +1109,6 @@ module ts {
|
|||
}
|
||||
|
||||
export interface EmitResolver {
|
||||
getProgram(): Program;
|
||||
getLocalNameOfContainer(container: ModuleDeclaration | EnumDeclaration): string;
|
||||
getExpressionNamePrefix(node: Identifier): string;
|
||||
getExportAssignmentName(node: SourceFile): string;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 }[];
|
||||
|
@ -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);
|
||||
});
|
||||
|
@ -138,7 +138,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
|||
lastUnit = undefined;
|
||||
rootDir = undefined;
|
||||
result = undefined;
|
||||
checker = undefined;
|
||||
program = undefined;
|
||||
options = undefined;
|
||||
toBeCompiled = undefined;
|
||||
otherFiles = undefined;
|
||||
|
@ -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 => {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'/>
|
||||
|
@ -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) {
|
||||
|
||||
|
@ -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[] = [];
|
||||
|
@ -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';
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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(() => {
|
||||
|
@ -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);
|
||||
});
|
||||
|
||||
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
/// <reference path="..\compiler\types.ts"/>
|
||||
/// <reference path="..\compiler\core.ts"/>
|
||||
/// <reference path="..\compiler\scanner.ts"/>
|
||||
/// <reference path="..\compiler\parser.ts"/>
|
||||
/// <reference path="..\compiler\checker.ts"/>
|
||||
/// <reference path="..\compiler\program.ts"/>
|
||||
|
||||
/// <reference path='breakpoints.ts' />
|
||||
/// <reference path='outliningElementsCollector.ts' />
|
||||
|
@ -13,7 +9,6 @@
|
|||
/// <reference path='formatting\smartIndenter.ts' />
|
||||
|
||||
module ts {
|
||||
|
||||
export var servicesVersion = "0.4"
|
||||
|
||||
export interface Node {
|
||||
|
@ -1925,16 +1920,11 @@ module ts {
|
|||
// this checker is used to answer all LS questions except errors
|
||||
var typeInfoResolver: TypeChecker;
|
||||
|
||||
// the sole purpose of this checker is to return semantic diagnostics
|
||||
// creation is deferred - use getFullTypeCheckChecker to get instance
|
||||
var fullTypeCheckChecker_doNotAccessDirectly: TypeChecker;
|
||||
|
||||
var useCaseSensitivefilenames = false;
|
||||
var sourceFilesByName: Map<SourceFile> = {};
|
||||
var documentRegistry = documentRegistry;
|
||||
var cancellationToken = new CancellationTokenObject(host.getCancellationToken && host.getCancellationToken());
|
||||
var activeCompletionSession: CompletionSession; // The current active completion session, used to get the completion entry details
|
||||
var writer: (filename: string, data: string, writeByteOrderMark: boolean) => void = undefined;
|
||||
|
||||
// Check if the localized messages json is set, otherwise query the host for it
|
||||
if (!localizedDiagnosticMessages && host.getLocalizedDiagnosticMessages) {
|
||||
|
@ -1949,8 +1939,8 @@ module ts {
|
|||
return lookUp(sourceFilesByName, getCanonicalFileName(filename));
|
||||
}
|
||||
|
||||
function getFullTypeCheckChecker() {
|
||||
return fullTypeCheckChecker_doNotAccessDirectly || (fullTypeCheckChecker_doNotAccessDirectly = program.getTypeChecker(/*fullTypeCheck*/ true));
|
||||
function getDiagnosticsProducingTypeChecker() {
|
||||
return program.getTypeChecker(/*produceDiagnostics:*/ true);
|
||||
}
|
||||
|
||||
function getRuleProvider(options: FormatCodeOptions) {
|
||||
|
@ -1977,7 +1967,6 @@ module ts {
|
|||
return host.getDefaultLibFilename(options);
|
||||
},
|
||||
writeFile: (filename, data, writeByteOrderMark) => {
|
||||
writer(filename, data, writeByteOrderMark);
|
||||
},
|
||||
getCurrentDirectory: (): string => {
|
||||
return host.getCurrentDirectory();
|
||||
|
@ -2090,8 +2079,7 @@ module ts {
|
|||
|
||||
// Now create a new compiler
|
||||
program = createProgram(hostfilenames, compilationSettings, createCompilerHost());
|
||||
typeInfoResolver = program.getTypeChecker(/*fullTypeCheckMode*/ false);
|
||||
fullTypeCheckChecker_doNotAccessDirectly = undefined;
|
||||
typeInfoResolver = program.getTypeChecker(/*produceDiagnostics*/ false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2101,8 +2089,7 @@ module ts {
|
|||
*/
|
||||
function cleanupSemanticCache(): void {
|
||||
if (program) {
|
||||
typeInfoResolver = program.getTypeChecker(/*fullTypeCheckMode*/ false);
|
||||
fullTypeCheckChecker_doNotAccessDirectly = undefined;
|
||||
typeInfoResolver = program.getTypeChecker(/*produceDiagnostics*/ false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2131,7 +2118,7 @@ module ts {
|
|||
|
||||
filename = normalizeSlashes(filename)
|
||||
var compilerOptions = program.getCompilerOptions();
|
||||
var checker = getFullTypeCheckChecker();
|
||||
var checker = getDiagnosticsProducingTypeChecker();
|
||||
var targetSourceFile = getSourceFile(filename);
|
||||
|
||||
// Only perform the action per file regardless of '-out' flag as LanguageServiceHost is expected to call this function per file.
|
||||
|
@ -2140,7 +2127,7 @@ module ts {
|
|||
var allDiagnostics = checker.getDiagnostics(targetSourceFile);
|
||||
if (compilerOptions.declaration) {
|
||||
// If '-d' is enabled, check for emitter error. One example of emitter error is export class implements non-export interface
|
||||
allDiagnostics = allDiagnostics.concat(checker.getDeclarationDiagnostics(targetSourceFile));
|
||||
allDiagnostics = allDiagnostics.concat(program.getDeclarationDiagnostics(targetSourceFile));
|
||||
}
|
||||
return allDiagnostics
|
||||
}
|
||||
|
@ -4571,7 +4558,7 @@ module ts {
|
|||
|
||||
var outputFiles: OutputFile[] = [];
|
||||
|
||||
function getEmitOutputWriter(filename: string, data: string, writeByteOrderMark: boolean) {
|
||||
function writeFile(filename: string, data: string, writeByteOrderMark: boolean) {
|
||||
outputFiles.push({
|
||||
name: filename,
|
||||
writeByteOrderMark: writeByteOrderMark,
|
||||
|
@ -4579,13 +4566,12 @@ module ts {
|
|||
});
|
||||
}
|
||||
|
||||
// Initialize writer for CompilerHost.writeFile
|
||||
writer = getEmitOutputWriter;
|
||||
// Get an emit host from our program, but override the writeFile functionality to
|
||||
// call our local writer function.
|
||||
var emitHost = createEmitHostFromProgram(program);
|
||||
emitHost.writeFile = writeFile;
|
||||
|
||||
var emitOutput = getFullTypeCheckChecker().emitFiles(sourceFile);
|
||||
|
||||
// Reset writer back to undefined to make sure that we produce an error message if CompilerHost.writeFile method is called when we are not in getEmitOutput
|
||||
writer = undefined;
|
||||
var emitOutput = emitFiles(getDiagnosticsProducingTypeChecker().getEmitResolver(), emitHost, sourceFile);
|
||||
|
||||
return {
|
||||
outputFiles,
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
tests/cases/compiler/objectLiteralMemberWithModifiers2.ts(1,11): error TS1184: Modifiers cannot appear here.
|
||||
tests/cases/compiler/objectLiteralMemberWithModifiers2.ts(1,22): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
|
||||
tests/cases/compiler/objectLiteralMemberWithModifiers2.ts(1,22): error TS2378: A 'get' accessor must return a value or consist of a single 'throw' statement.
|
||||
|
||||
|
||||
==== tests/cases/compiler/objectLiteralMemberWithModifiers2.ts (2 errors) ====
|
||||
var v = { public get foo() { } }
|
||||
~~~~~~
|
||||
!!! error TS1184: Modifiers cannot appear here.
|
||||
~~~
|
||||
!!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
|
||||
~~~
|
||||
!!! error TS2378: A 'get' accessor must return a value or consist of a single 'throw' statement.
|
|
@ -1,6 +0,0 @@
|
|||
//// [objectLiteralMemberWithModifiers2.ts]
|
||||
var v = { public get foo() { } }
|
||||
|
||||
//// [objectLiteralMemberWithModifiers2.js]
|
||||
var v = { get foo() {
|
||||
} };
|
|
@ -1,12 +1,9 @@
|
|||
tests/cases/conformance/parser/ecmascript5/Accessors/parserAccessors10.ts(2,3): error TS1184: Modifiers cannot appear here.
|
||||
tests/cases/conformance/parser/ecmascript5/Accessors/parserAccessors10.ts(2,14): error TS2378: A 'get' accessor must return a value or consist of a single 'throw' statement.
|
||||
|
||||
|
||||
==== tests/cases/conformance/parser/ecmascript5/Accessors/parserAccessors10.ts (2 errors) ====
|
||||
==== tests/cases/conformance/parser/ecmascript5/Accessors/parserAccessors10.ts (1 errors) ====
|
||||
var v = {
|
||||
public get foo() { }
|
||||
~~~~~~
|
||||
!!! error TS1184: Modifiers cannot appear here.
|
||||
~~~
|
||||
!!! error TS2378: A 'get' accessor must return a value or consist of a single 'throw' statement.
|
||||
};
|
Loading…
Reference in a new issue