Skip to content

Commit

Permalink
Adjustments to parser API
Browse files Browse the repository at this point in the history
The ParserInput source is now a `Buffer`, which I think better reflects what we need.

Also added some initial setup for the `JavaScriptParser`.
  • Loading branch information
knutwannheden committed Sep 23, 2024
1 parent 176579d commit 9852f00
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 28 deletions.
7 changes: 1 addition & 6 deletions openrewrite/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,9 @@ module.exports = {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
transform: {
'^.+\\.tsx?$': ['ts-jest', {
tsconfig: 'tsconfig.json', // Adjust if your tsconfig file is named or located differently
tsconfig: 'tsconfig.test.json', // Adjust if your tsconfig file is named or located differently
}],
},
testMatch: ['**/__tests__/**/*.+(ts|tsx|js)', '**/?(*.)+(spec|test).+(ts|tsx|js)'],
collectCoverageFrom: ['src/**/*.{ts,tsx}', '!src/**/*.d.ts'],
globals: {
'ts-jest': {
tsconfig: 'tsconfig.test.json'
}
}
};
22 changes: 8 additions & 14 deletions openrewrite/src/core/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ export class ParserInput {
private readonly _path: string;
private readonly _fileAttributes: FileAttributes | null;
private readonly _synthetic: boolean;
private readonly _source: () => fs.ReadStream;
private readonly _source: () => Buffer;

constructor(
path: string,
fileAttributes: FileAttributes | null,
synthetic: boolean,
source: () => fs.ReadStream
source: () => Buffer
) {
this._path = path;
this._fileAttributes = fileAttributes;
Expand All @@ -33,7 +33,7 @@ export class ParserInput {
return this._synthetic;
}

get source(): () => fs.ReadStream {
get source(): () => Buffer {
return this._source;
}
}
Expand All @@ -50,18 +50,18 @@ export abstract class Parser {
abstract sourcePathFromSourceText(prefix: string, sourceCode: string): string;

parse(
sourceFiles: Iterable<string>,
sourceFilesPaths: Iterable<string>,
relativeTo: string | null,
ctx: ExecutionContext
): Iterable<SourceFile> {
const inputs: ParserInput[] = [];
for (const path of sourceFiles) {
for (const path of sourceFilesPaths) {
inputs.push(
new ParserInput(
path,
null,
false,
() => fs.createReadStream(path)
() => fs.readFileSync(path)
)
);
}
Expand All @@ -79,13 +79,7 @@ export abstract class Parser {
path,
null,
true,
() => {
// FIXME handling of streams
const stream = new fs.ReadStream(null!);
stream.push(source);
stream.push(null);
return stream;
}
() => Buffer.from(source)
);
});
return this.parseInputs(inputs, null, ctx);
Expand Down Expand Up @@ -136,7 +130,7 @@ function requirePrintEqualsInput(
const required = ctx.getMessage(ExecutionContext.REQUIRE_PRINT_EQUALS_INPUT, true);
if (required && !sourceFile.printEqualsInput(parserInput, ctx)) {
const diff = Result.diff(
parserInput.source().read().toString(),
parserInput.source().toString(),
sourceFile.printAll(),
parserInput.path
);
Expand Down
2 changes: 1 addition & 1 deletion openrewrite/src/core/tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ export class ParseError implements SourceFile {
parser.getCharset(ctx),
false,
null,
input.source().read().toString(),
input.source().toString(),
erroneous
);
}
Expand Down
39 changes: 34 additions & 5 deletions openrewrite/src/javascript/parser.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,51 @@
import * as ts from 'typescript';
import * as JS from './tree';
import {ExecutionContext, Markers, Parser, ParserInput, randomId, SourceFile} from "../core";
import {ExecutionContext, Markers, Parser, ParserInput, randomId, SourceFile, Tree} from "../core";
import {Space} from "../java/tree";

export class JavaScriptParser extends Parser {
parseInputs(sources: Iterable<ParserInput>, relativeTo: string | null, ctx: ExecutionContext): Iterable<SourceFile> {
return [new JS.CompilationUnit(
parseInputs(inputs: Iterable<ParserInput>, relativeTo: string | null, ctx: ExecutionContext): Iterable<SourceFile> {
const inputsArray = Array.from(inputs);
const compilerOptions: ts.CompilerOptions = {
target: ts.ScriptTarget.Latest,
module: ts.ModuleKind.CommonJS,
strict: true,
};
const host = ts.createCompilerHost(compilerOptions);
host.getSourceFile = (fileName, languageVersion) => {
if (!fileName.endsWith('lib.d.ts')) {
let sourceText = inputsArray.find(i => i.path === fileName)?.source().toString('utf8')!;
return sourceText ? ts.createSourceFile(fileName, sourceText, languageVersion, true) : undefined;
}

// For default library files like lib.d.ts
const libFilePath = ts.getDefaultLibFilePath(compilerOptions);
const libSource = ts.sys.readFile(libFilePath);
return libSource
? ts.createSourceFile(fileName, libSource, languageVersion, true)
: undefined;
}

const program = ts.createProgram(Array.from(inputsArray, i => i.path), compilerOptions, host);
const typeChecker = program.getTypeChecker();
return inputsArray.map(i => program.getSourceFile(i.path)).map(sf => this.visit(sf!, sf!, typeChecker) as SourceFile);
}

private visit(node: ts.Node, sourceFile: ts.SourceFile, typeChecker: ts.TypeChecker): Tree {
const kind = ts.SyntaxKind[node.kind];
return new JS.CompilationUnit(
randomId(),
Space.EMPTY,
Markers.EMPTY,
"file.ts",
sourceFile.fileName,
null,
null,
false,
null,
[],
[],
Space.EMPTY
)];
);
}

accept(path: string): boolean {
Expand Down
10 changes: 8 additions & 2 deletions openrewrite/test/core/tree.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {Cursor, Markers, randomId} from '../../src/core';
import {Cursor, InMemoryExecutionContext, Markers, ParserInput, randomId} from '../../src/core';
import {isSourceFile} from "typescript";
import {Document, Documents, isYaml} from "../../src/yaml";
import {Document, Documents, isYaml} from "../../src/yaml/tree";
import {JavaScriptParser} from "../../src/javascript";

describe('tree utils', () => {
test('new random ID', () => {
Expand All @@ -16,4 +17,9 @@ describe('tree utils', () => {
expect(c.firstEnclosing(Documents)).toBeDefined();
expect(c.firstEnclosing(Document)).toBeNull();
});

test('parse', () => {
const parser = new JavaScriptParser();
parser.parseInputs([new ParserInput('foo.ts', null, true, () => Buffer.from('const c = 1;', 'utf8'))], null, new InMemoryExecutionContext());
});
});

0 comments on commit 9852f00

Please sign in to comment.