question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Adding nodes to an ArrayLiteralExpression

See original GitHub issue

I located a node of kind ‘ArrayLiteralExpression’ via a getFirstChildByKindOrThrow(SyntaxKind.ArrayLiteralExpression) call.

How can I add additional items to the array? I cannot find an interface from ts-simple-ast that represents this array expression.

The actual code I’d like to manipulate is:

@NgModule({
  declarations: [
    AppComponent],
  imports: [
    BrowserModule,
    AppRoutingModule
  , WchNgModule.forRoot(environment)],
  providers: [],
  entryComponents: [...LAYOUTS],
bootstrap: [AppComponent]
})

I’d like to add a value to the ‘decorations’ property (and managed to locate the array node).

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

8reactions
dsherretcommented, Aug 29, 2017

@CarstenLeue, this is implemented in 0.57.0. I’ll add documentation later.


Nodes of kind ts.SyntaxKind.ArrayLiteralExpressions are now ArrayLiteralExpression. So in the example above, you can do the following assertion (note that when #36 is implemented, the assertion would not be necessary):

const array = declarationsProp.getFirstChildByKindOrThrow(SyntaxKind.ArrayLiteralExpression) as ArrayLiteralExpression;

From there, you can do any of the following:

array.addElement("1"); // [1]
array.addElements(["5", "6"]); // [1, 5, 6]
array.insertElement(1, "2"); // [1, 2, 5, 6]
array.insertElements(2, ["3", "4"]); // [1, 2, 3, 4, 5, 6]
array.removeElement(5); // [1, 2, 3, 4, 5]
array.removeElement(array.getElements()[0]); // [2, 3, 4, 5]

Let me know if you run into any issues.

1reaction
dsherretcommented, Aug 28, 2017

Thanks for the compliment! 😃 Yeah, I’ve pulled out my hair many times trying to figure out the raw AST. Let me know if you run into any issues using the library.

Take note that #63 is implemented and available in 0.56.1. It will be slightly annoying to use because it will blow away the previously navigated nodes, but it should be an ok solution for the time being.

I believe the code would be something like (untested):

// just realized I don't have a convenient .getDecorator("NgModule") method... will add in #59
const decorator = classDeclaration.getDecorators().find(d => d.getName() === "NgModule")!;
const arg = decorator.getArguments()[0];

// this part is not so nice because there's not an easy way of navigating
// ObjectLiteralExpressions right now... I opened #65 for that
const declarationsProp = arg.getDescendants()
    .find(d => d.getKind() === SyntaxKind.PropertyAssignment &&
        (d.compilerNode as ts.PropertyAssignment).name === "declarations");
const array = declarationsProp.getFirstChildByKindOrThrow(SyntaxKind.ArrayLiteralExpression);
const closeBracketToken = array.getLastChildByKindOrThrow(SyntaxKind.CloseBracketToken);

sourceFile.insertText(closeBracketToken.getPos(), `, "something new!"`);

So after doing this everything you’ve just navigated to won’t work… for example, doing anything on classDeclaration, decorator, arg, declarationsProp, etc… will throw an error because these nodes were blown away by the sourceFile.insertText(...). You would have to renavigate to them: classDeclaration = sourceFile.getClass("YourClassName")!

That’s an unfortunate side effect of using it and why it would be nice if there were actual methods for doing this.


All that said, I’m going to take a break from working on removing nodes and prioritize this because it’s quite easy to implement. I’ll start work on it tomorrow evening.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Spread syntax (...) - JavaScript - MDN Web Docs - Mozilla
The spread (...) syntax allows an iterable, such as an array or string, to be expanded in places where zero or more arguments...
Read more >
Array Literals in Java - GeeksforGeeks
Method 1: Initialization of array elements at the time of creating array object. It is the most commonly used syntax and can only...
Read more >
Conditionally adding entries inside Array and object literals
This blog post shows how you can conditionally add elements inside Array literals and properties inside object literals.
Read more >
What is array literal notation in javascript and when should ...
array literal notation is where you define a new array using just empty brackets. In your example: var myArray = [];. It is...
Read more >
Documentation: 15: 8.15. Arrays - PostgreSQL
To write an array value as a literal constant, enclose the element values within curly braces and separate them by commas. (If you...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found