Skip to content

Commit

Permalink
refactor(all)
Browse files Browse the repository at this point in the history
  • Loading branch information
fathyb committed Mar 3, 2018
1 parent ec1412b commit 847a59e
Show file tree
Hide file tree
Showing 17 changed files with 158 additions and 153 deletions.
6 changes: 3 additions & 3 deletions src/backend/compiler/tsc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as ts from 'typescript'

import {CompileResult} from '../../interfaces'
import {Configuration, Transformers} from '../config-loader'
import {formatDiagnostics} from '../format'
import {formatDiagnostics} from '../diagnostics'
import {CompilerHost} from './host'

// This should only be used for non-watch build
Expand All @@ -29,7 +29,7 @@ export class TypeScriptCompiler {
this.transformers = transformers
}

public compile(path: string, reportErrors: boolean): CompileResult {
public compile(path: string, reportErrors: boolean, root: string): CompileResult {
const {program, transformers, host} = this
const diagnostics: ts.Diagnostic[] = []

Expand All @@ -53,7 +53,7 @@ export class TypeScriptCompiler {
...program.getSyntacticDiagnostics(sourceFile)
)

const formatted = formatDiagnostics(diagnostics, process.cwd())
const formatted = formatDiagnostics(diagnostics, root)

if(reportErrors && diagnostics.length > 0) {
console.error(formatted)
Expand Down
21 changes: 13 additions & 8 deletions src/backend/config-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import commentsJson = require('comment-json')
import findUp = require('find-up')
import resolveFrom = require('resolve-from')

import {PathTransform} from '../exports'
import {readFile} from '../utils/fs'
import {PathTransform} from './transformers/paths'

export type TransformerList = Array<ts.TransformerFactory<ts.SourceFile>>
export interface Transformers {
Expand All @@ -16,17 +16,17 @@ export interface Transformers {
}

export interface Configuration {
path: string | null
typescript: ts.ParsedCommandLine
plugin: {
transpileOnly: boolean
transformers: Transformers
}
path: string
}

const configCache: {[path: string]: Configuration} = {}

export async function loadConfiguration(path: string): Promise<Configuration> {
export async function loadConfiguration(path: string, rootDir: string): Promise<Configuration> {
const cached = Object.keys(configCache).find(cachePath => path.indexOf(cachePath) === 0)

if(cached) {
Expand All @@ -35,12 +35,14 @@ export async function loadConfiguration(path: string): Promise<Configuration> {

const cwd = dirname(path)
const configPath = await findUp('tsconfig.json', {cwd})
let tsconfig: any

if(!configPath) {
throw new Error('Cannot find tsconfig')
tsconfig = {}
}
else {
tsconfig = commentsJson.parse(await readFile(configPath))
}

const tsconfig = configPath && commentsJson.parse(await readFile(configPath))

// TODO: use the ParsedCommandLine for the type roots
const {
Expand All @@ -62,8 +64,11 @@ export async function loadConfiguration(path: string): Promise<Configuration> {
]
}

const base = dirname(configPath)
const base = configPath
? dirname(configPath)
: rootDir
const typescript = ts.parseJsonConfigFileContent(tsconfig, ts.sys, base)

const config: Configuration = {
typescript,
plugin: {
Expand All @@ -87,7 +92,7 @@ export async function loadConfiguration(path: string): Promise<Configuration> {
}

function getTransformerFactory(options: ts.CompilerOptions, dir: string, transformers: any): Transformers {
const before: TransformerList = [PathTransform(options)]
const before: TransformerList = [PathTransform(options, dir)]

if(transformers === undefined) {
return {before, after: []}
Expand Down
64 changes: 64 additions & 0 deletions src/backend/diagnostics/format.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import {EOL} from 'os'

import {codeFrameColumns, Location} from '@babel/code-frame'

import chalk from 'chalk'
import normalizePath = require('normalize-path')
import * as ts from 'typescript'

export function formatDiagnostics(diagnostics: ReadonlyArray<ts.Diagnostic>, context: string): string {
return diagnostics.map(diagnostic => {
const messageText = formatDiagnosticMessage(diagnostic.messageText, '', context)
const {file} = diagnostic
let message = messageText

if(file != null && diagnostic.start != null) {
const lineChar = file.getLineAndCharacterOfPosition(diagnostic.start)
const source = file.text || diagnostic.source
const start = {
line: lineChar.line + 1,
column: lineChar.character + 1
}
const location: Location = {start}
const red = chalk.red(`🚨 ${file.fileName}(${start.line},${start.column})`)

const messages = [`${red}\n${chalk.redBright(messageText)}`]

if(source != null) {
if(typeof diagnostic.length === 'number') {
const end = file.getLineAndCharacterOfPosition(diagnostic.start + diagnostic.length)

location.end = {
line: end.line + 1,
column: end.character + 1
}
}

const frame = codeFrameColumns(source, location, {
linesAbove: 1,
linesBelow: 1,
highlightCode: true
})

messages.push(
frame
.split('\n')
.map(str => ` ${str}`)
.join('\n')
)
}

message = messages.join('\n')
}

return message + EOL
}).join(EOL) + EOL
}

function formatDiagnosticMessage(diagnostic: string|ts.DiagnosticMessageChain, delimiter: string, context: string) {
const contextPath = normalizePath(context)

return ts
.flattenDiagnosticMessageText(diagnostic, delimiter)
.replace(new RegExp(contextPath, 'g'), '.')
}
2 changes: 2 additions & 0 deletions src/backend/diagnostics/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './format'
export * from './reporter'
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import {Diagnostic} from 'typescript'

import {formatDiagnostics} from './format'

export function reportDiagnostics(diagnostics: ReadonlyArray<Diagnostic>): void {
export function reportDiagnostics(diagnostics: ReadonlyArray<Diagnostic>, context: string): void {
if(diagnostics.length > 0 ) {
const frame = formatDiagnostics(diagnostics, process.cwd())
const frame = formatDiagnostics(diagnostics, context)

console.error(frame)
}
Expand Down
2 changes: 1 addition & 1 deletion src/backend/exports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ export * from './transformers/paths'

export * from './config-loader'
export * from './service'
export * from './reporter'
export * from './diagnostics'
export * from './transpiler'
70 changes: 0 additions & 70 deletions src/backend/format.ts

This file was deleted.

35 changes: 35 additions & 0 deletions src/backend/linter/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import * as tslint from 'tslint'
import * as ts from 'typescript'

export class Linter {
private readonly linter: tslint.Linter | null = null

constructor(
program: ts.Program,
private readonly config: tslint.Configuration.IConfigurationFile
) {
try {
const tslintModule: typeof tslint = require('tslint')

this.linter = new tslintModule.Linter({fix: false}, program)
}
catch {
this.linter = null
}
}

public lint(file: string, code: string): tslint.RuleFailure[] {
const {linter} = this

if(!linter) {
return []
}

linter.lint(file, code, this.config)

return linter
.getResult()
.failures
.filter(failure => failure.getFileName() === file)
}
}
9 changes: 4 additions & 5 deletions src/backend/service/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import * as ts from 'typescript'

import {TypeCheckResult} from '../../interfaces'
import {formatDiagnostics} from '../format'
import {reportDiagnostics} from '../reporter'
import {formatDiagnostics, reportDiagnostics} from '../diagnostics'
import {LanguageServiceHost} from './host'

export class LanguageService {
Expand All @@ -14,7 +13,7 @@ export class LanguageService {
this.service = ts.createLanguageService(this.host, ts.createDocumentRegistry())
}

public check(path: string, reportErrors: boolean): TypeCheckResult {
public check(path: string, reportErrors: boolean, root: string): TypeCheckResult {
const {service} = this

this.host.invalidate(path)
Expand All @@ -23,10 +22,10 @@ export class LanguageService {
...service.getSemanticDiagnostics(path),
...service.getSyntacticDiagnostics(path)
]
const formatted = formatDiagnostics(diagnostics, process.cwd())
const formatted = formatDiagnostics(diagnostics, root)

if(reportErrors && diagnostics.length > 0) {
reportDiagnostics(diagnostics)
reportDiagnostics(diagnostics, root)
}

return {
Expand Down
12 changes: 6 additions & 6 deletions src/backend/transformers/paths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as ts from 'typescript'
import {findModule} from '../modules/resolver'

// TODO: use options from the TransformationContext
export function PathTransform(options: ts.CompilerOptions): ts.TransformerFactory<ts.SourceFile> {
export function PathTransform(options: ts.CompilerOptions, baseDir: string): ts.TransformerFactory<ts.SourceFile> {
return function(context: ts.TransformationContext) {
return (node: ts.SourceFile) => {
if(options.baseUrl) {
Expand All @@ -16,7 +16,7 @@ export function PathTransform(options: ts.CompilerOptions): ts.TransformerFactor
throw new Error('Expected child.moduleSpecifier to be StringLiteral')
}

let resolved = resolve(specifier.text, options)
let resolved = resolve(specifier.text, baseDir, options)

if(path.isAbsolute(resolved)) {
const sourceDir = path.dirname(node.fileName)
Expand All @@ -42,7 +42,7 @@ export function PathTransform(options: ts.CompilerOptions): ts.TransformerFactor
}
}

function resolve(modulePath: string, {paths, baseUrl}: ts.CompilerOptions): string {
function resolve(modulePath: string, baseDir: string, {paths, baseUrl}: ts.CompilerOptions): string {
if(!baseUrl) {
return modulePath
}
Expand All @@ -56,7 +56,7 @@ function resolve(modulePath: string, {paths, baseUrl}: ts.CompilerOptions): stri
if(paths) {
const mappings = Object
.keys(paths)
.map(alias => getPathMappings(alias, paths[alias], baseUrl))
.map(alias => getPathMappings(alias, paths[alias], baseDir, baseUrl))
.reduce((a, b) => a.concat(b), [])
.filter(mapping => mapping.pattern.test(modulePath))

Expand All @@ -81,8 +81,8 @@ interface PathMapping {
target: string
}

function getPathMappings(alias: string, targets: string[], baseUrl: string = '.'): PathMapping[] {
const absoluteBase = path.resolve(process.cwd(), baseUrl)
function getPathMappings(alias: string, targets: string[], baseDir: string, baseUrl: string = '.'): PathMapping[] {
const absoluteBase = path.resolve(baseDir, baseUrl)

const moduleOnly = alias.indexOf('*') === -1
const escaped = escapeRegExp(alias)
Expand Down
Loading

0 comments on commit 847a59e

Please sign in to comment.