Skip to content

Commit

Permalink
Merge dccfc89 into 8b48640
Browse files Browse the repository at this point in the history
  • Loading branch information
Anish2 committed Sep 8, 2019
2 parents 8b48640 + dccfc89 commit ad5e088
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 48 deletions.
25 changes: 25 additions & 0 deletions src/app-error.ts
Expand Up @@ -36,6 +36,19 @@ interface UnmappedBytesErrorContext {
unmappedBytes: number;
}

interface InvalidMappingLineErrorContext {
code: 'InvalidMappingLine';
generatedLine: number;
maxLine: number;
}

interface InvalidMappingColumnErrorContext {
code: 'InvalidMappingColumn';
generatedLine: number;
generatedColumn: number;
maxColumn: number;
}

interface CannotOpenTempFileErrorContext {
code: 'CannotOpenTempFile';
error: Buffer;
Expand All @@ -46,6 +59,8 @@ export type ErrorContext =
| CommonErrorContext
| OneSourceSourceMapErrorContext
| UnmappedBytesErrorContext
| InvalidMappingLineErrorContext
| InvalidMappingColumnErrorContext
| CannotOpenTempFileErrorContext;

export function getErrorMessage(context: ErrorContext): string {
Expand All @@ -71,6 +86,16 @@ See ${SOURCE_MAP_INFO_URL}`;
return `Unable to map ${unmappedBytes}/${totalBytes} bytes (${bytesString}%)`;
}

case 'InvalidMappingLine': {
const { generatedLine, maxLine } = context;
return `Your source map refers to generated line ${generatedLine}, but the source only contains ${maxLine} line(s).\nCheck that you are using the correct source map.`;
}

case 'InvalidMappingColumn': {
const { generatedLine, generatedColumn, maxColumn } = context;
return `Your source map refers to generated column ${generatedColumn} on line ${generatedLine}, but the source only contains ${maxColumn} column(s) on that line.\nCheck that you are using the correct source map.`;
}

case 'CannotSaveFile':
return 'Unable to save HTML to file';

Expand Down
93 changes: 45 additions & 48 deletions src/explore.ts
Expand Up @@ -21,7 +21,7 @@ export async function exploreBundle(

const sourceMapData = await loadSourceMap(code, map);

const sizes = computeGeneratedFileSizes(sourceMapData);
const sizes = computeFileSizeMapOptimized(sourceMapData);

const files = adjustSourcePaths(sizes.files, options);

Expand Down Expand Up @@ -85,66 +85,63 @@ async function loadSourceMap(codeFile: File, sourceMapFile?: File): Promise<Sour
};
}

/** Calculate the number of bytes contributed by each source file */
function computeGeneratedFileSizes(sourceMapData: SourceMapData): FileSizes {
const spans = computeSpans(sourceMapData);

function computeFileSizeMapOptimized(sourceMapData: SourceMapData): FileSizes {
const { consumer, codeFileContent } = sourceMapData;
const lines = codeFileContent.split('\n');
const files: FileSizeMap = {};
let unmappedBytes = 0;
let totalBytes = 0;

for (let i = 0; i < spans.length; i++) {
const { numChars, source } = spans[i];
let mappedBytes = 0;

consumer.computeColumnSpans();

consumer.eachMapping((m: any) => {
// lines are 1-based
const line = lines[m.generatedLine - 1];
if (line == null) {
throw new AppError({
code: 'InvalidMappingLine',
generatedLine: m.generatedLine,
maxLine: lines.length,
});
}

totalBytes += numChars;
// columns are 0-based
if (m.generatedColumn >= line.length) {
throw new AppError({
code: 'InvalidMappingColumn',
generatedLine: m.generatedLine,
generatedColumn: m.generatedColumn,
maxColumn: line.length,
});
}

if (source === null) {
unmappedBytes += numChars;
let mappingLength: number = 0;
if (m.lastGeneratedColumn != null) {
if (m.lastGeneratedColumn >= line.length) {
throw new AppError({
code: 'InvalidMappingColumn',
generatedLine: m.generatedLine,
generatedColumn: m.lastGeneratedColumn,
maxColumn: line.length,
});
}
mappingLength = m.lastGeneratedColumn - m.generatedColumn + 1;
} else {
files[source] = (files[source] || 0) + numChars;
mappingLength = line.length - m.generatedColumn;
}
}
files[m.source] = (files[m.source] || 0) + mappingLength;
mappedBytes += mappingLength;
});

// Doesn't count newlines as original version didn't count newlines
let totalBytes = codeFileContent.length - lines.length + 1;
const unmappedBytes = totalBytes - mappedBytes;
return {
files,
unmappedBytes,
totalBytes,
};
}

interface Span {
source: string | null;
numChars: number;
}

function computeSpans(sourceMapData: SourceMapData): Span[] {
const { consumer, codeFileContent } = sourceMapData;

const lines = codeFileContent.split('\n');
const spans: Span[] = [];
let numChars = 0;

let lastSource: string | null | undefined = undefined; // not a string, not null

for (let line = 1; line <= lines.length; line++) {
const lineText = lines[line - 1];
const numCols = lineText.length;

for (let column = 0; column < numCols; column++, numChars++) {
const { source } = consumer.originalPositionFor({ line, column });

if (source !== lastSource) {
lastSource = source;
spans.push({ source, numChars: 1 });
} else {
spans[spans.length - 1].numChars += 1;
}
}
}

return spans;
}

export function adjustSourcePaths(fileSizeMap: FileSizeMap, options: ExploreOptions): FileSizeMap {
if (!options.noRoot) {
const prefix = getCommonPathPrefix(Object.keys(fileSizeMap));
Expand Down
2 changes: 2 additions & 0 deletions src/index.ts
Expand Up @@ -20,6 +20,8 @@ export type ErrorCode =
| 'NoSourceMap'
| 'OneSourceSourceMap'
| 'UnmappedBytes'
| 'InvalidMappingLine'
| 'InvalidMappingColumn'
| 'CannotSaveFile'
| 'CannotCreateTempFile'
| 'CannotOpenTempFile';
Expand Down

0 comments on commit ad5e088

Please sign in to comment.