mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 03:23:08 -06:00
Merge pull request #12895 from Microsoft/vladima/merge-master
merge master into release-2.1
This commit is contained in:
commit
051648ca91
@ -16581,6 +16581,10 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getParameterTypeNodeForDecoratorCheck(node: ParameterDeclaration): TypeNode {
|
||||
return node.dotDotDotToken ? getRestParameterElementType(node.type) : node.type;
|
||||
}
|
||||
|
||||
/** Check the decorators of a node */
|
||||
function checkDecorators(node: Node): void {
|
||||
if (!node.decorators) {
|
||||
@ -16612,7 +16616,7 @@ namespace ts {
|
||||
const constructor = getFirstConstructorWithBody(<ClassDeclaration>node);
|
||||
if (constructor) {
|
||||
for (const parameter of constructor.parameters) {
|
||||
markTypeNodeAsReferenced(parameter.type);
|
||||
markTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -16621,15 +16625,17 @@ namespace ts {
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
for (const parameter of (<FunctionLikeDeclaration>node).parameters) {
|
||||
markTypeNodeAsReferenced(parameter.type);
|
||||
markTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter));
|
||||
}
|
||||
|
||||
markTypeNodeAsReferenced((<FunctionLikeDeclaration>node).type);
|
||||
break;
|
||||
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
markTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(<ParameterDeclaration>node));
|
||||
break;
|
||||
case SyntaxKind.Parameter:
|
||||
markTypeNodeAsReferenced((<PropertyDeclaration | ParameterDeclaration>node).type);
|
||||
markTypeNodeAsReferenced((<PropertyDeclaration>node).type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -156,6 +156,9 @@ namespace ts {
|
||||
|
||||
if (!skipTrailingComments) {
|
||||
emitLeadingComments(detachedRange.end, /*isEmittedNode*/ true);
|
||||
if (hasWrittenComment && !writer.isAtStartOfLine()) {
|
||||
writer.writeLine();
|
||||
}
|
||||
}
|
||||
|
||||
if (extendedDiagnostics) {
|
||||
|
||||
@ -101,20 +101,21 @@ namespace ts {
|
||||
// So the helper will be emit at the correct position instead of at the top of the source-file
|
||||
const moduleName = tryGetModuleNameFromFile(node, host, compilerOptions);
|
||||
const dependencies = createArrayLiteral(map(dependencyGroups, dependencyGroup => dependencyGroup.name));
|
||||
const updated = updateSourceFileNode(
|
||||
node,
|
||||
createNodeArray([
|
||||
createStatement(
|
||||
createCall(
|
||||
createPropertyAccess(createIdentifier("System"), "register"),
|
||||
const updated = setEmitFlags(
|
||||
updateSourceFileNode(
|
||||
node,
|
||||
createNodeArray([
|
||||
createStatement(
|
||||
createCall(
|
||||
createPropertyAccess(createIdentifier("System"), "register"),
|
||||
/*typeArguments*/ undefined,
|
||||
moduleName
|
||||
? [moduleName, dependencies, moduleBodyFunction]
|
||||
: [dependencies, moduleBodyFunction]
|
||||
moduleName
|
||||
? [moduleName, dependencies, moduleBodyFunction]
|
||||
: [dependencies, moduleBodyFunction]
|
||||
)
|
||||
)
|
||||
)
|
||||
], node.statements)
|
||||
);
|
||||
], node.statements)
|
||||
), EmitFlags.NoTrailingComments);
|
||||
|
||||
if (!(compilerOptions.outFile || compilerOptions.out)) {
|
||||
moveEmitHelpers(updated, moduleBodyBlock, helper => !helper.scoped);
|
||||
|
||||
@ -1577,24 +1577,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the most likely element type for a TypeNode. This is not an exhaustive test
|
||||
* as it assumes a rest argument can only be an array type (either T[], or Array<T>).
|
||||
*
|
||||
* @param node The type node.
|
||||
*/
|
||||
function getRestParameterElementType(node: TypeNode) {
|
||||
if (node && node.kind === SyntaxKind.ArrayType) {
|
||||
return (<ArrayTypeNode>node).elementType;
|
||||
}
|
||||
else if (node && node.kind === SyntaxKind.TypeReference) {
|
||||
return singleOrUndefined((<TypeReferenceNode>node).typeArguments);
|
||||
}
|
||||
else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes the types of the parameters of a node for use with decorator type metadata.
|
||||
*
|
||||
|
||||
@ -803,6 +803,23 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the most likely element type for a TypeNode. This is not an exhaustive test
|
||||
* as it assumes a rest argument can only be an array type (either T[], or Array<T>).
|
||||
*
|
||||
* @param node The type node.
|
||||
*/
|
||||
export function getRestParameterElementType(node: TypeNode) {
|
||||
if (node && node.kind === SyntaxKind.ArrayType) {
|
||||
return (<ArrayTypeNode>node).elementType;
|
||||
}
|
||||
else if (node && node.kind === SyntaxKind.TypeReference) {
|
||||
return singleOrUndefined((<TypeReferenceNode>node).typeArguments);
|
||||
}
|
||||
else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export function isVariableLike(node: Node): node is VariableLikeDeclaration {
|
||||
if (node) {
|
||||
|
||||
@ -1238,6 +1238,7 @@ namespace ts.projectSystem {
|
||||
projectService.closeExternalProject(externalProjectName);
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 0 });
|
||||
});
|
||||
|
||||
it("external project with included config file opened after configured project and then closed", () => {
|
||||
const file1 = {
|
||||
path: "/a/b/f1.ts",
|
||||
@ -1797,6 +1798,49 @@ namespace ts.projectSystem {
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 0 });
|
||||
});
|
||||
|
||||
it("language service disabled state is updated in external projects", () => {
|
||||
debugger
|
||||
const f1 = {
|
||||
path: "/a/app.js",
|
||||
content: "var x = 1"
|
||||
};
|
||||
const f2 = {
|
||||
path: "/a/largefile.js",
|
||||
content: ""
|
||||
};
|
||||
const host = createServerHost([f1, f2]);
|
||||
const originalGetFileSize = host.getFileSize;
|
||||
host.getFileSize = (filePath: string) =>
|
||||
filePath === f2.path ? server.maxProgramSizeForNonTsFiles + 1 : originalGetFileSize.call(host, filePath);
|
||||
|
||||
const service = createProjectService(host);
|
||||
const projectFileName = "/a/proj.csproj";
|
||||
|
||||
service.openExternalProject({
|
||||
projectFileName,
|
||||
rootFiles: toExternalFiles([f1.path, f2.path]),
|
||||
options: {}
|
||||
});
|
||||
service.checkNumberOfProjects({ externalProjects: 1 });
|
||||
assert.isFalse(service.externalProjects[0].languageServiceEnabled, "language service should be disabled - 1");
|
||||
|
||||
service.openExternalProject({
|
||||
projectFileName,
|
||||
rootFiles: toExternalFiles([f1.path]),
|
||||
options: {}
|
||||
});
|
||||
service.checkNumberOfProjects({ externalProjects: 1 });
|
||||
assert.isTrue(service.externalProjects[0].languageServiceEnabled, "language service should be enabled");
|
||||
|
||||
service.openExternalProject({
|
||||
projectFileName,
|
||||
rootFiles: toExternalFiles([f1.path, f2.path]),
|
||||
options: {}
|
||||
});
|
||||
service.checkNumberOfProjects({ externalProjects: 1 });
|
||||
assert.isFalse(service.externalProjects[0].languageServiceEnabled, "language service should be disabled - 2");
|
||||
});
|
||||
|
||||
it("language service disabled events are triggered", () => {
|
||||
const f1 = {
|
||||
path: "/a/app.js",
|
||||
|
||||
@ -75,17 +75,32 @@ namespace ts.server {
|
||||
getFilesAffectedBy(scriptInfo: ScriptInfo): string[];
|
||||
onProjectUpdateGraph(): void;
|
||||
emitFile(scriptInfo: ScriptInfo, writeFile: (path: string, data: string, writeByteOrderMark?: boolean) => void): boolean;
|
||||
clear(): void;
|
||||
}
|
||||
|
||||
abstract class AbstractBuilder<T extends BuilderFileInfo> implements Builder {
|
||||
|
||||
private fileInfos = createFileMap<T>();
|
||||
/**
|
||||
* stores set of files from the project.
|
||||
* NOTE: this field is created on demand and should not be accessed directly.
|
||||
* Use 'getFileInfos' instead.
|
||||
*/
|
||||
private fileInfos_doNotAccessDirectly: FileMap<T>;
|
||||
|
||||
constructor(public readonly project: Project, private ctor: { new (scriptInfo: ScriptInfo, project: Project): T }) {
|
||||
}
|
||||
|
||||
private getFileInfos() {
|
||||
return this.fileInfos_doNotAccessDirectly || (this.fileInfos_doNotAccessDirectly = createFileMap<T>());
|
||||
}
|
||||
|
||||
public clear() {
|
||||
// drop the existing list - it will be re-created as necessary
|
||||
this.fileInfos_doNotAccessDirectly = undefined;
|
||||
}
|
||||
|
||||
protected getFileInfo(path: Path): T {
|
||||
return this.fileInfos.get(path);
|
||||
return this.getFileInfos().get(path);
|
||||
}
|
||||
|
||||
protected getOrCreateFileInfo(path: Path): T {
|
||||
@ -99,19 +114,19 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
protected getFileInfoPaths(): Path[] {
|
||||
return this.fileInfos.getKeys();
|
||||
return this.getFileInfos().getKeys();
|
||||
}
|
||||
|
||||
protected setFileInfo(path: Path, info: T) {
|
||||
this.fileInfos.set(path, info);
|
||||
this.getFileInfos().set(path, info);
|
||||
}
|
||||
|
||||
protected removeFileInfo(path: Path) {
|
||||
this.fileInfos.remove(path);
|
||||
this.getFileInfos().remove(path);
|
||||
}
|
||||
|
||||
protected forEachFileInfo(action: (fileInfo: T) => any) {
|
||||
this.fileInfos.forEachValue((_path, value) => action(value));
|
||||
this.getFileInfos().forEachValue((_path, value) => action(value));
|
||||
}
|
||||
|
||||
abstract getFilesAffectedBy(scriptInfo: ScriptInfo): string[];
|
||||
@ -231,6 +246,11 @@ namespace ts.server {
|
||||
|
||||
private projectVersionForDependencyGraph: string;
|
||||
|
||||
public clear() {
|
||||
this.projectVersionForDependencyGraph = undefined;
|
||||
super.clear();
|
||||
}
|
||||
|
||||
private getReferencedFileInfos(fileInfo: ModuleBuilderFileInfo): ModuleBuilderFileInfo[] {
|
||||
if (!fileInfo.isExternalModuleOrHasOnlyAmbientExternalModules()) {
|
||||
return [];
|
||||
|
||||
@ -126,7 +126,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
export interface OpenConfiguredProjectResult {
|
||||
configFileName?: string;
|
||||
configFileName?: NormalizedPath;
|
||||
configFileErrors?: Diagnostic[];
|
||||
}
|
||||
|
||||
@ -659,6 +659,13 @@ namespace ts.server {
|
||||
// open file in inferred project
|
||||
(projectsToRemove || (projectsToRemove = [])).push(p);
|
||||
}
|
||||
|
||||
if (!p.languageServiceEnabled) {
|
||||
// if project language service is disabled then we create a program only for open files.
|
||||
// this means that project should be marked as dirty to force rebuilding of the program
|
||||
// on the next request
|
||||
p.markAsDirty();
|
||||
}
|
||||
}
|
||||
if (projectsToRemove) {
|
||||
for (const project of projectsToRemove) {
|
||||
@ -1052,9 +1059,7 @@ namespace ts.server {
|
||||
project.stopWatchingDirectory();
|
||||
}
|
||||
else {
|
||||
if (!project.languageServiceEnabled) {
|
||||
project.enableLanguageService();
|
||||
}
|
||||
project.enableLanguageService();
|
||||
this.watchConfigDirectoryForProject(project, projectOptions);
|
||||
this.updateNonInferredProject(project, projectOptions.files, fileNamePropertyReader, projectOptions.compilerOptions, projectOptions.typeAcquisition, projectOptions.compileOnSave, configFileErrors);
|
||||
}
|
||||
@ -1226,9 +1231,22 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
openClientFileWithNormalizedPath(fileName: NormalizedPath, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean): OpenConfiguredProjectResult {
|
||||
const { configFileName = undefined, configFileErrors = undefined }: OpenConfiguredProjectResult = this.findContainingExternalProject(fileName)
|
||||
? {}
|
||||
: this.openOrUpdateConfiguredProjectForFile(fileName);
|
||||
let configFileName: NormalizedPath;
|
||||
let configFileErrors: Diagnostic[];
|
||||
|
||||
let project: ConfiguredProject | ExternalProject = this.findContainingExternalProject(fileName);
|
||||
if (!project) {
|
||||
({ configFileName, configFileErrors } = this.openOrUpdateConfiguredProjectForFile(fileName));
|
||||
if (configFileName) {
|
||||
project = this.findConfiguredProjectByProjectName(configFileName);
|
||||
}
|
||||
}
|
||||
if (project && !project.languageServiceEnabled) {
|
||||
// if project language service is disabled then we create a program only for open files.
|
||||
// this means that project should be marked as dirty to force rebuilding of the program
|
||||
// on the next request
|
||||
project.markAsDirty();
|
||||
}
|
||||
|
||||
// at this point if file is the part of some configured/external project then this project should be created
|
||||
const info = this.getOrCreateScriptInfoForNormalizedPath(fileName, /*openedByClient*/ true, fileContent, scriptKind, hasMixedContent);
|
||||
@ -1392,8 +1410,15 @@ namespace ts.server {
|
||||
let exisingConfigFiles: string[];
|
||||
if (externalProject) {
|
||||
if (!tsConfigFiles) {
|
||||
const compilerOptions = convertCompilerOptions(proj.options);
|
||||
if (this.exceededTotalSizeLimitForNonTsFiles(compilerOptions, proj.rootFiles, externalFilePropertyReader)) {
|
||||
externalProject.disableLanguageService();
|
||||
}
|
||||
else {
|
||||
externalProject.enableLanguageService();
|
||||
}
|
||||
// external project already exists and not config files were added - update the project and return;
|
||||
this.updateNonInferredProject(externalProject, proj.rootFiles, externalFilePropertyReader, convertCompilerOptions(proj.options), proj.typeAcquisition, proj.options.compileOnSave, /*configFileErrors*/ undefined);
|
||||
this.updateNonInferredProject(externalProject, proj.rootFiles, externalFilePropertyReader, compilerOptions, proj.typeAcquisition, proj.options.compileOnSave, /*configFileErrors*/ undefined);
|
||||
return;
|
||||
}
|
||||
// some config files were added to external project (that previously were not there)
|
||||
|
||||
@ -90,87 +90,6 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
const emptyResult: any[] = [];
|
||||
const getEmptyResult = () => emptyResult;
|
||||
const getUndefined = () => <any>undefined;
|
||||
const emptyEncodedSemanticClassifications = { spans: emptyResult, endOfLineState: EndOfLineState.None };
|
||||
|
||||
export function createNoSemanticFeaturesWrapper(realLanguageService: LanguageService): LanguageService {
|
||||
return {
|
||||
cleanupSemanticCache: noop,
|
||||
getSyntacticDiagnostics: (fileName) =>
|
||||
fileName ? realLanguageService.getSyntacticDiagnostics(fileName) : emptyResult,
|
||||
getSemanticDiagnostics: getEmptyResult,
|
||||
getCompilerOptionsDiagnostics: () =>
|
||||
realLanguageService.getCompilerOptionsDiagnostics(),
|
||||
getSyntacticClassifications: (fileName, span) =>
|
||||
realLanguageService.getSyntacticClassifications(fileName, span),
|
||||
getEncodedSyntacticClassifications: (fileName, span) =>
|
||||
realLanguageService.getEncodedSyntacticClassifications(fileName, span),
|
||||
getSemanticClassifications: getEmptyResult,
|
||||
getEncodedSemanticClassifications: () =>
|
||||
emptyEncodedSemanticClassifications,
|
||||
getCompletionsAtPosition: getUndefined,
|
||||
findReferences: getEmptyResult,
|
||||
getCompletionEntryDetails: getUndefined,
|
||||
getQuickInfoAtPosition: getUndefined,
|
||||
findRenameLocations: getEmptyResult,
|
||||
getNameOrDottedNameSpan: (fileName, startPos, endPos) =>
|
||||
realLanguageService.getNameOrDottedNameSpan(fileName, startPos, endPos),
|
||||
getBreakpointStatementAtPosition: (fileName, position) =>
|
||||
realLanguageService.getBreakpointStatementAtPosition(fileName, position),
|
||||
getBraceMatchingAtPosition: (fileName, position) =>
|
||||
realLanguageService.getBraceMatchingAtPosition(fileName, position),
|
||||
getSignatureHelpItems: getUndefined,
|
||||
getDefinitionAtPosition: getEmptyResult,
|
||||
getRenameInfo: () => ({
|
||||
canRename: false,
|
||||
localizedErrorMessage: getLocaleSpecificMessage(Diagnostics.Language_service_is_disabled),
|
||||
displayName: undefined,
|
||||
fullDisplayName: undefined,
|
||||
kind: undefined,
|
||||
kindModifiers: undefined,
|
||||
triggerSpan: undefined
|
||||
}),
|
||||
getTypeDefinitionAtPosition: getUndefined,
|
||||
getReferencesAtPosition: getEmptyResult,
|
||||
getDocumentHighlights: getEmptyResult,
|
||||
getOccurrencesAtPosition: getEmptyResult,
|
||||
getNavigateToItems: getEmptyResult,
|
||||
getNavigationBarItems: fileName =>
|
||||
realLanguageService.getNavigationBarItems(fileName),
|
||||
getNavigationTree: fileName =>
|
||||
realLanguageService.getNavigationTree(fileName),
|
||||
getOutliningSpans: fileName =>
|
||||
realLanguageService.getOutliningSpans(fileName),
|
||||
getTodoComments: getEmptyResult,
|
||||
getIndentationAtPosition: (fileName, position, options) =>
|
||||
realLanguageService.getIndentationAtPosition(fileName, position, options),
|
||||
getFormattingEditsForRange: (fileName, start, end, options) =>
|
||||
realLanguageService.getFormattingEditsForRange(fileName, start, end, options),
|
||||
getFormattingEditsForDocument: (fileName, options) =>
|
||||
realLanguageService.getFormattingEditsForDocument(fileName, options),
|
||||
getFormattingEditsAfterKeystroke: (fileName, position, key, options) =>
|
||||
realLanguageService.getFormattingEditsAfterKeystroke(fileName, position, key, options),
|
||||
getDocCommentTemplateAtPosition: (fileName, position) =>
|
||||
realLanguageService.getDocCommentTemplateAtPosition(fileName, position),
|
||||
isValidBraceCompletionAtPosition: (fileName, position, openingBrace) =>
|
||||
realLanguageService.isValidBraceCompletionAtPosition(fileName, position, openingBrace),
|
||||
getEmitOutput: getUndefined,
|
||||
getProgram: () =>
|
||||
realLanguageService.getProgram(),
|
||||
getNonBoundSourceFile: fileName =>
|
||||
realLanguageService.getNonBoundSourceFile(fileName),
|
||||
dispose: () =>
|
||||
realLanguageService.dispose(),
|
||||
getCompletionEntrySymbol: getUndefined,
|
||||
getImplementationAtPosition: getEmptyResult,
|
||||
getSourceFile: fileName =>
|
||||
realLanguageService.getSourceFile(fileName),
|
||||
getCodeFixesAtPosition: getEmptyResult
|
||||
};
|
||||
}
|
||||
|
||||
export abstract class Project {
|
||||
private rootFiles: ScriptInfo[] = [];
|
||||
private rootFilesMap: FileMap<ScriptInfo> = createFileMap<ScriptInfo>();
|
||||
@ -181,8 +100,6 @@ namespace ts.server {
|
||||
private lastCachedUnresolvedImportsList: SortedReadonlyArray<string>;
|
||||
|
||||
private readonly languageService: LanguageService;
|
||||
// wrapper over the real language service that will suppress all semantic operations
|
||||
private readonly noSemanticFeaturesLanguageService: LanguageService;
|
||||
|
||||
public languageServiceEnabled = true;
|
||||
|
||||
@ -258,7 +175,6 @@ namespace ts.server {
|
||||
this.lsHost.setCompilationSettings(this.compilerOptions);
|
||||
|
||||
this.languageService = ts.createLanguageService(this.lsHost, this.documentRegistry);
|
||||
this.noSemanticFeaturesLanguageService = createNoSemanticFeaturesWrapper(this.languageService);
|
||||
|
||||
if (!languageServiceEnabled) {
|
||||
this.disableLanguageService();
|
||||
@ -282,9 +198,7 @@ namespace ts.server {
|
||||
if (ensureSynchronized) {
|
||||
this.updateGraph();
|
||||
}
|
||||
return this.languageServiceEnabled
|
||||
? this.languageService
|
||||
: this.noSemanticFeaturesLanguageService;
|
||||
return this.languageService;
|
||||
}
|
||||
|
||||
getCompileOnSaveAffectedFileList(scriptInfo: ScriptInfo): string[] {
|
||||
@ -373,7 +287,10 @@ namespace ts.server {
|
||||
const result: string[] = [];
|
||||
if (this.rootFiles) {
|
||||
for (const f of this.rootFiles) {
|
||||
result.push(f.fileName);
|
||||
if (this.languageServiceEnabled || f.isScriptOpen()) {
|
||||
// if language service is disabled - process only files that are open
|
||||
result.push(f.fileName);
|
||||
}
|
||||
}
|
||||
if (this.typingFiles) {
|
||||
for (const f of this.typingFiles) {
|
||||
@ -389,6 +306,10 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
getScriptInfos() {
|
||||
if (!this.languageServiceEnabled) {
|
||||
// if language service is not enabled - return just root files
|
||||
return this.rootFiles;
|
||||
}
|
||||
return map(this.program.getSourceFiles(), sourceFile => {
|
||||
const scriptInfo = this.projectService.getScriptInfoForPath(sourceFile.path);
|
||||
if (!scriptInfo) {
|
||||
@ -529,10 +450,6 @@ namespace ts.server {
|
||||
* @returns: true if set of files in the project stays the same and false - otherwise.
|
||||
*/
|
||||
updateGraph(): boolean {
|
||||
if (!this.languageServiceEnabled) {
|
||||
return true;
|
||||
}
|
||||
|
||||
this.lsHost.startRecordingFilesWithChangedResolutions();
|
||||
|
||||
let hasChanges = this.updateGraphWorker();
|
||||
@ -564,6 +481,16 @@ namespace ts.server {
|
||||
if (this.setTypings(cachedTypings)) {
|
||||
hasChanges = this.updateGraphWorker() || hasChanges;
|
||||
}
|
||||
|
||||
// update builder only if language service is enabled
|
||||
// otherwise tell it to drop its internal state
|
||||
if (this.languageServiceEnabled) {
|
||||
this.builder.onProjectUpdateGraph();
|
||||
}
|
||||
else {
|
||||
this.builder.clear();
|
||||
}
|
||||
|
||||
if (hasChanges) {
|
||||
this.projectStructureVersion++;
|
||||
}
|
||||
@ -602,7 +529,6 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
}
|
||||
this.builder.onProjectUpdateGraph();
|
||||
return hasChanges;
|
||||
}
|
||||
|
||||
@ -673,7 +599,8 @@ namespace ts.server {
|
||||
projectName: this.getProjectName(),
|
||||
version: this.projectStructureVersion,
|
||||
isInferred: this.projectKind === ProjectKind.Inferred,
|
||||
options: this.getCompilerOptions()
|
||||
options: this.getCompilerOptions(),
|
||||
languageServiceDisabled: !this.languageServiceEnabled
|
||||
};
|
||||
const updatedFileNames = this.updatedFileNames;
|
||||
this.updatedFileNames = undefined;
|
||||
|
||||
@ -904,6 +904,11 @@ namespace ts.server.protocol {
|
||||
* Current set of compiler options for project
|
||||
*/
|
||||
options: ts.CompilerOptions;
|
||||
|
||||
/**
|
||||
* true if project language service is disabled
|
||||
*/
|
||||
languageServiceDisabled: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1028,6 +1028,9 @@ namespace ts.server {
|
||||
if (!project) {
|
||||
Errors.ThrowNoProject();
|
||||
}
|
||||
if (!project.languageServiceEnabled) {
|
||||
return false;
|
||||
}
|
||||
const scriptInfo = project.getScriptInfo(file);
|
||||
return project.builder.emitFile(scriptInfo, (path, data, writeByteOrderMark) => this.host.writeFile(path, data, writeByteOrderMark));
|
||||
}
|
||||
|
||||
@ -0,0 +1,112 @@
|
||||
//// [tests/cases/compiler/decoratorMetadataRestParameterWithImportedType.ts] ////
|
||||
|
||||
//// [aux.ts]
|
||||
|
||||
export class SomeClass {
|
||||
field: string;
|
||||
}
|
||||
|
||||
//// [aux1.ts]
|
||||
export class SomeClass1 {
|
||||
field: string;
|
||||
}
|
||||
|
||||
//// [aux2.ts]
|
||||
export class SomeClass2 {
|
||||
field: string;
|
||||
}
|
||||
//// [main.ts]
|
||||
import { SomeClass } from './aux';
|
||||
import { SomeClass1 } from './aux1';
|
||||
|
||||
function annotation(): ClassDecorator {
|
||||
return (target: any): void => { };
|
||||
}
|
||||
|
||||
function annotation1(): MethodDecorator {
|
||||
return (target: any): void => { };
|
||||
}
|
||||
|
||||
@annotation()
|
||||
export class ClassA {
|
||||
array: SomeClass[];
|
||||
|
||||
constructor(...init: SomeClass[]) {
|
||||
this.array = init;
|
||||
}
|
||||
|
||||
@annotation1()
|
||||
foo(... args: SomeClass1[]) {
|
||||
}
|
||||
}
|
||||
|
||||
//// [aux.js]
|
||||
"use strict";
|
||||
var SomeClass = (function () {
|
||||
function SomeClass() {
|
||||
}
|
||||
return SomeClass;
|
||||
}());
|
||||
exports.SomeClass = SomeClass;
|
||||
//// [aux1.js]
|
||||
"use strict";
|
||||
var SomeClass1 = (function () {
|
||||
function SomeClass1() {
|
||||
}
|
||||
return SomeClass1;
|
||||
}());
|
||||
exports.SomeClass1 = SomeClass1;
|
||||
//// [aux2.js]
|
||||
"use strict";
|
||||
var SomeClass2 = (function () {
|
||||
function SomeClass2() {
|
||||
}
|
||||
return SomeClass2;
|
||||
}());
|
||||
exports.SomeClass2 = SomeClass2;
|
||||
//// [main.js]
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
var aux_1 = require("./aux");
|
||||
var aux1_1 = require("./aux1");
|
||||
function annotation() {
|
||||
return function (target) { };
|
||||
}
|
||||
function annotation1() {
|
||||
return function (target) { };
|
||||
}
|
||||
var ClassA = (function () {
|
||||
function ClassA() {
|
||||
var init = [];
|
||||
for (var _i = 0; _i < arguments.length; _i++) {
|
||||
init[_i] = arguments[_i];
|
||||
}
|
||||
this.array = init;
|
||||
}
|
||||
ClassA.prototype.foo = function () {
|
||||
var args = [];
|
||||
for (var _i = 0; _i < arguments.length; _i++) {
|
||||
args[_i] = arguments[_i];
|
||||
}
|
||||
};
|
||||
return ClassA;
|
||||
}());
|
||||
__decorate([
|
||||
annotation1(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [aux1_1.SomeClass1]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], ClassA.prototype, "foo", null);
|
||||
ClassA = __decorate([
|
||||
annotation(),
|
||||
__metadata("design:paramtypes", [aux_1.SomeClass])
|
||||
], ClassA);
|
||||
exports.ClassA = ClassA;
|
||||
@ -0,0 +1,77 @@
|
||||
=== tests/cases/compiler/aux.ts ===
|
||||
|
||||
export class SomeClass {
|
||||
>SomeClass : Symbol(SomeClass, Decl(aux.ts, 0, 0))
|
||||
|
||||
field: string;
|
||||
>field : Symbol(SomeClass.field, Decl(aux.ts, 1, 24))
|
||||
}
|
||||
|
||||
=== tests/cases/compiler/aux1.ts ===
|
||||
export class SomeClass1 {
|
||||
>SomeClass1 : Symbol(SomeClass1, Decl(aux1.ts, 0, 0))
|
||||
|
||||
field: string;
|
||||
>field : Symbol(SomeClass1.field, Decl(aux1.ts, 0, 25))
|
||||
}
|
||||
|
||||
=== tests/cases/compiler/aux2.ts ===
|
||||
export class SomeClass2 {
|
||||
>SomeClass2 : Symbol(SomeClass2, Decl(aux2.ts, 0, 0))
|
||||
|
||||
field: string;
|
||||
>field : Symbol(SomeClass2.field, Decl(aux2.ts, 0, 25))
|
||||
}
|
||||
=== tests/cases/compiler/main.ts ===
|
||||
import { SomeClass } from './aux';
|
||||
>SomeClass : Symbol(SomeClass, Decl(main.ts, 0, 8))
|
||||
|
||||
import { SomeClass1 } from './aux1';
|
||||
>SomeClass1 : Symbol(SomeClass1, Decl(main.ts, 1, 8))
|
||||
|
||||
function annotation(): ClassDecorator {
|
||||
>annotation : Symbol(annotation, Decl(main.ts, 1, 36))
|
||||
>ClassDecorator : Symbol(ClassDecorator, Decl(lib.d.ts, --, --))
|
||||
|
||||
return (target: any): void => { };
|
||||
>target : Symbol(target, Decl(main.ts, 4, 12))
|
||||
}
|
||||
|
||||
function annotation1(): MethodDecorator {
|
||||
>annotation1 : Symbol(annotation1, Decl(main.ts, 5, 1))
|
||||
>MethodDecorator : Symbol(MethodDecorator, Decl(lib.d.ts, --, --))
|
||||
|
||||
return (target: any): void => { };
|
||||
>target : Symbol(target, Decl(main.ts, 8, 12))
|
||||
}
|
||||
|
||||
@annotation()
|
||||
>annotation : Symbol(annotation, Decl(main.ts, 1, 36))
|
||||
|
||||
export class ClassA {
|
||||
>ClassA : Symbol(ClassA, Decl(main.ts, 9, 1))
|
||||
|
||||
array: SomeClass[];
|
||||
>array : Symbol(ClassA.array, Decl(main.ts, 12, 21))
|
||||
>SomeClass : Symbol(SomeClass, Decl(main.ts, 0, 8))
|
||||
|
||||
constructor(...init: SomeClass[]) {
|
||||
>init : Symbol(init, Decl(main.ts, 15, 16))
|
||||
>SomeClass : Symbol(SomeClass, Decl(main.ts, 0, 8))
|
||||
|
||||
this.array = init;
|
||||
>this.array : Symbol(ClassA.array, Decl(main.ts, 12, 21))
|
||||
>this : Symbol(ClassA, Decl(main.ts, 9, 1))
|
||||
>array : Symbol(ClassA.array, Decl(main.ts, 12, 21))
|
||||
>init : Symbol(init, Decl(main.ts, 15, 16))
|
||||
}
|
||||
|
||||
@annotation1()
|
||||
>annotation1 : Symbol(annotation1, Decl(main.ts, 5, 1))
|
||||
|
||||
foo(... args: SomeClass1[]) {
|
||||
>foo : Symbol(ClassA.foo, Decl(main.ts, 17, 5))
|
||||
>args : Symbol(args, Decl(main.ts, 20, 8))
|
||||
>SomeClass1 : Symbol(SomeClass1, Decl(main.ts, 1, 8))
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,82 @@
|
||||
=== tests/cases/compiler/aux.ts ===
|
||||
|
||||
export class SomeClass {
|
||||
>SomeClass : SomeClass
|
||||
|
||||
field: string;
|
||||
>field : string
|
||||
}
|
||||
|
||||
=== tests/cases/compiler/aux1.ts ===
|
||||
export class SomeClass1 {
|
||||
>SomeClass1 : SomeClass1
|
||||
|
||||
field: string;
|
||||
>field : string
|
||||
}
|
||||
|
||||
=== tests/cases/compiler/aux2.ts ===
|
||||
export class SomeClass2 {
|
||||
>SomeClass2 : SomeClass2
|
||||
|
||||
field: string;
|
||||
>field : string
|
||||
}
|
||||
=== tests/cases/compiler/main.ts ===
|
||||
import { SomeClass } from './aux';
|
||||
>SomeClass : typeof SomeClass
|
||||
|
||||
import { SomeClass1 } from './aux1';
|
||||
>SomeClass1 : typeof SomeClass1
|
||||
|
||||
function annotation(): ClassDecorator {
|
||||
>annotation : () => ClassDecorator
|
||||
>ClassDecorator : ClassDecorator
|
||||
|
||||
return (target: any): void => { };
|
||||
>(target: any): void => { } : (target: any) => void
|
||||
>target : any
|
||||
}
|
||||
|
||||
function annotation1(): MethodDecorator {
|
||||
>annotation1 : () => MethodDecorator
|
||||
>MethodDecorator : MethodDecorator
|
||||
|
||||
return (target: any): void => { };
|
||||
>(target: any): void => { } : (target: any) => void
|
||||
>target : any
|
||||
}
|
||||
|
||||
@annotation()
|
||||
>annotation() : ClassDecorator
|
||||
>annotation : () => ClassDecorator
|
||||
|
||||
export class ClassA {
|
||||
>ClassA : ClassA
|
||||
|
||||
array: SomeClass[];
|
||||
>array : SomeClass[]
|
||||
>SomeClass : SomeClass
|
||||
|
||||
constructor(...init: SomeClass[]) {
|
||||
>init : SomeClass[]
|
||||
>SomeClass : SomeClass
|
||||
|
||||
this.array = init;
|
||||
>this.array = init : SomeClass[]
|
||||
>this.array : SomeClass[]
|
||||
>this : this
|
||||
>array : SomeClass[]
|
||||
>init : SomeClass[]
|
||||
}
|
||||
|
||||
@annotation1()
|
||||
>annotation1() : MethodDecorator
|
||||
>annotation1 : () => MethodDecorator
|
||||
|
||||
foo(... args: SomeClass1[]) {
|
||||
>foo : (...args: SomeClass1[]) => void
|
||||
>args : SomeClass1[]
|
||||
>SomeClass1 : SomeClass1
|
||||
}
|
||||
}
|
||||
18
tests/baselines/reference/systemModuleTrailingComments.js
Normal file
18
tests/baselines/reference/systemModuleTrailingComments.js
Normal file
@ -0,0 +1,18 @@
|
||||
//// [systemModuleTrailingComments.ts]
|
||||
export const test = "TEST";
|
||||
|
||||
//some comment
|
||||
|
||||
//// [systemModuleTrailingComments.js]
|
||||
System.register([], function (exports_1, context_1) {
|
||||
"use strict";
|
||||
var __moduleName = context_1 && context_1.id;
|
||||
var test;
|
||||
return {
|
||||
setters: [],
|
||||
execute: function () {
|
||||
exports_1("test", test = "TEST");
|
||||
//some comment
|
||||
}
|
||||
};
|
||||
});
|
||||
@ -0,0 +1,5 @@
|
||||
=== tests/cases/compiler/systemModuleTrailingComments.ts ===
|
||||
export const test = "TEST";
|
||||
>test : Symbol(test, Decl(systemModuleTrailingComments.ts, 0, 12))
|
||||
|
||||
//some comment
|
||||
@ -0,0 +1,6 @@
|
||||
=== tests/cases/compiler/systemModuleTrailingComments.ts ===
|
||||
export const test = "TEST";
|
||||
>test : "TEST"
|
||||
>"TEST" : "TEST"
|
||||
|
||||
//some comment
|
||||
@ -0,0 +1,42 @@
|
||||
// @experimentalDecorators: true
|
||||
// @emitDecoratorMetadata: true
|
||||
// @target: es5
|
||||
|
||||
// @filename: aux.ts
|
||||
export class SomeClass {
|
||||
field: string;
|
||||
}
|
||||
|
||||
// @filename: aux1.ts
|
||||
export class SomeClass1 {
|
||||
field: string;
|
||||
}
|
||||
|
||||
// @filename: aux2.ts
|
||||
export class SomeClass2 {
|
||||
field: string;
|
||||
}
|
||||
// @filename: main.ts
|
||||
import { SomeClass } from './aux';
|
||||
import { SomeClass1 } from './aux1';
|
||||
|
||||
function annotation(): ClassDecorator {
|
||||
return (target: any): void => { };
|
||||
}
|
||||
|
||||
function annotation1(): MethodDecorator {
|
||||
return (target: any): void => { };
|
||||
}
|
||||
|
||||
@annotation()
|
||||
export class ClassA {
|
||||
array: SomeClass[];
|
||||
|
||||
constructor(...init: SomeClass[]) {
|
||||
this.array = init;
|
||||
}
|
||||
|
||||
@annotation1()
|
||||
foo(... args: SomeClass1[]) {
|
||||
}
|
||||
}
|
||||
4
tests/cases/compiler/systemModuleTrailingComments.ts
Normal file
4
tests/cases/compiler/systemModuleTrailingComments.ts
Normal file
@ -0,0 +1,4 @@
|
||||
// @module: system
|
||||
export const test = "TEST";
|
||||
|
||||
//some comment
|
||||
Loading…
x
Reference in New Issue
Block a user