diff --git a/packages/language-service/BUILD.bazel b/packages/language-service/BUILD.bazel index 320cc23995..7869219b68 100644 --- a/packages/language-service/BUILD.bazel +++ b/packages/language-service/BUILD.bazel @@ -19,6 +19,7 @@ ts_library( "//packages/compiler", "//packages/compiler-cli", "//packages/core", + "//packages/language-service/common", "@npm//@types/node", "@npm//typescript", ], diff --git a/packages/language-service/common/BUILD.bazel b/packages/language-service/common/BUILD.bazel new file mode 100644 index 0000000000..afe8f39b56 --- /dev/null +++ b/packages/language-service/common/BUILD.bazel @@ -0,0 +1,11 @@ +load("//tools:defaults.bzl", "ts_library") + +package(default_visibility = ["//packages/language-service:__subpackages__"]) + +ts_library( + name = "common", + srcs = glob(["*.ts"]), + deps = [ + "@npm//typescript", + ], +) diff --git a/packages/language-service/common/quick_info.ts b/packages/language-service/common/quick_info.ts new file mode 100644 index 0000000000..9f1076e98a --- /dev/null +++ b/packages/language-service/common/quick_info.ts @@ -0,0 +1,60 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +import * as ts from 'typescript'; + +// Reverse mappings of enum would generate strings +export const ALIAS_NAME = ts.SymbolDisplayPartKind[ts.SymbolDisplayPartKind.aliasName]; +export const SYMBOL_INTERFACE = ts.SymbolDisplayPartKind[ts.SymbolDisplayPartKind.interfaceName]; +export const SYMBOL_PUNC = ts.SymbolDisplayPartKind[ts.SymbolDisplayPartKind.punctuation]; +export const SYMBOL_SPACE = ts.SymbolDisplayPartKind[ts.SymbolDisplayPartKind.space]; +export const SYMBOL_TEXT = ts.SymbolDisplayPartKind[ts.SymbolDisplayPartKind.text]; + +/** + * Construct a QuickInfo object taking into account its container and type. + * @param name Name of the QuickInfo target + * @param kind component, directive, pipe, etc. + * @param textSpan span of the target + * @param containerName either the Symbol's container or the NgModule that contains the directive + * @param type user-friendly name of the type + * @param documentation docstring or comment + */ +export function createQuickInfo( + name: string, kind: string, textSpan: ts.TextSpan, containerName?: string, type?: string, + documentation?: ts.SymbolDisplayPart[]): ts.QuickInfo { + const containerDisplayParts = containerName ? + [ + {text: containerName, kind: SYMBOL_INTERFACE}, + {text: '.', kind: SYMBOL_PUNC}, + ] : + []; + + const typeDisplayParts = type ? + [ + {text: ':', kind: SYMBOL_PUNC}, + {text: ' ', kind: SYMBOL_SPACE}, + {text: type, kind: SYMBOL_INTERFACE}, + ] : + []; + + return { + kind: kind as ts.ScriptElementKind, + kindModifiers: ts.ScriptElementKindModifier.none, + textSpan: textSpan, + displayParts: [ + {text: '(', kind: SYMBOL_PUNC}, + {text: kind, kind: SYMBOL_TEXT}, + {text: ')', kind: SYMBOL_PUNC}, + {text: ' ', kind: SYMBOL_SPACE}, + ...containerDisplayParts, + {text: name, kind: SYMBOL_INTERFACE}, + ...typeDisplayParts, + ], + documentation, + }; +} diff --git a/packages/language-service/ivy/BUILD.bazel b/packages/language-service/ivy/BUILD.bazel index f512182eb6..e5886aacd9 100644 --- a/packages/language-service/ivy/BUILD.bazel +++ b/packages/language-service/ivy/BUILD.bazel @@ -15,8 +15,7 @@ ts_library( "//packages/compiler-cli/src/ngtsc/shims", "//packages/compiler-cli/src/ngtsc/typecheck", "//packages/compiler-cli/src/ngtsc/typecheck/api", - # TODO(atscott): Pull functions/variables common to VE and Ivy into a new package - "//packages/language-service", + "//packages/language-service/common", "@npm//typescript", ], ) diff --git a/packages/language-service/ivy/quick_info.ts b/packages/language-service/ivy/quick_info.ts index 76ba3b0d40..cab76ba08e 100644 --- a/packages/language-service/ivy/quick_info.ts +++ b/packages/language-service/ivy/quick_info.ts @@ -10,7 +10,7 @@ import {NgCompiler} from '@angular/compiler-cli/src/ngtsc/core'; import {DirectiveSymbol, DomBindingSymbol, ElementSymbol, ExpressionSymbol, InputBindingSymbol, OutputBindingSymbol, ReferenceSymbol, ShimLocation, Symbol, SymbolKind, VariableSymbol} from '@angular/compiler-cli/src/ngtsc/typecheck/api'; import * as ts from 'typescript'; -import {createQuickInfo, SYMBOL_PUNC, SYMBOL_SPACE, SYMBOL_TEXT} from '../src/hover'; +import {createQuickInfo, SYMBOL_PUNC, SYMBOL_SPACE, SYMBOL_TEXT} from '../common/quick_info'; import {findNodeAtPosition} from './hybrid_visitor'; import {filterAliasImports, getDirectiveMatches, getDirectiveMatchesForAttribute, getTemplateInfoAtPosition, getTextSpanOfNode} from './utils'; diff --git a/packages/language-service/ivy/utils.ts b/packages/language-service/ivy/utils.ts index a2ad10423d..a900eb970c 100644 --- a/packages/language-service/ivy/utils.ts +++ b/packages/language-service/ivy/utils.ts @@ -12,7 +12,7 @@ import * as e from '@angular/compiler/src/expression_parser/ast'; // e for expr import * as t from '@angular/compiler/src/render3/r3_ast'; // t for template AST import * as ts from 'typescript'; -import {ALIAS_NAME, SYMBOL_PUNC} from '../src/hover'; +import {ALIAS_NAME, SYMBOL_PUNC} from '../common/quick_info'; /** * Given a list of directives and a text to use as a selector, returns the directives which match diff --git a/packages/language-service/src/hover.ts b/packages/language-service/src/hover.ts index 781d06d2b9..9bc98a3f86 100644 --- a/packages/language-service/src/hover.ts +++ b/packages/language-service/src/hover.ts @@ -8,17 +8,13 @@ import {NgAnalyzedModules} from '@angular/compiler'; import * as ts from 'typescript'; + +import {createQuickInfo} from '../common/quick_info'; + import {locateSymbols} from './locate_symbol'; import * as ng from './types'; import {inSpan} from './utils'; -// Reverse mappings of enum would generate strings -export const SYMBOL_SPACE = ts.SymbolDisplayPartKind[ts.SymbolDisplayPartKind.space]; -export const SYMBOL_PUNC = ts.SymbolDisplayPartKind[ts.SymbolDisplayPartKind.punctuation]; -export const SYMBOL_TEXT = ts.SymbolDisplayPartKind[ts.SymbolDisplayPartKind.text]; -export const SYMBOL_INTERFACE = ts.SymbolDisplayPartKind[ts.SymbolDisplayPartKind.interfaceName]; -export const ALIAS_NAME = ts.SymbolDisplayPartKind[ts.SymbolDisplayPartKind.aliasName]; - /** * Traverse the template AST and look for the symbol located at `position`, then * return the corresponding quick info. @@ -71,47 +67,3 @@ export function getTsHover( } } } - -/** - * Construct a QuickInfo object taking into account its container and type. - * @param name Name of the QuickInfo target - * @param kind component, directive, pipe, etc. - * @param textSpan span of the target - * @param containerName either the Symbol's container or the NgModule that contains the directive - * @param type user-friendly name of the type - * @param documentation docstring or comment - */ -export function createQuickInfo( - name: string, kind: string, textSpan: ts.TextSpan, containerName?: string, type?: string, - documentation?: ts.SymbolDisplayPart[]): ts.QuickInfo { - const containerDisplayParts = containerName ? - [ - {text: containerName, kind: SYMBOL_INTERFACE}, - {text: '.', kind: SYMBOL_PUNC}, - ] : - []; - - const typeDisplayParts = type ? - [ - {text: ':', kind: SYMBOL_PUNC}, - {text: ' ', kind: SYMBOL_SPACE}, - {text: type, kind: SYMBOL_INTERFACE}, - ] : - []; - - return { - kind: kind as ts.ScriptElementKind, - kindModifiers: ts.ScriptElementKindModifier.none, - textSpan: textSpan, - displayParts: [ - {text: '(', kind: SYMBOL_PUNC}, - {text: kind, kind: SYMBOL_TEXT}, - {text: ')', kind: SYMBOL_PUNC}, - {text: ' ', kind: SYMBOL_SPACE}, - ...containerDisplayParts, - {text: name, kind: SYMBOL_INTERFACE}, - ...typeDisplayParts, - ], - documentation, - }; -}