From bd9cb758bed01d1799b6d15b7d3aaadc8e9f50a7 Mon Sep 17 00:00:00 2001 From: Stephen M Moraco Date: Tue, 21 Nov 2023 21:24:55 -0700 Subject: [PATCH] repair multiline symbol lookup --- .../TEST_LANG_SERVER/spin2/221206-fixes.spin2 | 2 +- .../TEST_LANG_SERVER/spin2/231118-fixes.spin2 | 1 + spin2/server/src/parser/spin.common.ts | 35 +++++++++---------- .../parser/spin2.documentSemanticParser.ts | 29 ++++++--------- 4 files changed, 28 insertions(+), 39 deletions(-) diff --git a/spin2/TEST_LANG_SERVER/spin2/221206-fixes.spin2 b/spin2/TEST_LANG_SERVER/spin2/221206-fixes.spin2 index dc902df..97b5dbc 100644 --- a/spin2/TEST_LANG_SERVER/spin2/221206-fixes.spin2 +++ b/spin2/TEST_LANG_SERVER/spin2/221206-fixes.spin2 @@ -1,6 +1,6 @@ ' Run with DEBUG enabled to view -_clkfreq = 300_000_000 ' <--- FIXME:l not colored correctly (TOP defaults to CON (but syntax, how???) +_clkfreq = 300_000_000 sprites = 128 diff --git a/spin2/TEST_LANG_SERVER/spin2/231118-fixes.spin2 b/spin2/TEST_LANG_SERVER/spin2/231118-fixes.spin2 index a4afb26..95e1327 100644 --- a/spin2/TEST_LANG_SERVER/spin2/231118-fixes.spin2 +++ b/spin2/TEST_LANG_SERVER/spin2/231118-fixes.spin2 @@ -31,6 +31,7 @@ PRI DeleteChainFromID(ID, EndID, Mode, KeepFirstIDValid) | Block, Header Header.[19..8] <> EndID, ... 'mode 1: delete to ThisID = EndID ID <> EndID) 'mode 2: delete to NextID = EndID + while lookupz(Mode: Header.[0], Header.[19..8] <> EndID, ID <> EndID) 'mode 2: delete to NextID = EndID PRI CancelBlock(Block) diff --git a/spin2/server/src/parser/spin.common.ts b/spin2/server/src/parser/spin.common.ts index acdd871..aa820f7 100644 --- a/spin2/server/src/parser/spin.common.ts +++ b/spin2/server/src/parser/spin.common.ts @@ -3,7 +3,6 @@ import { Position } from "vscode-languageserver-types"; import { Context } from "../context"; -import { isBuffer } from "util"; export enum eDebugDisplayType { Unknown = 0, @@ -100,7 +99,7 @@ export class ContinuedLines { this.haveAllLines = true; this._finishLine(); } - this._logMessage(` --- ContLn: addLine() line=[${nextLine}], lineIdx=(${lineIdx}), nbrLines=(${this.rawLines.length}), haveAllLines=(${this.haveAllLines})`); + //this._logMessage(` --- ContLn: addLine() line=[${nextLine}], lineIdx=(${lineIdx}), nbrLines=(${this.rawLines.length}), haveAllLines=(${this.haveAllLines})`); } else { this._logMessage(` --- ContLn: ERROR addLine() line=[${nextLine}], lineIdx=(${lineIdx}) - attempt add after last line arrived!`); } @@ -205,9 +204,9 @@ export class ContinuedLines { let rawIdx: number = 0; let remainingOffset: number = offset; // subtract earlier line lengths from remainder to locate line our symbol is on - //this._logMessage( - // ` --- ContLn: ENTRY locateSymbol([${symbolName}], srtOfs=(${offset})) - rawLines=(${this.rawLines.length}), Ln#${this.lineStartIdx + 1}-${this.lineStartIdx + this.rawLines.length}` - //); + this._logMessage( + ` --- ContLn: ENTRY locateSymbol([${symbolName}], srtOfs=(${offset})) - rawLines=(${this.rawLines.length}), Ln#${this.lineStartIdx + 1}-${this.lineStartIdx + this.rawLines.length}` + ); for (let index = 0; index < this.rawLines.length; index++) { const rawPossContLine: string = this.rawLines[index]; const isLineContinued: boolean = rawPossContLine.endsWith("..."); @@ -215,31 +214,29 @@ export class ContinuedLines { const foundLineWhiteSpaceLength = this._skipWhite(rawPossContLine, 0); // if the first line, don't take out the leading whitespace const accumLength = index == 0 ? foundLineWhiteSpaceLength + currLineLength : currLineLength; - //this._logMessage( - // ` --- ContLn: ls() - CHECKING rawIdx=(${rawIdx}), remainingOffset=(${remainingOffset}), currLineLength=(${currLineLength}), isLineContinued=(${isLineContinued}) continuedLine=[${rawPossContLine}](${rawPossContLine.length})` - //); + const trimmedLineContentOnly: string = isLineContinued ? rawPossContLine.slice(0, -3).trimEnd() : rawPossContLine.trimEnd(); + const remainingString: string = index == 0 ? trimmedLineContentOnly.substring(remainingOffset) : trimmedLineContentOnly.trimStart().substring(remainingOffset); + /* + this._logMessage(` --- ContLn: ls() - CHECKING rawIdx=(${rawIdx}), remainingOffset=(${remainingOffset}), currLineLength=(${currLineLength}), isLineContinued=(${isLineContinued})`); + this._logMessage(` --- ContLn: ls() - CHECKING continuedLine=[${rawPossContLine}](${rawPossContLine.length})`); + this._logMessage(` --- ContLn: ls() - CHECKING remainingString=[${remainingString}](${remainingString.length})`); + //*/ // if our offset is not in this line -or- the remainder of this line is not long enough to contain our symbol - if (remainingOffset > accumLength) { + if (remainingOffset >= accumLength) { // not in this line... go to next... rawIdx++; remainingOffset -= accumLength; //this._logMessage( // ` --- ContLn: ls() - NOT-LINE rawIdx=(${rawIdx}), remainingOffset=(${remainingOffset}), currLineLength=(${currLineLength}), isLineContinued=(${isLineContinued})` //); - } else if (rawPossContLine.indexOf(symbolName, remainingOffset) == -1) { + } else if (remainingString.length < symbolName.length || remainingString.indexOf(symbolName) == -1) { // if not found in remainder of line... go to next rawIdx++; remainingOffset = 0; - } else if (currLineLength - remainingOffset < symbolName.length) { - // symbol can't fit in this line? go to next - // FIXME: TODO: is this needed?? / VALID?? - rawIdx++; - remainingOffset = 0; - //this._logMessage(` --- ContLn: ls() - NOT-FIT rawIdx=(${rawIdx}), remainingOffset=(${remainingOffset}), currLineLength=(${currLineLength}), isLineContinued=(${isLineContinued})`); } else { // must be in this line! this._logMessage( - ` --- ContLn: locateSymbol() - THIS-LINE rawIdx=(${rawIdx}), remainingOffset=(${remainingOffset}), currLineLength=(${currLineLength}), isLineContinued=(${isLineContinued})` + ` --- ContLn: locateSymbol() - THIS-LINE rawIdx=(${rawIdx}), remainingOffset=(${remainingOffset}), currLineLength=(${currLineLength}), isLineContinued=(${isLineContinued})` ); break; // symbol is in this line } @@ -257,9 +254,9 @@ export class ContinuedLines { desiredLocation = Position.create(lineIdx, symbolOffset); //this._logMessage(` --- ContLn: locateSymbol() -> Posn=[line=(${lineIdx}), char=(${symbolOffset})]`); if (symbolOffset != -1) { - this._logMessage(` --- ContLn: Found IN Ln#${lineIdx + 1} [${this.rawLines[rawIdx]}](${this.rawLines[rawIdx].length})`); + this._logMessage(` --- ContLn: Found [${symbolName}] IN Ln#${lineIdx + 1} [${this.rawLines[rawIdx]}](${this.rawLines[rawIdx].length})`); } else { - this._logMessage(` --- NOT found! ?? [${symbolName}] NOT in line=[${this.rawLines[rawIdx]}] ??`); + this._logMessage(` --- ERROR NOT found! ?? [${symbolName}] NOT in line=[${this.rawLines[rawIdx]}] ??`); } } return desiredLocation; diff --git a/spin2/server/src/parser/spin2.documentSemanticParser.ts b/spin2/server/src/parser/spin2.documentSemanticParser.ts index 3948731..7988c0c 100644 --- a/spin2/server/src/parser/spin2.documentSemanticParser.ts +++ b/spin2/server/src/parser/spin2.documentSemanticParser.ts @@ -3836,10 +3836,10 @@ export class Spin2DocumentSemanticParser { if (variableNamePart.endsWith(".")) { variableNamePart = variableNamePart.substr(0, variableNamePart.length - 1); } - //const nameOffset = line.indexOf(variableNamePart, currSingleLineOffset); - symbolPosition = multiLineSet.locateSymbol(variableNamePart, currSingleLineOffset); - let nameOffset = multiLineSet.offsetIntoLineForPosition(symbolPosition); if (variableNamePart.charAt(0).match(/[a-zA-Z_]/)) { + //const nameOffset = line.indexOf(variableNamePart, currSingleLineOffset); + symbolPosition = multiLineSet.locateSymbol(variableNamePart, currSingleLineOffset); + let nameOffset = multiLineSet.offsetIntoLineForPosition(symbolPosition); if (this._isPossibleObjectReference(variableNamePart)) { // go register object reference! const bHaveObjReference = this._reportObjectReference(variableNamePart, symbolPosition.line, symbolPosition.character, multiLineSet.lineAt(symbolPosition.line), tokenSet); @@ -4144,6 +4144,7 @@ export class Spin2DocumentSemanticParser { this._logSPIN(` -- assignmentStringOffset=[${assignmentStringOffset}], bIsDebugLine=(${bIsDebugLine})`); let offsetInNonStringRHS = 0; let currNameLength: number = 0; + this._logSPIN(` -- SPIN Multi loop start currSingleLineOffset=(${currSingleLineOffset})`); for (let index = 0; index < possNames.length; index++) { let possibleName = possNames[index]; // special code to handle case of var.[bitfield] leaving name a 'var.' @@ -4176,27 +4177,17 @@ export class Spin2DocumentSemanticParser { if (!bHaveObjReference) { const searchString: string = possibleNameSet.length == 1 ? possibleNameSet[0] : possibleNameSet[0] + "." + possibleNameSet[1]; //nameOffset = nonStringAssignmentRHSStr.indexOf(searchString, offsetInNonStringRHS) + assignmentStringOffset; // so we don't match in in strings... - symbolPosition = multiLineSet.locateSymbol(searchString, currSingleLineOffset); - nameOffset = multiLineSet.offsetIntoLineForPosition(symbolPosition); this._logSPIN(` -- SPIN RHS nonStringAssignmentRHSStr=[${nonStringAssignmentRHSStr}]`); this._logSPIN(` -- SPIN RHS searchString=[${searchString}]`); this._logSPIN(` -- SPIN RHS nameOffset=(${nameOffset}), offsetInNonStringRHS=(${offsetInNonStringRHS}), currSingleLineOffset=(${currSingleLineOffset})`); let referenceDetails: RememberedToken | undefined = undefined; if (this.semanticFindings.isLocalToken(namePart)) { referenceDetails = this.semanticFindings.getLocalTokenForLine(namePart, symbolPosition.line + 1); - if (referenceDetails) { - this._logSPIN(` -- FOUND Local name=[${namePart}], referenceDetails=(${referenceDetails})`); - } else { - this._logSPIN(` -- EXISTS Local name=[${namePart}], BUT referenceDetails=(${referenceDetails})`); - } + this._logSPIN(` -- FOUND Local name=[${namePart}], referenceDetails=(${referenceDetails})`); } if (!referenceDetails && this.semanticFindings.isGlobalToken(namePart)) { referenceDetails = this.semanticFindings.getGlobalToken(namePart); - if (referenceDetails) { - this._logSPIN(` -- FOUND Global name=[${namePart}], referenceDetails=(${referenceDetails})`); - } else { - this._logSPIN(` -- EXISTS Global name=[${namePart}], BUT referenceDetails=(${referenceDetails})`); - } + this._logSPIN(` -- FOUND Global name=[${namePart}], referenceDetails=(${referenceDetails})`); if (referenceDetails != undefined && referenceDetails?.type == "method") { const methodCallNoSpace = `${namePart}(`; const methodCallSpace = `${namePart} (`; @@ -4357,8 +4348,8 @@ export class Spin2DocumentSemanticParser { }); } offsetInNonStringRHS += currNameLength + 1; - currSingleLineOffset += currNameLength + 1; - //this._logSPIN(` -- SPIN ADVANCE by name part len - offsetInNonStringRHS: (${priorInNonStringRHS}) -> (${offsetInNonStringRHS}), currentOffset: (${priorOffset}) -> (${currentOffset})`); + currSingleLineOffset = nameOffset > 0 ? nameOffset + currNameLength : currSingleLineOffset + currNameLength; + this._logSPIN(` -- SPIN Multi loop currSingleLineOffset=(${currSingleLineOffset}) <-- nameOffset=(${nameOffset}), currNameLength=(${currNameLength})`); } } return tokenSet; @@ -4721,11 +4712,11 @@ export class Spin2DocumentSemanticParser { let nameOffset: number = 0; currNameLength = possibleName.length; if (possibleName.charAt(0).match(/[a-zA-Z_]/)) { - this._logSPIN(" -- possibleName=[" + possibleName + "]"); + this._logSPIN(` -- possibleName=[${possibleName}]`); // does name contain a namespace reference? if (possibleName.includes(".")) { possibleNameSet = possibleName.split("."); - this._logSPIN(" -- possibleNameSet=[" + possibleNameSet + "]"); + this._logSPIN(` -- possibleNameSet=[${possibleNameSet}]`); } const namePart = possibleNameSet[0]; currNameLength = namePart.length;