"Fossies" - the Fresh Open Source Software Archive

Member "angular-13.3.9/packages/language-service/src/adapters.ts" (18 May 2022, 6880 Bytes) of package /linux/www/angular-13.3.9.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) TypeScript source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "adapters.ts": 13.3.6_vs_13.3.7.

    1 /**
    2  * @license
    3  * Copyright Google LLC All Rights Reserved.
    4  *
    5  * Use of this source code is governed by an MIT-style license that can be
    6  * found in the LICENSE file at https://angular.io/license
    7  */
    8 
    9 /** @fileoverview provides adapters for communicating with the ng compiler */
   10 
   11 import {ConfigurationHost} from '@angular/compiler-cli';
   12 import {NgCompilerAdapter} from '@angular/compiler-cli/src/ngtsc/core/api';
   13 import {AbsoluteFsPath, FileStats, PathSegment, PathString} from '@angular/compiler-cli/src/ngtsc/file_system';
   14 import {isShim} from '@angular/compiler-cli/src/ngtsc/shims';
   15 import {getRootDirs} from '@angular/compiler-cli/src/ngtsc/util/src/typescript';
   16 import * as p from 'path';
   17 import * as ts from 'typescript/lib/tsserverlibrary';
   18 
   19 import {isTypeScriptFile} from './utils';
   20 
   21 const PRE_COMPILED_STYLE_EXTENSIONS = ['.scss', '.sass', '.less', '.styl'];
   22 
   23 export class LanguageServiceAdapter implements NgCompilerAdapter {
   24   readonly entryPoint = null;
   25   readonly constructionDiagnostics: ts.Diagnostic[] = [];
   26   readonly ignoreForEmit: Set<ts.SourceFile> = new Set();
   27   readonly factoryTracker = null;      // no .ngfactory shims
   28   readonly unifiedModulesHost = null;  // only used in Bazel
   29   readonly rootDirs: AbsoluteFsPath[];
   30 
   31   /**
   32    * Map of resource filenames to the version of the file last read via `readResource`.
   33    *
   34    * Used to implement `getModifiedResourceFiles`.
   35    */
   36   private readonly lastReadResourceVersion = new Map<string, string>();
   37 
   38   constructor(private readonly project: ts.server.Project) {
   39     this.rootDirs = getRootDirs(this, project.getCompilationSettings());
   40   }
   41 
   42   resourceNameToFileName(
   43       url: string, fromFile: string,
   44       fallbackResolve?: (url: string, fromFile: string) => string | null): string|null {
   45     // If we are trying to resolve a `.css` file, see if we can find a pre-compiled file with the
   46     // same name instead. That way, we can provide go-to-definition for the pre-compiled files which
   47     // would generally be the desired behavior.
   48     if (url.endsWith('.css')) {
   49       const styleUrl = p.resolve(fromFile, '..', url);
   50       for (const ext of PRE_COMPILED_STYLE_EXTENSIONS) {
   51         const precompiledFileUrl = styleUrl.replace(/\.css$/, ext);
   52         if (this.fileExists(precompiledFileUrl)) {
   53           return precompiledFileUrl;
   54         }
   55       }
   56     }
   57     return fallbackResolve?.(url, fromFile) ?? null;
   58   }
   59 
   60   isShim(sf: ts.SourceFile): boolean {
   61     return isShim(sf);
   62   }
   63 
   64   isResource(sf: ts.SourceFile): boolean {
   65     const scriptInfo = this.project.getScriptInfo(sf.fileName);
   66     return scriptInfo?.scriptKind === ts.ScriptKind.Unknown;
   67   }
   68 
   69   fileExists(fileName: string): boolean {
   70     return this.project.fileExists(fileName);
   71   }
   72 
   73   readFile(fileName: string): string|undefined {
   74     return this.project.readFile(fileName);
   75   }
   76 
   77   getCurrentDirectory(): string {
   78     return this.project.getCurrentDirectory();
   79   }
   80 
   81   getCanonicalFileName(fileName: string): string {
   82     return this.project.projectService.toCanonicalFileName(fileName);
   83   }
   84 
   85   /**
   86    * Return the real path of a symlink. This method is required in order to
   87    * resolve symlinks in node_modules.
   88    */
   89   realpath(path: string): string {
   90     return this.project.realpath?.(path) ?? path;
   91   }
   92 
   93   /**
   94    * readResource() is an Angular-specific method for reading files that are not
   95    * managed by the TS compiler host, namely templates and stylesheets.
   96    * It is a method on ExtendedTsCompilerHost, see
   97    * packages/compiler-cli/src/ngtsc/core/api/src/interfaces.ts
   98    */
   99   readResource(fileName: string): string {
  100     if (isTypeScriptFile(fileName)) {
  101       throw new Error(`readResource() should not be called on TS file: ${fileName}`);
  102     }
  103     // Calling getScriptSnapshot() will actually create a ScriptInfo if it does
  104     // not exist! The same applies for getScriptVersion().
  105     // getScriptInfo() will not create one if it does not exist.
  106     // In this case, we *want* a script info to be created so that we could
  107     // keep track of its version.
  108     const version = this.project.getScriptVersion(fileName);
  109     this.lastReadResourceVersion.set(fileName, version);
  110     const scriptInfo = this.project.getScriptInfo(fileName);
  111     if (!scriptInfo) {
  112       // // This should not happen because it would have failed already at `getScriptVersion`.
  113       throw new Error(`Failed to get script info when trying to read ${fileName}`);
  114     }
  115     // Add external resources as root files to the project since we project language service
  116     // features for them (this is currently only the case for HTML files, but we could investigate
  117     // css file features in the future). This prevents the project from being closed when navigating
  118     // away from a resource file.
  119     if (!this.project.isRoot(scriptInfo)) {
  120       this.project.addRoot(scriptInfo);
  121     }
  122     const snapshot = scriptInfo.getSnapshot();
  123     return snapshot.getText(0, snapshot.getLength());
  124   }
  125 
  126   getModifiedResourceFiles(): Set<string>|undefined {
  127     const modifiedFiles = new Set<string>();
  128     for (const [fileName, oldVersion] of this.lastReadResourceVersion) {
  129       if (this.project.getScriptVersion(fileName) !== oldVersion) {
  130         modifiedFiles.add(fileName);
  131       }
  132     }
  133     return modifiedFiles.size > 0 ? modifiedFiles : undefined;
  134   }
  135 }
  136 
  137 /**
  138  * Used to read configuration files.
  139  *
  140  * A language service parse configuration host is independent of the adapter
  141  * because signatures of calls like `FileSystem#readFile` are a bit stricter
  142  * than those on the adapter.
  143  */
  144 export class LSParseConfigHost implements ConfigurationHost {
  145   constructor(private readonly serverHost: ts.server.ServerHost) {}
  146   exists(path: AbsoluteFsPath): boolean {
  147     return this.serverHost.fileExists(path) || this.serverHost.directoryExists(path);
  148   }
  149   readFile(path: AbsoluteFsPath): string {
  150     const content = this.serverHost.readFile(path);
  151     if (content === undefined) {
  152       throw new Error(`LanguageServiceFS#readFile called on unavailable file ${path}`);
  153     }
  154     return content;
  155   }
  156   lstat(path: AbsoluteFsPath): FileStats {
  157     return {
  158       isFile: () => {
  159         return this.serverHost.fileExists(path);
  160       },
  161       isDirectory: () => {
  162         return this.serverHost.directoryExists(path);
  163       },
  164       isSymbolicLink: () => {
  165         throw new Error(`LanguageServiceFS#lstat#isSymbolicLink not implemented`);
  166       },
  167     };
  168   }
  169   pwd(): AbsoluteFsPath {
  170     return this.serverHost.getCurrentDirectory() as AbsoluteFsPath;
  171   }
  172   extname(path: AbsoluteFsPath|PathSegment): string {
  173     return p.extname(path);
  174   }
  175   resolve(...paths: string[]): AbsoluteFsPath {
  176     return p.resolve(...paths) as AbsoluteFsPath;
  177   }
  178   dirname<T extends PathString>(file: T): T {
  179     return p.dirname(file) as T;
  180   }
  181   join<T extends PathString>(basePath: T, ...paths: string[]): T {
  182     return p.join(basePath, ...paths) as T;
  183   }
  184 }