216 lines
9.4 KiB
Plaintext
216 lines
9.4 KiB
Plaintext
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.createDocumentsAndSourceMaps = exports.MirrorMapWithDocument = exports.SourceMapWithDocuments = void 0;
|
|
const language_core_1 = require("@volar/language-core");
|
|
const vscode_languageserver_textdocument_1 = require("vscode-languageserver-textdocument");
|
|
const common_1 = require("./utils/common");
|
|
class SourceMapWithDocuments {
|
|
constructor(sourceFileDocument, virtualFileDocument, map) {
|
|
this.sourceFileDocument = sourceFileDocument;
|
|
this.virtualFileDocument = virtualFileDocument;
|
|
this.map = map;
|
|
}
|
|
// Range APIs
|
|
toSourceRange(range, filter = () => true) {
|
|
for (const result of this.toSourceRanges(range, filter)) {
|
|
return result;
|
|
}
|
|
}
|
|
toGeneratedRange(range, filter = () => true) {
|
|
for (const result of this.toGeneratedRanges(range, filter)) {
|
|
return result;
|
|
}
|
|
}
|
|
*toSourceRanges(range, filter = () => true) {
|
|
for (const result of this.toRanges(range, filter, 'toSourcePositionsBase', 'matchSourcePosition')) {
|
|
yield result;
|
|
}
|
|
}
|
|
*toGeneratedRanges(range, filter = () => true) {
|
|
for (const result of this.toRanges(range, filter, 'toGeneratedPositionsBase', 'matchGeneratedPosition')) {
|
|
yield result;
|
|
}
|
|
}
|
|
*toRanges(range, filter, api, api2) {
|
|
const failedLookUps = [];
|
|
for (const mapped of this[api](range.start, filter, 'left')) {
|
|
const end = this[api2](range.end, mapped[1], 'right');
|
|
if (end) {
|
|
yield { start: mapped[0], end };
|
|
}
|
|
else {
|
|
failedLookUps.push(mapped);
|
|
}
|
|
}
|
|
for (const failedLookUp of failedLookUps) {
|
|
for (const mapped of this[api](range.end, filter, 'right')) {
|
|
yield { start: failedLookUp[0], end: mapped[0] };
|
|
}
|
|
}
|
|
}
|
|
// Position APIs
|
|
toSourcePosition(position, filter = () => true, baseOffset) {
|
|
for (const mapped of this.toSourcePositions(position, filter, baseOffset)) {
|
|
return mapped;
|
|
}
|
|
}
|
|
toGeneratedPosition(position, filter = () => true, baseOffset) {
|
|
for (const mapped of this.toGeneratedPositions(position, filter, baseOffset)) {
|
|
return mapped;
|
|
}
|
|
}
|
|
*toSourcePositions(position, filter = () => true, baseOffset) {
|
|
for (const mapped of this.toSourcePositionsBase(position, filter, baseOffset)) {
|
|
yield mapped[0];
|
|
}
|
|
}
|
|
*toGeneratedPositions(position, filter = () => true, baseOffset) {
|
|
for (const mapped of this.toGeneratedPositionsBase(position, filter, baseOffset)) {
|
|
yield mapped[0];
|
|
}
|
|
}
|
|
*toSourcePositionsBase(position, filter = () => true, baseOffset) {
|
|
let hasResult = false;
|
|
for (const mapped of this.toPositions(position, filter, this.virtualFileDocument, this.sourceFileDocument, 'generatedRange', 'sourceRange', baseOffset ?? 'left')) {
|
|
hasResult = true;
|
|
yield mapped;
|
|
}
|
|
if (!hasResult && baseOffset === undefined) {
|
|
for (const mapped of this.toPositions(position, filter, this.virtualFileDocument, this.sourceFileDocument, 'generatedRange', 'sourceRange', 'right')) {
|
|
yield mapped;
|
|
}
|
|
}
|
|
}
|
|
*toGeneratedPositionsBase(position, filter = () => true, baseOffset) {
|
|
let hasResult = false;
|
|
for (const mapped of this.toPositions(position, filter, this.sourceFileDocument, this.virtualFileDocument, 'sourceRange', 'generatedRange', baseOffset ?? 'left')) {
|
|
hasResult = true;
|
|
yield mapped;
|
|
}
|
|
if (!hasResult && baseOffset === undefined) {
|
|
for (const mapped of this.toPositions(position, filter, this.sourceFileDocument, this.virtualFileDocument, 'sourceRange', 'generatedRange', 'right')) {
|
|
yield mapped;
|
|
}
|
|
}
|
|
}
|
|
*toPositions(position, filter, fromDoc, toDoc, from, to, baseOffset) {
|
|
for (const mapped of this.map.matching(fromDoc.offsetAt(position), from, to, baseOffset === 'right')) {
|
|
if (!filter(mapped[1].data)) {
|
|
continue;
|
|
}
|
|
yield [toDoc.positionAt(mapped[0]), mapped[1]];
|
|
}
|
|
}
|
|
matchSourcePosition(position, mapping, baseOffset) {
|
|
let offset = this.map.matchOffset(this.virtualFileDocument.offsetAt(position), mapping['generatedRange'], mapping['sourceRange'], baseOffset === 'right');
|
|
if (offset !== undefined) {
|
|
return this.sourceFileDocument.positionAt(offset);
|
|
}
|
|
}
|
|
matchGeneratedPosition(position, mapping, baseOffset) {
|
|
let offset = this.map.matchOffset(this.sourceFileDocument.offsetAt(position), mapping['sourceRange'], mapping['generatedRange'], baseOffset === 'right');
|
|
if (offset !== undefined) {
|
|
return this.virtualFileDocument.positionAt(offset);
|
|
}
|
|
}
|
|
}
|
|
exports.SourceMapWithDocuments = SourceMapWithDocuments;
|
|
class MirrorMapWithDocument extends SourceMapWithDocuments {
|
|
constructor(document, map) {
|
|
super(document, document, map);
|
|
this.document = document;
|
|
}
|
|
*findMirrorPositions(start) {
|
|
for (const mapped of this.toGeneratedPositionsBase(start)) {
|
|
yield [mapped[0], mapped[1].data[1]];
|
|
}
|
|
for (const mapped of this.toSourcePositionsBase(start)) {
|
|
yield [mapped[0], mapped[1].data[0]];
|
|
}
|
|
}
|
|
}
|
|
exports.MirrorMapWithDocument = MirrorMapWithDocument;
|
|
function createDocumentsAndSourceMaps(env, host, mapper) {
|
|
let version = 0;
|
|
const map2DocMap = new WeakMap();
|
|
const mirrorMap2DocMirrorMap = new WeakMap();
|
|
const snapshot2Doc = new WeakMap();
|
|
return {
|
|
getSourceByUri(sourceFileUri) {
|
|
return mapper.getSource(env.uriToFileName(sourceFileUri));
|
|
},
|
|
isVirtualFileUri(virtualFileUri) {
|
|
return mapper.hasVirtualFile(env.uriToFileName(virtualFileUri));
|
|
},
|
|
getVirtualFileByUri(virtualFileUri) {
|
|
return mapper.getVirtualFile(env.uriToFileName(virtualFileUri));
|
|
},
|
|
getMirrorMapByUri(virtualFileUri) {
|
|
const fileName = env.uriToFileName(virtualFileUri);
|
|
const [virtualFile] = mapper.getVirtualFile(fileName);
|
|
if (virtualFile) {
|
|
const map = mapper.getMirrorMap(virtualFile);
|
|
if (map) {
|
|
if (!mirrorMap2DocMirrorMap.has(map)) {
|
|
mirrorMap2DocMirrorMap.set(map, new MirrorMapWithDocument(getDocumentByFileName(virtualFile.snapshot, fileName), map));
|
|
}
|
|
return [virtualFile, mirrorMap2DocMirrorMap.get(map)];
|
|
}
|
|
}
|
|
},
|
|
getMapsBySourceFileUri(uri) {
|
|
return this.getMapsBySourceFileName(env.uriToFileName(uri));
|
|
},
|
|
getMapsBySourceFileName(fileName) {
|
|
const source = mapper.getSource(fileName);
|
|
if (source) {
|
|
const result = [];
|
|
(0, language_core_1.forEachEmbeddedFile)(source.root, (virtualFile) => {
|
|
for (const [sourceFileName, [sourceSnapshot, map]] of mapper.getMaps(virtualFile)) {
|
|
if (sourceSnapshot === source.snapshot) {
|
|
if (!map2DocMap.has(map)) {
|
|
map2DocMap.set(map, new SourceMapWithDocuments(getDocumentByFileName(sourceSnapshot, sourceFileName), getDocumentByFileName(virtualFile.snapshot, fileName), map));
|
|
}
|
|
result.push([virtualFile, map2DocMap.get(map)]);
|
|
}
|
|
}
|
|
});
|
|
return {
|
|
snapshot: source.snapshot,
|
|
maps: result,
|
|
};
|
|
}
|
|
},
|
|
getMapsByVirtualFileUri(virtualFileUri) {
|
|
return this.getMapsByVirtualFileName(env.uriToFileName(virtualFileUri));
|
|
},
|
|
*getMapsByVirtualFileName(virtualFileName) {
|
|
const [virtualFile] = mapper.getVirtualFile(virtualFileName);
|
|
if (virtualFile) {
|
|
for (const [sourceFileName, [sourceSnapshot, map]] of mapper.getMaps(virtualFile)) {
|
|
if (!map2DocMap.has(map)) {
|
|
map2DocMap.set(map, new SourceMapWithDocuments(getDocumentByFileName(sourceSnapshot, sourceFileName), getDocumentByFileName(virtualFile.snapshot, virtualFileName), map));
|
|
}
|
|
yield [virtualFile, map2DocMap.get(map)];
|
|
}
|
|
}
|
|
},
|
|
getDocumentByUri(snapshot, uri) {
|
|
return this.getDocumentByFileName(snapshot, env.uriToFileName(uri));
|
|
},
|
|
getDocumentByFileName,
|
|
};
|
|
function getDocumentByFileName(snapshot, fileName) {
|
|
if (!snapshot2Doc.has(snapshot)) {
|
|
snapshot2Doc.set(snapshot, new Map());
|
|
}
|
|
const map = snapshot2Doc.get(snapshot);
|
|
if (!map.has(fileName)) {
|
|
const uri = env.fileNameToUri(fileName);
|
|
map.set(fileName, vscode_languageserver_textdocument_1.TextDocument.create(uri, host.getLanguageId?.(fileName) ?? (0, common_1.resolveCommonLanguageId)(uri), version++, snapshot.getText(0, snapshot.getLength())));
|
|
}
|
|
return map.get(fileName);
|
|
}
|
|
}
|
|
exports.createDocumentsAndSourceMaps = createDocumentsAndSourceMaps;
|
|
//# sourceMappingURL=documents.js.map |