Skip to content

Commit

Permalink
Diagnostic #6
Browse files Browse the repository at this point in the history
  • Loading branch information
AziatkaVictor committed Apr 16, 2023
1 parent 6771f4c commit 418d4d4
Show file tree
Hide file tree
Showing 10 changed files with 157 additions and 79 deletions.
6 changes: 3 additions & 3 deletions package.json
Expand Up @@ -204,10 +204,10 @@
{
"title": "Diagnostics",
"properties": {
"ltx-support.diagnostics.enableDiagnostic": {
"ltx-support.diagnostics.enable": {
"type": "boolean",
"default": false,
"markdownDescription": "Включить диагностику файлов. Будет происходить проверка файла на ошибки. На данный момент не работает. `WiP`"
"default": true,
"markdownDescription": "Включить диагностику файлов. Будет происходить проверка файла на ошибки."
},
"ltx-support.diagnostics.ignoreParamsDiagnostic": {
"type": "boolean",
Expand Down
30 changes: 4 additions & 26 deletions src/extension.ts
Expand Up @@ -10,7 +10,8 @@ import { isUpdateDocumentation, isDiagnosticEnabled} from './settings';
import { provideCompletion } from './providers/logicCompletionItemProvider';
import { updateDocumentation } from './documentation';

let diagnosticCollection: DiagnosticCollection;
export var diagnosticCollection: DiagnosticCollection;
export var diagnosticMap: Map<string, Diagnostic[]> = new Map();
export var documents: Map<TextDocument, LtxDocument> = new Map<TextDocument, LtxDocument>();

export function getLtxDocument(document : TextDocument) {
Expand Down Expand Up @@ -73,31 +74,8 @@ function createFileData() {
return;
}

diagnosticCollection.clear();
if (isDiagnosticEnabled()) {
// let diagnosticMap: Map<string, Diagnostic[]> = new Map();
// workspace.textDocuments.forEach(document => {
// if (document.languageId !== "ltx") {
// return;
// }
// var errors = getLtxDocument(document).errorsData;
// let canonicalFile = document.uri.toString();
// let diagnostics = diagnosticMap.get(canonicalFile);

// if (!diagnostics) {
// diagnostics = [];
// }
// errors.forEach(item => {
// let diagnosticItem = new Diagnostic(item.range, item.descr, item.errorType);
// diagnosticItem.code = item.tag;
// diagnostics.push(diagnosticItem);
// });
// diagnosticMap.set(canonicalFile, diagnostics);
// })

// diagnosticMap.forEach((diags, file) => {
// diagnosticCollection.set(Uri.parse(file), diags);
// });
if (!isDiagnosticEnabled()) {
diagnosticCollection.clear();
}
}

Expand Down
51 changes: 37 additions & 14 deletions src/ltx/ltxCondlist.ts
@@ -1,6 +1,7 @@
import { Position, Range } from "vscode";
import { sectionsArray } from "./ltxDocument";
import { addSemantic, LtxSemantic, LtxSemanticDescription, LtxSemanticModification, LtxSemanticType } from "./ltxSemantic";
import { LtxLine } from "./ltxLine";

export class LtxCondlist {
readonly range: Range;
Expand All @@ -10,23 +11,26 @@ export class LtxCondlist {
readonly conditionRange?: Range;
readonly function?;
readonly functionRange?: Range;
readonly sectionLink?;

private tempData;

isInside(position : Position) : boolean {
owner: LtxLine;

isInside(position: Position): boolean {
return this.range.start.isBefore(position) && this.range.end.isAfterOrEqual(position);
}

isInsideCondition(position : Position) : boolean {
isInsideCondition(position: Position): boolean {
return this.conditionRange ? this.conditionRange.start.isBefore(position) && this.conditionRange.end.isAfterOrEqual(position) : false;
}

isInsideFunction(position : Position) : boolean {
isInsideFunction(position: Position): boolean {
return this.functionRange ? this.functionRange.start.isBefore(position) && this.functionRange.end.isAfterOrEqual(position) : false;
}

constructor(lineIndex: number, PosIndex: number, content: string) {
constructor(lineIndex: number, PosIndex: number, content: string, owner: LtxLine) {
this.tempData = content;
this.owner = owner;
this.range = new Range(new Position(lineIndex, PosIndex), new Position(lineIndex, PosIndex + content.length))
this.lineIndex = lineIndex;
this.positionIndex = PosIndex;
Expand All @@ -42,23 +46,42 @@ export class LtxCondlist {
}

this.findElements(/(\-|\+)(?!\d)\w*\b(?<=\w)/g, LtxSemanticType.variable, LtxSemanticModification.declaration, LtxSemanticDescription.info);
this.findElements(/(\=|\!)\w*\b(?<=\w)/g, LtxSemanticType.function, LtxSemanticModification.readonly, null);
this.findElements(/(\=|\!)\w*\b(?<=\w)/g, LtxSemanticType.function, LtxSemanticModification.definition, null);

for (let count = 0; count < sectionsArray.length; count++) {
this.findElements(new RegExp("(?<![\\w\\\\\"])" + sectionsArray[count] + "(?![\\w\\@]+)(?=\\b)", "g"), LtxSemanticType.class, LtxSemanticModification.definition, null);
if (this.owner.canHaveSectionLink()) {
this.findElements(/(?<![\w\@])[\w\@]+?(?![\w\@])(?=\b)/g, LtxSemanticType.class, LtxSemanticModification.definition, null, isOutside);
}
this.tempData = content;
}

private findElements(RegExp : RegExp, SemanticType : LtxSemanticType, SemanticModification, SemanticDescription) {
private findElements(RegExp: RegExp, SemanticType: LtxSemanticType, SemanticModification: LtxSemanticModification, SemanticDescription: LtxSemanticDescription, condition?: (match: RegExpExecArray, condlist: LtxCondlist) => boolean) {
var match;
var data = [];
while ((match = RegExp.exec(this.tempData)) !== null) {
let range = new Range(new Position(this.lineIndex, this.positionIndex + match.index), new Position(this.lineIndex, this.positionIndex + match.index + match[0].length))
addSemantic(new LtxSemantic(SemanticType, SemanticModification, range, SemanticDescription, match[0]))
this.tempData = this.replaceText(this.tempData, match[0]);
if (!(condition ? condition(match, this) : true)) {
continue;
}

var start = this.positionIndex + match.index;
var end = this.positionIndex + match.index + match[0].length;
var range = new Range(new Position(this.lineIndex, start), new Position(this.lineIndex, end));
var token = new LtxSemantic(SemanticType, SemanticModification, range, SemanticDescription, match[0]);
addSemantic(token);
data.push(token);
this.tempData = this.replaceText(this.tempData, match.index, match.index + match[0].length);
}
return data;
}

private replaceText(data: string, start: number, end: number) {
return data.substring(0, start) + " ".repeat(end - start) + data.substring(end);
}
}

private replaceText(data, text) {
return data.replace(new RegExp("(?<=\\b)\\" + text + "(?=\\b)"), " ".repeat(text.length));
function isOutside(match: RegExpExecArray, condlist: LtxCondlist): boolean {
if (!match) {
return false;
}
var pos = new Position(condlist.lineIndex, condlist.positionIndex + match.index);
return !condlist.isInsideCondition(pos) && !condlist.isInsideFunction(pos);
}
65 changes: 46 additions & 19 deletions src/ltx/ltxDocument.ts
Expand Up @@ -3,14 +3,17 @@ import {
Position,
TextDocument,
Uri,
DiagnosticSeverity
DiagnosticSeverity,
Diagnostic
} from "vscode";
import { LtxError } from "./ltxError";
import { LtxLine } from "./ltxLine";
import { LtxSection } from "./ltxSection";
import { globalSenmaticsData, LtxSemantic, LtxSemanticDescription } from "./ltxSemantic";
import { getFileData } from "../utils/fileReader";
import { getParamsByFile } from "../utils/modulesParser";
import { isDiagnosticEnabled } from "../settings";
import { diagnosticCollection, diagnosticMap } from "../extension";
export var sectionsArray: string[];
export var currentFile: string;

Expand All @@ -27,16 +30,22 @@ export enum LtxDocumentType {
*/
export class LtxDocument {
readonly filePath: string
readonly uri: Uri
readonly text: string
private sections: LtxSection[] = []
private rawData: Map<number, LtxLine> = new Map<number, LtxLine>()
private sectionsName: string[] = []

private semanticData: LtxSemantic[]
private errorsData: LtxError[]
private semanticData: LtxSemantic[] = []
private errorsData: LtxError[] = []

private fileType: LtxDocumentType
private tempSection: LtxSection

addError(range: Range, descr: string, data?: string, errorType?: DiagnosticSeverity, tag?: string) {
this.errorsData.push(new LtxError(range, descr, data, errorType, tag));
}

getSections(): LtxSection[] {
return this.sections;
}
Expand Down Expand Up @@ -75,11 +84,6 @@ export class LtxDocument {
}
}

// TODO: Заменить на Validate
getErrorsData(): LtxError[] {
return this.errorsData;
}

getType(): LtxDocumentType {
return this.fileType;
}
Expand Down Expand Up @@ -151,7 +155,7 @@ export class LtxDocument {
}

canAddSectionLink(position: Position): boolean {
return this.inInsideCondlist(position) && !this.isInsideCondlistGroups(position) && (this.getLine(position).isType("condlist") || this.getLine(position).isType("npc_and_zone"))
return this.inInsideCondlist(position) && !this.isInsideCondlistGroups(position) && this.getLine(position).canHaveSectionLink()
}

/**
Expand Down Expand Up @@ -206,7 +210,7 @@ export class LtxDocument {
* @returns Возвращаем первую секцию, которую мы нашли
*/
private findSection(text: string, lineIndex: number) {
var re = /\[.*\]/g;
var re = /\[.*?\]/g;
var match: RegExpExecArray;
var result: RegExpExecArray;

Expand All @@ -215,8 +219,8 @@ export class LtxDocument {
result = match;
continue;
}
// let range = new Range(new Position(lineIndex, match.index), new Position(lineIndex, match.index + match[0].length));
// addError(range, "В данной строке уже есть объявление секции.", match[0], DiagnosticSeverity.Error, "Remove");
let range = new Range(new Position(lineIndex, match.index), new Position(lineIndex, match.index + match[0].length));
this.addError(range, "В данной строке уже есть объявление секции.", match[0], DiagnosticSeverity.Error, "Section Repetition");
}

return result;
Expand All @@ -232,6 +236,12 @@ export class LtxDocument {
var match;
sectionsArray = [];
while ((match = re.exec(text)) !== null) {
if (sectionsArray.includes(match[0])) {
let substr = text.substring(0, match.index);
let lineIndex = (substr.match(/\n/g) || []).length || 0;
let range = new Range(new Position(lineIndex, substr.length - match.index), new Position(lineIndex, substr.length - match.index + match[0].length));
this.addError(range, "Повторение имени секции", match[0], DiagnosticSeverity.Error, "Section Repetition")
}
sectionsArray.push(match[0]);
}
return sectionsArray;
Expand All @@ -247,7 +257,7 @@ export class LtxDocument {
if (this.tempSection) {
this.closeSection(this.tempSection);
}
this.tempSection = new LtxSection(result[0], lineIndex, result.index, this.fileType);
this.tempSection = new LtxSection(result[0], lineIndex, result.index, this.fileType, this);
return;
}
else if (this.tempSection) {
Expand All @@ -259,7 +269,7 @@ export class LtxDocument {
this.rawData.set(lineIndex, new LtxLine(lineIndex, line, null));
}

private async parsingSections(content: string, args: string[]) {
private async parsingData(content: string, args: string[]) {
let contentArray = content.split("\n");

for (let lineIndex = 0; lineIndex < contentArray.length; lineIndex++) {
Expand All @@ -273,6 +283,22 @@ export class LtxDocument {
for await (const section of this.sections) {
section.parseLines();
}

if (isDiagnosticEnabled()) {
this.validate();
}
}

validate() {
let canonicalFile = this.uri.toString();
var diagnostics = [];
this.errorsData.forEach(item => {
let diagnosticItem = new Diagnostic(item.range, item.descr, item.errorType);
diagnosticItem.code = item.tag;
diagnostics.push(diagnosticItem);
});
diagnosticMap.set(canonicalFile, diagnostics);
diagnosticCollection.set(Uri.parse(canonicalFile), diagnostics);
}

private setDocumentType() {
Expand Down Expand Up @@ -304,15 +330,16 @@ export class LtxDocument {
*/
constructor(document: TextDocument | Uri, args: string[] = []) {
this.filePath = document instanceof Uri ? document.fsPath : document.uri.fsPath;
this.uri = document instanceof Uri ? document : document.uri;
currentFile = this.filePath;

this.setDocumentType();

globalSenmaticsData.set(currentFile, []);

var content = document instanceof Uri ? getFileData(this.filePath) : document.getText();
this.sectionsName = this.findAllSectionsNames(content);
this.text = document instanceof Uri ? getFileData(this.filePath) : document.getText();
this.sectionsName = this.findAllSectionsNames(this.text);

this.parsingSections(content, args);
this.setDocumentType();
this.parsingData(this.text, args);

this.semanticData = globalSenmaticsData.get(currentFile);
}
Expand Down
4 changes: 2 additions & 2 deletions src/ltx/ltxError.ts
Expand Up @@ -7,10 +7,10 @@ export class LtxError {
errorType: DiagnosticSeverity
tag: string

constructor(data: string, range: Range, descr: string, errorType = DiagnosticSeverity.Error, tag? : string) {
constructor(range: Range, descr: string, data?: string, errorType = DiagnosticSeverity.Error, tag? : string) {
this.data = data;
this.range = range;
this.descr = descr;
this.descr = data ? `\`${data}\`: ${descr}` : descr;
this.errorType = errorType;
this.tag = tag;
}
Expand Down
17 changes: 12 additions & 5 deletions src/ltx/ltxLine.ts
Expand Up @@ -33,13 +33,20 @@ export class LtxLine {
}

isType(name: string): boolean {
return this.getType().includes(name);
return this.getType() ? this.getType().includes(name) : false;
}

canHaveSectionLink(): boolean {
return this.isType("condlist") || this.isType("npc_and_zone");
}

getType(): string | null {
for (const param of getSectionData().get(this.owner.getTypeName())) {
if (param.indexOf(this.propertyName) !== -1) {
return param.split(":")[0];
const data = getSectionData().get(this.owner.getTypeName());
if (data) {
for (const param of data) {
if (param.indexOf(this.propertyName) !== -1) {
return param.split(":")[0];
}
}
}

Expand Down Expand Up @@ -96,7 +103,7 @@ export class LtxLine {
re = /(?<=(\=|\,)).+?(?=(\,|\\n|$))/gm;
let match;
while ((match = re.exec(tempData)) !== null) {
this.condlists.push(new LtxCondlist(index, match.index, match[0]));
this.condlists.push(new LtxCondlist(index, match.index, match[0], this));
}
}
}

0 comments on commit 418d4d4

Please sign in to comment.