-
Notifications
You must be signed in to change notification settings - Fork 454
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use language server to get proper reflection types #505
Merged
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
cb3b137
Add Date reflection bug test suite
MichalLytek 0292529
Add array props test cases
MichalLytek 6c019af
Merge remote-tracking branch 'test-fork/metadata-reflection-bug' into…
GeeWee 75434da
test commit
GeeWee 1a14e62
working commit
GeeWee ddbc65b
Merge remote-tracking branch 'origin/master' into reflect
GeeWee 3135b52
..
GeeWee 86e4601
commmit
GeeWee f296111
added flag
GeeWee 55ba740
added reflect-metadata
GeeWee 881ff30
removed logging
GeeWee b35e0d8
cleanup
GeeWee c727e19
Merge remote-tracking branch 'origin/master' into reflect
GeeWee f08332f
bumped version
GeeWee File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
import * as fs from 'fs'; | ||
import { cwd } from 'process'; | ||
import * as ts from 'typescript'; | ||
import { logOnce } from './logger'; | ||
import { TsJestConfig } from './jest-types'; | ||
|
||
// Takes the typescript code and by whatever method configured, makes it into javascript code. | ||
export function transpileTypescript( | ||
filePath: string, | ||
fileSrc: string, | ||
compilerOptions: ts.CompilerOptions, | ||
tsJestConfig: TsJestConfig, | ||
): string { | ||
if (tsJestConfig.useExperimentalLanguageServer) { | ||
logOnce('Using experimental language server.'); | ||
return transpileViaLanguageServer(filePath, fileSrc, compilerOptions); | ||
} | ||
logOnce('Compiling via normal transpileModule call'); | ||
return transpileViaTranspileModile(filePath, fileSrc, compilerOptions); | ||
} | ||
|
||
/** | ||
* This is slower, but can properly parse enums and deal with reflect metadata. | ||
* This is an experimental approach from our side. Potentially we should cache | ||
* the languageServer between calls. | ||
*/ | ||
function transpileViaLanguageServer( | ||
filePath: string, | ||
fileSrc: string, | ||
compilerOptions: ts.CompilerOptions, | ||
) { | ||
const serviceHost: ts.LanguageServiceHost = { | ||
// Returns an array of the files we need to consider | ||
getScriptFileNames: () => { | ||
return [filePath]; | ||
}, | ||
|
||
getScriptVersion: fileName => { | ||
// We're not doing any watching or changing files, so versioning is not relevant for us | ||
return undefined; | ||
}, | ||
|
||
getCurrentDirectory: () => { | ||
return cwd(); | ||
}, | ||
|
||
getScriptSnapshot: fileName => { | ||
if (fileName === filePath) { | ||
// jest has already served this file for us, so no need to hit disk again. | ||
return ts.ScriptSnapshot.fromString(fileSrc); | ||
} | ||
// Read file from disk. I think this could be problematic if the files are not saved as utf8. | ||
const result = fs.readFileSync(fileName, 'utf8'); | ||
return ts.ScriptSnapshot.fromString(result); | ||
}, | ||
|
||
getCompilationSettings: () => { | ||
return compilerOptions; | ||
}, | ||
|
||
getDefaultLibFileName: () => { | ||
return ts.getDefaultLibFilePath(compilerOptions); | ||
}, | ||
fileExists: ts.sys.fileExists, | ||
readFile: ts.sys.readFile, | ||
readDirectory: ts.sys.readDirectory, | ||
getDirectories: ts.sys.getDirectories, | ||
directoryExists: ts.sys.directoryExists, | ||
}; | ||
const service = ts.createLanguageService(serviceHost); | ||
const serviceOutput = service.getEmitOutput(filePath); | ||
const files = serviceOutput.outputFiles.filter(file => { | ||
// Service outputs both d.ts and .js files - we're not interested in the declarations. | ||
return file.name.endsWith('js'); | ||
}); | ||
logOnce('JS files parsed', files.map(f => f.name)); | ||
|
||
// Log some diagnostics here: | ||
const diagnostics = service | ||
.getCompilerOptionsDiagnostics() | ||
.concat(service.getSyntacticDiagnostics(filePath)) | ||
.concat(service.getSemanticDiagnostics(filePath)); | ||
|
||
if (diagnostics.length > 0) { | ||
const errors = `${diagnostics.map(d => d.messageText)}\n`; | ||
logOnce(`Diagnostic errors from TSC: ${errors}`); | ||
// Maybe we should keep compiling even though there are errors. This can possibly be configured. | ||
throw Error( | ||
`TSC language server encountered errors while transpiling. Errors: ${errors}`, | ||
); | ||
} | ||
|
||
return files[0].text; | ||
} | ||
|
||
/** | ||
* This is faster, and considers the modules in isolation | ||
*/ | ||
function transpileViaTranspileModile( | ||
filePath: string, | ||
fileSource: string, | ||
compilerOptions: ts.CompilerOptions, | ||
) { | ||
return ts.transpileModule(fileSource, { | ||
compilerOptions, | ||
fileName: filePath, | ||
}).outputText; | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ran into several issues where I'd like to clean the node_modules inside tests also, so I'm sure that there's no old files left-over