Skip to content

go-to-type-definition, and find-all-refs should work for import.meta #44364

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 7 commits into from
Feb 25, 2022

Conversation

Zzzen
Copy link
Contributor

@Zzzen Zzzen commented Jun 1, 2021

Fixes #24353

IIUC, import.meta have no corresponding symbol, and the general algorithm (find the symbol of node, find the type/references of symbol) will not work. So I just intercept them in the services.

@typescript-bot typescript-bot added the For Backlog Bug PRs that fix a backlog bug label Jun 1, 2021
function getAllReferencesForImportMeta(sourceFiles: readonly SourceFile[], cancellationToken: CancellationToken): SymbolAndEntries[] | undefined {
const references = flatMap(sourceFiles, sourceFile => {
cancellationToken.throwIfCancellationRequested();
return mapDefined(getPossibleSymbolReferenceNodes(sourceFile, "import.meta", sourceFile), node => {
Copy link
Member

Choose a reason for hiding this comment

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

This doesn't work in the presence of whitespace.

let x = import
  .  // hai :)
    meta;

I would change your search string to meta instead.

Copy link
Member

@DanielRosenwasser DanielRosenwasser left a comment

Choose a reason for hiding this comment

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

This looks good! I think I mostly just have a nit regarding what we consider a "definition" reference.

}
});
});
return references.length ? [{ definition: { type: DefinitionKind.Keyword, node: references[0].node }, references }] : undefined;
Copy link
Member

@DanielRosenwasser DanielRosenwasser Jun 3, 2021

Choose a reason for hiding this comment

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

I don't exactly know if you should be considering anything a "definition" location apart from the global ImportMeta interface.

Even that one is a little weird, because that's what you'd want if you requested "go-to-type", not necessarily "go-to-definition".

Do all responses require a definition? @jessetrinity and @andrewbranch might have more knowledge here.

Copy link
Member

Choose a reason for hiding this comment

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

The types imply that a definition isn’t required. My intuition is that this shouldn’t be one.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's copied from getAllReferencesForKeyword, which searches primitive types like string/number/any. They should have no definition either?

function getAllReferencesForKeyword(sourceFiles: readonly SourceFile[], keywordKind: SyntaxKind, cancellationToken: CancellationToken, filter?: (node: Node) => boolean): SymbolAndEntries[] | undefined {
    // ...
    return references.length ? [{ definition: { type: DefinitionKind.Keyword, node: references[0].node }, references }] : undefined;
}

Copy link
Member

Choose a reason for hiding this comment

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

I’m not 100% sure what the implications are for removing it—we should check with @mjbvz ad @uniqueiniquity.

Copy link
Member

Choose a reason for hiding this comment

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

Let’s get rid of the definition

Copy link
Contributor Author

@Zzzen Zzzen Feb 24, 2022

Choose a reason for hiding this comment

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

Only include referenced symbols that have a valid definition.

findReferencedSymbols won't work if definition is absent.

export function findReferencedSymbols(program: Program, cancellationToken: CancellationToken, sourceFiles: readonly SourceFile[], sourceFile: SourceFile, position: number): ReferencedSymbol[] | undefined {
const node = getTouchingPropertyName(sourceFile, position);
const referencedSymbols = Core.getReferencedSymbolsForNode(position, node, program, sourceFiles, cancellationToken, { use: FindReferencesUse.References });
const checker = program.getTypeChecker();
const symbol = checker.getSymbolAtLocation(node);
return !referencedSymbols || !referencedSymbols.length ? undefined : mapDefined<SymbolAndEntries, ReferencedSymbol>(referencedSymbols, ({ definition, references }) =>
// Only include referenced symbols that have a valid definition.
definition && {
definition: checker.runWithCancellationToken(cancellationToken, checker => definitionToReferencedSymbolDefinitionInfo(definition, checker, node)),
references: references.map(r => toReferenceEntry(r, symbol))
});
}

Copy link
Member

Choose a reason for hiding this comment

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

🤦 I swear all this stuff was just made up on the spot

}
});
});
return references.length ? [{ definition: { type: DefinitionKind.Keyword, node: references[0].node }, references }] : undefined;
Copy link
Member

Choose a reason for hiding this comment

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

Let’s get rid of the definition

@@ -0,0 +1 @@
[]
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn’t there be something here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ooops, it's empty because definition is removed. Currently definition is required. It might break vscode if we make it optional.

export interface ReferencedSymbol {
definition: ReferencedSymbolDefinitionInfo;
references: ReferenceEntry[];
}

}
});
});
return references.length ? [{ definition: { type: DefinitionKind.Keyword, node: references[0].node }, references }] : undefined;
Copy link
Member

Choose a reason for hiding this comment

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

🤦 I swear all this stuff was just made up on the spot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
For Backlog Bug PRs that fix a backlog bug
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

go-to-type-definition, and find-all-refs not working for import.meta
4 participants