added relaxed emit rules for separate compilation

This commit is contained in:
Vladimir Matveev
2015-03-25 23:18:58 -07:00
parent 8610a881c3
commit a51f0bf8bb
3 changed files with 97 additions and 3 deletions

View File

@@ -1635,6 +1635,86 @@ module ts {
sourceFile.scriptSnapshot = scriptSnapshot;
}
export function transpile(input: string, compilerOptions?: CompilerOptions, fileName?: string, syntaxErrors?: Diagnostic[]): string {
let options = compilerOptions ? ts.clone(compilerOptions) : getDefaultCompilerOptions();
// Single file transformation is only guranteed to be correct if inside an external module.
// External modules have thier own scope and can not contribute to internal modules outside their
// scope.
if (options.target !== ScriptTarget.ES6 && (!options.module || options.module === ModuleKind.None)) {
// add errors
}
// In sigle file transformation the compiler does not have access to declaration sites.
// Const enum property access will not be detected if they are not in the same file as the enum.
// thus they are goign to be emitted as normal propety access. To ensure correct behaviour at runtime,
// we need to generare the actual enum object so that the proprty accesses do not fail.
options.preserveConstEnums = true;
// No reason to get declarations, we are only returning javascript
options.declaration = false;
// Filename can be non-ts file. We are not locating any modules as well, so allow
// non-ts extensions
options.allowNonTsExtensions = true;
// enable relaxed emit rules
options.separateCompilation = true;
// We are not resolving references or modules, or even including the library. Disabling
// emit on error will block generating the output and has no meaningful use here.
options.noEmitOnError = false;
// No resolution requests will be honered anyways. So do not do it
options.noResolve = true;
// TODO (vladima): add inlineSourceMap once it is checked in
//if (options.sourceMap) {
// // We need to return a single string, so inline the sourceMap in the output
// options.inlineSourceMap = true;;
//}
// Parse
var inputFileName = fileName || "module.ts";
var sourceFile = ts.createSourceFile(inputFileName, input, options.target);
// Store syntactic diagnostics
if (syntaxErrors && sourceFile.parseDiagnostics) {
syntaxErrors.push(...sourceFile.parseDiagnostics);
}
// Output
let outputText: string;
// Create a compilerHost object to allow the compiler to read and write files
var compilerHost: CompilerHost = {
getSourceFile: (fileName, target) => fileName === inputFileName ? sourceFile : undefined,
writeFile: (name, text, writeByteOrderMark) => {
if (ts.fileExtensionIs(name, ".js")) {
Debug.assert(outputText === undefined, "Unexpected multiple outputs for the file: " + name);
outputText = text;
}
},
getDefaultLibFileName: () => "lib.d.ts",
useCaseSensitiveFileNames: () => false,
getCanonicalFileName: fileName => fileName,
getCurrentDirectory: () => "",
getNewLine: () => "\r\n"
};
// Note: The emitter needs a the checker to walk the file, so we will create a program for this
// though single file transformation does not really need this. First we need to drop the emitter
// dependcy on the checker and then implement a new resolver that does not do the full check.
var program = ts.createProgram([inputFileName], options, compilerHost);
// Emit
program.emit();
Debug.assert(outputText !== undefined, "Output generation failed");
return outputText;
}
export function createLanguageServiceSourceFile(fileName: string, scriptSnapshot: IScriptSnapshot, scriptTarget: ScriptTarget, version: string, setNodeParents: boolean): SourceFile {
let sourceFile = createSourceFile(fileName, scriptSnapshot.getText(0, scriptSnapshot.getLength()), scriptTarget, setNodeParents);
setSourceFileFields(sourceFile, scriptSnapshot, version);