|
1 | 1 | import ts = require('typescript'); |
2 | 2 | import path = require('path'); |
3 | 3 | import gutil = require('gulp-util'); |
| 4 | +import sourceMap = require('source-map'); |
4 | 5 | import tsApi = require('./tsapi'); |
5 | 6 | import input = require('./input'); |
6 | 7 | import output = require('./output'); |
7 | 8 | import host = require('./host'); |
8 | 9 | import project = require('./project'); |
9 | 10 | import filter = require('./filter'); |
| 11 | +import utils = require('./utils'); |
10 | 12 |
|
11 | 13 | export interface ICompiler { |
12 | 14 | prepare(_project: project.Project): void; |
13 | 15 | inputFile(file: input.File); |
14 | 16 | inputDone(); |
| 17 | + /** |
| 18 | + * Corrects the paths in the sourcemap. |
| 19 | + * Returns true when the file is located |
| 20 | + * under the base path. |
| 21 | + */ |
| 22 | + correctSourceMap(map: sourceMap.RawSourceMap): boolean; |
15 | 23 | } |
16 | 24 |
|
17 | 25 | /** |
@@ -90,6 +98,51 @@ export class ProjectCompiler implements ICompiler { |
90 | 98 |
|
91 | 99 | this.project.output.finish(); |
92 | 100 | } |
| 101 | + |
| 102 | + private _commonBaseDiff: [number, string]; |
| 103 | + /** |
| 104 | + * Calculates the difference between the common base directory calculated based on the base paths of the input files |
| 105 | + * and the common source directory calculated by TypeScript. |
| 106 | + */ |
| 107 | + private get commonBaseDiff(): [number, string] { |
| 108 | + if (this._commonBaseDiff) return this._commonBaseDiff; |
| 109 | + |
| 110 | + const expected = this.project.input.commonBasePath; |
| 111 | + const real = this.project.input.commonSourceDirectory; |
| 112 | + |
| 113 | + const length = real.length - expected.length; |
| 114 | + |
| 115 | + if (length > 0) { |
| 116 | + return this._commonBaseDiff = [length, real.substring(real.length - length)]; |
| 117 | + } else { |
| 118 | + return this._commonBaseDiff = [length, expected.substring(expected.length + length)]; |
| 119 | + } |
| 120 | + } |
| 121 | + |
| 122 | + correctSourceMap(map: sourceMap.RawSourceMap) { |
| 123 | + const [diffLength, diff] = this.commonBaseDiff; |
| 124 | + |
| 125 | + if (diffLength < 0) { |
| 126 | + // There were files added outside of the common base. |
| 127 | + map.sources = map.sources.map<string>(fileName => { |
| 128 | + const full = utils.normalizePath(path.join(this.project.input.commonSourceDirectory, fileName)); |
| 129 | + let relative = path.relative(utils.normalizePath(this.project.input.commonBasePath), full); |
| 130 | + if (relative.substring(0, 3) === '../') { |
| 131 | + |
| 132 | + return undefined; |
| 133 | + } |
| 134 | + |
| 135 | + if (relative.substring(0, 2) === './') { |
| 136 | + relative = relative.substring(2); |
| 137 | + } |
| 138 | + return full.substring(full.length - relative.length); |
| 139 | + }).filter(fileName => fileName !== undefined); |
| 140 | + |
| 141 | + if (map.sources.length === 0) return false; |
| 142 | + } |
| 143 | + |
| 144 | + return true; |
| 145 | + } |
93 | 146 | } |
94 | 147 |
|
95 | 148 | // TODO: file-based compiler |
0 commit comments