mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
added relaxed emit rules for separate compilation
This commit is contained in:
+16
-3
@@ -713,8 +713,14 @@ module ts {
|
||||
function markExportAsReferenced(node: ImportEqualsDeclaration | ExportAssignment | ExportSpecifier) {
|
||||
let symbol = getSymbolOfNode(node);
|
||||
let target = resolveAlias(symbol);
|
||||
if (target && target !== unknownSymbol && target.flags & SymbolFlags.Value && !isConstEnumOrConstEnumOnlyModule(target)) {
|
||||
markAliasSymbolAsReferenced(symbol);
|
||||
if (target) {
|
||||
let markAlias =
|
||||
(target === unknownSymbol && compilerOptions.separateCompilation) ||
|
||||
(target !== unknownSymbol && target.flags & SymbolFlags.Value && !isConstEnumOrConstEnumOnlyModule(target));
|
||||
|
||||
if (markAlias) {
|
||||
markAliasSymbolAsReferenced(symbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9745,7 +9751,9 @@ module ts {
|
||||
|
||||
checkKindsOfPropertyMemberOverrides(type, baseType);
|
||||
}
|
||||
}
|
||||
|
||||
if (type.baseTypes.length || (baseTypeNode && compilerOptions.separateCompilation)) {
|
||||
// Check that base type can be evaluated as expression
|
||||
checkExpressionOrQualifiedName(baseTypeNode.typeName);
|
||||
}
|
||||
@@ -11264,11 +11272,16 @@ module ts {
|
||||
// parent is not source file or it is not reference to internal module
|
||||
return false;
|
||||
}
|
||||
return isAliasResolvedToValue(getSymbolOfNode(node));
|
||||
|
||||
var isValue = isAliasResolvedToValue(getSymbolOfNode(node));
|
||||
return isValue && node.moduleReference && !nodeIsMissing(node.moduleReference);
|
||||
}
|
||||
|
||||
function isAliasResolvedToValue(symbol: Symbol): boolean {
|
||||
let target = resolveAlias(symbol);
|
||||
if (target === unknownSymbol && compilerOptions.separateCompilation) {
|
||||
return true;
|
||||
}
|
||||
// const enums and modules that contain only const enums are not considered values from the emit perespective
|
||||
return target !== unknownSymbol && target.flags & SymbolFlags.Value && !isConstEnumOrConstEnumOnlyModule(target);
|
||||
}
|
||||
|
||||
@@ -1587,6 +1587,7 @@ module ts {
|
||||
target?: ScriptTarget;
|
||||
version?: boolean;
|
||||
watch?: boolean;
|
||||
separateCompilation?: boolean;
|
||||
/* @internal */ stripInternal?: boolean;
|
||||
/* @internal */ preserveNewLines?: boolean;
|
||||
/* @internal */ cacheDownlevelForOfLength?: boolean;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user