ts-morph icon indicating copy to clipboard operation
ts-morph copied to clipboard

[Question] Idiomatic way to insert before the return statement of a function?

Open melMass opened this issue 1 year ago • 0 comments

Hi,

Thanks for this project. I'm trying a simple automatic implementation à la Rust macros. I have a crude POC that is almost working:

//- find all createXXXStore methods
project.getSourceFiles().forEach((sourceFile) => {
const func: FunctionDeclaration | undefined = sourceFile.getFunction((f) => {
    const func_name = f.getName();
    if (func_name) {
      const low = func_name.toLowerCase();
      return low.startsWith("create") && low.endsWith("store");
    }
    return false;
  });
  if (!func) return;

  //- extract the store type from the first parameter
  const initial_type = func.getParameters()[0];
  const props = initial_type.getType().getProperties();
  
  //- from each properties of our type we extract information to create setters.
  props.forEach((p) => {
    const name = p.getName();
    const kind = p.getTypeAtLocation(initial_type);
    //- naive way to get the location before the return block
    const child_location = func.getChildCount() - 1;
    //- make our setter
    const setter = func.insertFunction(child_location, {
      name: toCamelCase("set-" + name),
      leadingTrivia: "// autogenerated with ts-morph",
      statements: `update((state) => {
            return {
              ...state,
              ${name},
            };
          });`,
      parameters: [
        {
          name: name,
          type: kind.getText(),
        },
      ],
    });
  });
console.log(sourceFile.print({}));
});

TLDR

func.getChildCount() in the above code does not return the proper value: InvalidOperationError: Invalid index: The max index is 4, but 5 was specified. so childCount returned 6 instead of the 4 children the method has

melMass avatar Jan 24 '24 18:01 melMass