Skip to content

Add editor configurable filename-based ATA #40952

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Oct 19, 2020

Conversation

jessetrinity
Copy link
Contributor

@jessetrinity jessetrinity commented Oct 5, 2020

Filename-based ATA is sometimes undesirable in external and inferred projects. This change allows that behavior to be configured without needing to add a tsconfig.

  • Adds disableFilenameBasedTypeAcquisition to typeAcquisition, to control whether or not typings are inferred based on .js filenames.
  • Allows typeAcquisition to be configured by editors for non-configured (no tsconfig) projects.

Fixes #40123

@typescript-bot
Copy link
Collaborator

Thanks for the PR! It looks like you've changed the TSServer protocol in some way. Please ensure that any changes here don't break consumers of the current TSServer API. For some extra review, we'll ping @sheetalkamat, @amcasey, @mjbvz, @minestarks for you. Feel free to loop in other consumers/maintainers if necessary

@typescript-bot typescript-bot added the For Milestone Bug PRs that fix a bug with a specific milestone label Oct 5, 2020
@@ -3515,7 +3523,7 @@ namespace ts.server {
const typeAcquisition = proj.typeAcquisition!;
Debug.assert(!!typeAcquisition, "proj.typeAcquisition should be set by now");
// If type acquisition has been explicitly disabled, do not exclude anything from the project
if (typeAcquisition.enable === false) {
if (typeAcquisition.enable === false || typeAcquisition.inferTypings === false) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Just to clarify - does applySafeList only apply in the "infer from filenames" case?

Copy link
Contributor Author

@jessetrinity jessetrinity Oct 5, 2020

Choose a reason for hiding this comment

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

It removes any project files that appear in the safe list from the project, and adds them to the include list (for which typings are installed unconditionally).

If there is a case where we want to avoid adding files to the include list and remove them from the project, then this would be wrong (but I'm not sure what that is).

@@ -3632,6 +3640,7 @@ namespace ts.server {
if (proj.typeAcquisition.enable === undefined) {
proj.typeAcquisition.enable = hasNoTypeScriptSource(proj.rootFiles.map(f => f.fileName));
}
proj.typeAcquisition.inferTypings = this.hostConfiguration.typeAcquisition?.inferTypings ?? true;
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm a little surprised by this - it seems like whatever the editor sends on the specific project is unconditionally overwritten by the host config. Is that intended?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That was my intent. Do you think we should sent the setting with openExternalProjects rather than making it configurable through configure?

I guess I don't understand why we would prefer that way.

Copy link
Member

Choose a reason for hiding this comment

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

Yes.. This should be part of open external projects

@@ -3632,6 +3640,7 @@ namespace ts.server {
if (proj.typeAcquisition.enable === undefined) {
proj.typeAcquisition.enable = hasNoTypeScriptSource(proj.rootFiles.map(f => f.fileName));
}
proj.typeAcquisition.inferTypings = this.hostConfiguration.typeAcquisition?.inferTypings ?? true;
Copy link
Member

Choose a reason for hiding this comment

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

This seems incorrect.. host.typeAcquisition shouldnt mean for all projects.. external project can configure its on options so it shouldnt use default configured thing at all

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I did intend for it to be global. For VS this would be under tools > options. Is there a more preferred way of configuring external projects?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should openExternalProjects handle the setting typeAcquisition for external projects and then only inferred projects get the setting from the host configuration?

Copy link
Contributor

Choose a reason for hiding this comment

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

IMO you would at least want to allow an external project to specify what it wants and fall back to the host config.

Copy link
Member

Choose a reason for hiding this comment

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

The setting should be only for inferred projects rather than all.. You should look at compilerOptions for inferred project as they can also differ with projectRoot. You would want similar.

@@ -294,6 +304,7 @@ namespace ts.server {
hostInfo: string;
extraFileExtensions?: FileExtensionInfo[];
watchOptions?: WatchOptions;
typeAcquisition?: TypeAcquisition;
Copy link
Member

Choose a reason for hiding this comment

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

You shouldn’t need this since the options are per project and there isn’t anything in host

@@ -5844,7 +5844,8 @@ namespace ts {
enable?: boolean;
include?: string[];
exclude?: string[];
[option: string]: string[] | boolean | undefined;
inferTypingsFromFilenames?: boolean;
Copy link
Member

Choose a reason for hiding this comment

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

I think you want apposite of this option so that current type acquisitions in config file behave as if this option is set to false. Ideally you want new behavior to kick in only when the option is set

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think I accounted for that, making so that the behavior is only disabled if explicitly set to false. I was imagining something like Enable/disable filename-based ATA as the text of the setting on the editor side, with it checked by default.

I suppose disableFilenameBasedTypeAcquisition works just as well.

@@ -1333,7 +1333,7 @@ namespace ts.server.protocol {
* For external projects, some of the project settings are sent together with
* compiler settings.
*/
export type ExternalProjectCompilerOptions = CompilerOptions & CompileOnSaveMixin & WatchOptions;
export type ExternalProjectCompilerOptions = CompilerOptions & CompileOnSaveMixin & WatchOptions & TypeAcquisition;
Copy link
Member

Choose a reason for hiding this comment

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

ExternalProject has options called typeAcquisition so this type shouldnt be changed.

Copy link
Member

Choose a reason for hiding this comment

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

You can create different type instead you should create a type
export type InferredProjectCompilerOptions = ExternalProjectCompilerOptions & TypeAcquisition and update the usage.

@@ -1827,11 +1831,16 @@ namespace ts.server {
super.close();
}

setTypeAcquisition(newTypeAcquisition: TypeAcquisition): void {
Copy link
Member

Choose a reason for hiding this comment

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

Wonder if if this.typeAcquisition and set method should be moved to Project since 3 project types use the same method.

enable: allRootFilesAreJsOrDts(this),
include: ts.emptyArray,
exclude: ts.emptyArray
exclude: ts.emptyArray,
disableFilenameBasedTypeAcquisition: false
Copy link
Member

Choose a reason for hiding this comment

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

I dont think you need to set this since this is optional

@sheetalkamat
Copy link
Member

You would want to wait for this merge if this is for 4.2 instead of 4.1 though

@jessetrinity
Copy link
Contributor Author

@sheetalkamat because it is a new feature rather than a bug fix, or because of the protocol changes?

@sheetalkamat
Copy link
Member

New feature.. i think we are past merging features to 4.1 .. @DanielRosenwasser and @RyanCavanaugh are keeping track of schedule.

@minestarks
Copy link
Member

I think this is OK for 4.1 but I'll double check with @DanielRosenwasser / @RyanCavanaugh

@DanielRosenwasser
Copy link
Member

I think that's probably okay, we can always pull it out post-release if we see issues with VS or VS Code Insiders. @mjbvz just to ensure everyone's aware that we're making ATA changes for JS projects.

@jessetrinity jessetrinity merged commit 08e4f36 into microsoft:master Oct 19, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
For Milestone Bug PRs that fix a bug with a specific milestone
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Automatic Type Acquisition based on filename matching pulls in too many irrelevant typings
6 participants