I would like to make a tool to replace imports of old style to imports of new style:
// before
import dsa = require('data/search/account');
// after
import * as dsa from 'data/search/account';
is it possible to do via public compiler api?
if so, can anyone outline the steps?
another example is enforcing curly braces on if statements and such:
// before
if (isThis())
thenThat();
// after
if (isThis()) {
thenThat();
}
Ideally you could do this with #5595 (see also #3241), but until we have an API for that, you can use our language service API.
Then:
Something like this might work:
import * as ts from "typescript";
import * as fs from "fs";
interface Replacement {
start: number;
end: number;
replacementText: string;
}
function transformProgram(program: ts.Program) {
for (const file of program.getSourceFiles()) {
const replacements = getReplacements(file);
replacements.reverse();
const newText = getNewText(file.getText(), replacements);
fs.writeFileSync(file.fileName, newText);
}
}
function getReplacements(sourceFile: ts.SourceFile) {
const replacements: Replacement[] = [];
for (const statement of sourceFile.statements) {
if (statement.kind !== ts.SyntaxKind.ImportEqualsDeclaration) {
continue;
}
const importEquals = statement as ts.ImportEqualsDeclaration;
if (importEquals.moduleReference.kind !== ts.SyntaxKind.ExternalModuleReference) {
continue;
}
const importString = (importEquals.moduleReference as ts.ExternalModuleReference).expression as ts.StringLiteral;
if (!importString || importString.kind !== ts.SyntaxKind.StringLiteral) {
continue;
}
replacements.push({
start: statement.getStart(),
end: statement.getEnd(),
replacementText: `import ${ importEquals.name.getText() } from "${ importString.getText() }";`
});
}
return replacements;
}
function getNewText(sourceText: string, replacementsInReverse: Replacement[]) {
for (const { start, end, replacementText } of replacementsInReverse) {
sourceText = sourceText.slice(0, start) + replacementText + sourceText.slice(end)
}
return sourceText;
}
Don't hold me to it though, I haven't tested it out yet.
Also check out https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#pretty-printer-using-the-ls-formatter
Is it possible now to make source transformation using alternations in AST not via text replacement as shown?
When #5595 lands, yes... it should be in master soon
So https://github.com/Microsoft/TypeScript/issues/5595 seem to land? Is there some docs/info about transforming AST?
No, not yet... the team have been burning the midnight oil to get it into master. If you don't feel comfortable spelunking in the source code for TypeScript, I think you are going to have to wait a while until there is any sort of decent documentation. Likely though, especially when it comes to using the services and other internals of TypeScript, it is really up to the wider community to start providing the "how to" instead of official documentation.
@kitsonk Ok, thanks for response) I'm quite comfortable with source/tests code. Here is what I want to do:
1) I have a source TS file
2) Need to load it and get AST (I assume it is done using ts.createSourceFile)
3) Need a way to change AST (not sure how)
4) Compile changed AST
5) (as a bonus) Access resulting AST
Are step 3-5 possible now? If yest could you direct to the source that should be investigated?
We do not currently expose the transformation API as part of the language service. This is something we are considering. Once we make it available as a public API we will provide documentation on its use.
@rbuckton so it is not possible at all? ok can be hacked around?
i think he said that it is in private api that isnt exposed to public, can you use private API of TypeScript? sure, just take a full ownership of it meaning write your code right in it or modify it so that it is public
Ok, I get it, now I ask where to look for this private API in particular?
here is a list of all code cjanges related to AST transformations, at this point i'd say there is no better way to learn it other than by looking at what was done
https://github.com/Microsoft/TypeScript/issues?utf8=✓&q=is%3Amerged%20label%3A"Domain%3A%20Transforms"%20
We do not currently expose the transformation API as part of the language service. This is something we are considering. Once we make it available as a public API we will provide documentation on its use.
@rbuckton Is there an entry on the roadmap for making the AST transformation API public? Or can you estimate when this will happen?
@whitecolor Did you find a way to achieve your goals?
@kamekazemaster no i didn't look close yet
Most helpful comment
Ideally you could do this with #5595 (see also #3241), but until we have an API for that, you can use our language service API.
Then:
Something like this might work:
Don't hold me to it though, I haven't tested it out yet.