Skip to content
This repository has been archived by the owner on Oct 15, 2018. It is now read-only.

Methods editing #184

Closed
BzenkoSergey opened this issue Sep 13, 2016 · 5 comments
Closed

Methods editing #184

BzenkoSergey opened this issue Sep 13, 2016 · 5 comments

Comments

@BzenkoSergey
Copy link

How i can get body of class method then modify and write it?

@dsherret
Copy link
Owner

dsherret commented Sep 15, 2016

Hey, right now this library can only get the main structure of the code and not the individual statements. That might be added sometime in the future.

It's for that reason that if you read a file and write it out, it won't include the statements. For example:

Current Behaviour

// V:\\MyClass.ts
export class MyClass {
    myMethod(myParameter: string) {
        console.log("blah blah blah... original code in here");
    }
}
import {getInfoFromFiles} from "ts-type-info";

const file = getInfoFromFiles("V:\\MyClass.ts").getFile("MyClass.ts");
console.log(file.write());

Outputs:

export class MyClass {
    myMethod(myParameter: string) {
    }
}

Writing Your Own Method/Function Body

HOWEVER, you can do this:

import {getInfoFromFiles} from "ts-type-info";

const file = getInfoFromFiles("V:\\MyClass.ts").getFile("MyClass.ts");
const method = file.getClass("MyClass").getMethod("myMethod");

method.onWriteFunctionBody = (writer) => {
    writer.write("console.log('something');");
};

console.log(file.write());

Outputs:

export class MyClass {
    myMethod(myParameter: string) {
        console.log('something');
    }
}

@BzenkoSergey
Copy link
Author

BzenkoSergey commented Sep 15, 2016

My workaround

`

    // use ts-type-info lib
    let file = tsTypeInfoFile.getFile(filePath);
    let classInfo = file.classes[0];

    let tsFilePath = filePath.replace(/\\/g, '/').toLowerCase();

    // use ts compiler api
    let tsFile = this.tsProgram.getSourceFileByPath(tsFilePath);

    tsFile.nextContainer.members.forEach((member: any) => {
        let isMethod = !!member.body;
        if(!isMethod) {
            return;
        }

        let name = member.name ? member.name.text : member.symbol.getName();

        let method: any;
        let isConstructor = (name === '__constructor');
        if(isConstructor) {
            method = classInfo.constructorDef;
        } else {
            method = classInfo.methods.find((method: any) => {
                return method.name === name;
            });
        }

        method.onWriteFunctionBody = (writer: any) => {
            member.body.statements.forEach((statement: any) => {
                writer.newLine().write(statement.getText());
            });
        }
    })

`

@dsherret
Copy link
Owner

dsherret commented Sep 15, 2016

After seeing your solution, I think it would be useful if there was a flag in this library that made it include the ts.Node objects. For example:

import {getInfoFromFiles} from "ts-type-info";
import * as ts from "typescript";

const result = getInfoFromFiles([fileName], { includeTsNodes: true });
const file = result.getFile(fileName);
const method = file.getClass("MyClass").getMethod("myMethod");

method.onWriteFunctionBody = writer => {
    const methodNode = methodDef.tsNode as ts.MethodDeclaration;

    methodNode.body.statements.forEach(statement => {
        writer.writeLine(statement.getText());
    });
};

I just opened #185.

@BzenkoSergey
Copy link
Author

Thanks!

dsherret added a commit that referenced this issue Oct 15, 2016
@dsherret
Copy link
Owner

dsherret commented Oct 15, 2016

This will be in 6.1 (releasing in a little bit). I just committed a test that shows a working example and updated my example in this issue.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants