Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: dim ignored fields #745

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
91 changes: 24 additions & 67 deletions packages/language-server/src/MessageHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ import {
printLogMessage,
isRelationField,
} from './rename/renameUtil'
import {
checkForExperimentalFeaturesUSeage,
checkForPrisma1Model,
greyOutIgnoredParts,
transformLinterErrorsToDiagnostics,
} from './diagnosticsHandler'

export function getCurrentLine(document: TextDocument, line: number): string {
return document.getText({
Expand Down Expand Up @@ -211,35 +217,6 @@ export function getModelOrEnumBlock(
return foundBlocks[0]
}

function getExperimentalFeaturesRange(
document: TextDocument,
): Range | undefined {
const lines = convertDocumentTextToTrimmedLineArray(document)
const experimentalFeatures = 'experimentalFeatures'
let reachedStartLine = false
for (const [key, item] of lines.entries()) {
if (item.startsWith('generator') && item.includes('{')) {
reachedStartLine = true
}
if (!reachedStartLine) {
continue
}
if (reachedStartLine && item.startsWith('}')) {
return
}

if (item.startsWith(experimentalFeatures)) {
const startIndex = getCurrentLine(document, key).indexOf(
experimentalFeatures,
)
return {
start: { line: key, character: startIndex },
end: { line: key, character: startIndex + experimentalFeatures.length },
}
}
}
}

export async function handleDiagnosticsRequest(
document: TextDocument,
binPath: string,
Expand All @@ -252,55 +229,35 @@ export async function handleDiagnosticsRequest(
}
})

const diagnostics: Diagnostic[] = []
if (
res.some(
(diagnostic) =>
diagnostic.text === "Field declarations don't require a `:`." ||
diagnostic.text ===
'Model declarations have to be indicated with the `model` keyword.',
)
) {
if (checkForPrisma1Model(res)) {
if (onError) {
onError(
"You are currently viewing a Prisma 1 datamodel which is based on the GraphQL syntax. The current Prisma Language Server doesn't support this syntax. Please change the file extension to `.graphql` so the Prisma Language Server does not get triggered anymore.",
)
}
}

for (const diag of res) {
const diagnostic: Diagnostic = {
range: {
start: document.positionAt(diag.start),
end: document.positionAt(diag.end),
},
message: diag.text,
source: '',
}
if (diag.is_warning) {
diagnostic.severity = DiagnosticSeverity.Warning
} else {
diagnostic.severity = DiagnosticSeverity.Error
}
diagnostics.push(diagnostic)
}
const diagnostics: Diagnostic[] = transformLinterErrorsToDiagnostics(
res,
document,
)

// check for experimentalFeatures inside generator block
if (document.getText().includes('experimentalFeatures')) {
const experimentalFeaturesRange:
| Range
| undefined = getExperimentalFeaturesRange(document)
if (experimentalFeaturesRange) {
diagnostics.push({
severity: DiagnosticSeverity.Warning,
range: experimentalFeaturesRange,
message:
"This property has been renamed to 'previewFeatures' to better communicate what they are.",
source: '',
})
}
const experimentalFeaturesUsage = checkForExperimentalFeaturesUSeage(document)
if (experimentalFeaturesUsage) {
diagnostics.push({
severity: DiagnosticSeverity.Warning,
range: experimentalFeaturesUsage,
message:
"This property has been renamed to 'previewFeatures' to better communicate what they are.",
source: '',
})
}

const lines = convertDocumentTextToTrimmedLineArray(document)
const test = greyOutIgnoredParts(document, lines)
diagnostics.push(...test)

return diagnostics
}

Expand Down
119 changes: 119 additions & 0 deletions packages/language-server/src/diagnosticsHandler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { TextDocument } from 'vscode-languageserver-textdocument'
import {
Diagnostic,
DiagnosticSeverity,
DiagnosticTag,
Range,
} from 'vscode-languageserver/node'
import {
convertDocumentTextToTrimmedLineArray,
getBlockAtPosition,
getCurrentLine,
} from './MessageHandler'
import { LinterError } from './prisma-fmt/lint'

export function greyOutIgnoredParts(
document: TextDocument,
lines: string[],
): Diagnostic[] {
const diagnostics: Diagnostic[] = []

lines.map((currElement, index) => {
if (currElement.includes('@@ignore')) {
const block = getBlockAtPosition(index, lines)
if (block) {
diagnostics.push({
range: { start: block.start, end: block.end },
message: 'This model is ignored because it is invalid.',
tags: [DiagnosticTag.Unnecessary],
severity: DiagnosticSeverity.Information,
})
}
} else if (currElement.includes('@ignore')) {
diagnostics.push({
range: {
start: { line: index, character: 0 },
end: { line: index, character: Number.MAX_VALUE },
},
message: 'This field is ignored because it refers to an invalid model.',
tags: [DiagnosticTag.Unnecessary],
severity: DiagnosticSeverity.Information,
})
}
})
Comment on lines +15 to +43
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems the relevant part about greying/dim


return diagnostics
}

export function checkForPrisma1Model(linterErrors: LinterError[]): boolean {
return linterErrors.some(
(diagnostic) =>
diagnostic.text === "Field declarations don't require a `:`." ||
diagnostic.text ===
'Model declarations have to be indicated with the `model` keyword.',
)
}

export function transformLinterErrorsToDiagnostics(
linterErrors: LinterError[],
document: TextDocument,
): Diagnostic[] {
const diagnostics: Diagnostic[] = []
for (const diag of linterErrors) {
const diagnostic: Diagnostic = {
range: {
start: document.positionAt(diag.start),
end: document.positionAt(diag.end),
},
message: diag.text,
source: '',
}
if (diag.is_warning) {
diagnostic.severity = DiagnosticSeverity.Warning
} else {
diagnostic.severity = DiagnosticSeverity.Error
}
diagnostics.push(diagnostic)
}
return diagnostics
}

export function checkForExperimentalFeaturesUSeage(
document: TextDocument,
): Range | undefined {
if (document.getText().includes('experimentalFeatures')) {
const experimentalFeaturesRange:
| Range
| undefined = getExperimentalFeaturesRange(document)
return experimentalFeaturesRange
}
}

function getExperimentalFeaturesRange(
document: TextDocument,
): Range | undefined {
const lines = convertDocumentTextToTrimmedLineArray(document)
const experimentalFeatures = 'experimentalFeatures'
let reachedStartLine = false
for (const [key, item] of lines.entries()) {
if (item.startsWith('generator') && item.includes('{')) {
reachedStartLine = true
}
if (!reachedStartLine) {
continue
}
if (reachedStartLine && item.startsWith('}')) {
return
}

if (item.startsWith(experimentalFeatures)) {
const startIndex = getCurrentLine(document, key).indexOf(
experimentalFeatures,
)
return {
start: { line: key, character: startIndex },
end: { line: key, character: startIndex + experimentalFeatures.length },
}
}
}
}