CodeBlanks Logo Icon CodeBlanks

Plugin design

Write a language service plugin skeleton.

What is a language service plugin?

A language service plugin is a function that decorates the TypeScript language service. It takes a ts.server.PluginCreateInfo and returns a ts.LanguageService. The plugin is enabled by adding it to the plugins array in tsconfig.json.

import ts from "typescript";

function createPlugin(
  info: ts.server.PluginCreateInfo
): ts.LanguageService {
  const ls = info.languageService;
  return { ...ls };
}
export = createPlugin;

Plugin skeleton

The skeleton takes the existing language service and wraps its methods. You override methods like getSemanticDiagnostics: first take ls's result, add extras, and return.

return {
  ...ls,
  getSemanticDiagnostics: function(fileName) {
    const prior = ls.getSemanticDiagnostics(fileName);
    return prior;
  },
};

Practice Plugin skeleton

Write a plugin function that takes ts.server.PluginCreateInfo and returns ts.LanguageService. Get ls from info.languageService, wrap getSemanticDiagnostics and return ls's diagnostics as-is. Write a test: a mock language service returns 1 diagnostic; call the plugin and print the diagnostic count.

Starter code

index.ts
import * as ts from "typescript";

// Bir language service plugin fonksiyonu yaz:
// - PluginCreateInfo alır, LanguageService döndürür
// - info'daki dil servisini al
// - Semantic diagnostics metodunu sar ve ls'nin diagnostics'ini döndür
// Bir test yaz: mock dil servisi 1 diagnostic döndürsün
// Plugin'i çağır ve diagnostic sayısını yazdır.

// kodunu buraya yaz

Sample solution

index.ts
import ts from "typescript";

function createPlugin(info: ts.server.PluginCreateInfo): ts.LanguageService {
  const ls = info.languageService;
  return {
    ...ls,
    getSemanticDiagnostics: function(fileName: string) {
      return ls.getSemanticDiagnostics(fileName);
    },
  };
}

const fakeLs = {
  getSemanticDiagnostics: function(_fileName: string): ts.Diagnostic[] {
    return [{ category: ts.DiagnosticCategory.Error, code: 1, messageText: "test", file: undefined, start: 0, length: 1 } as ts.Diagnostic];
  },
} as unknown as ts.LanguageService;

const info = { languageService: fakeLs, config: {} } as unknown as ts.server.PluginCreateInfo;
const plugin = createPlugin(info);
const diags = plugin.getSemanticDiagnostics("app.ts");
console.log(diags.length);

Expected output

1

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 What does a language service plugin return?

  • ts.Diagnostic[]
  • ts.SourceFile
  • ts.LanguageService Correct answer
  • ts.Program

Explanation: A plugin takes PluginCreateInfo and returns a decorated LanguageService. It does not return a Program, Diagnostic[] or SourceFile.

2 Get the language service

Question
function createPlugin(info: ts.server.PluginCreateInfo): ts.LanguageService {
  const ls = info.____;
  return { ...ls };
}
Answer
function createPlugin(info: ts.server.PluginCreateInfo): ts.LanguageService {
  const ls = info.languageService;
  return { ...ls };
}

Explanation: info.languageService gives the existing LanguageService; ls and service properties do not exist, and there is no getService method.

3 Plugin skeleton parts

Term Meaning
PluginCreateInfo Plugin input
info.languageService Existing language service
ts.LanguageService Plugin output
getSemanticDiagnostics Decorated method

All lessons in Expert