77/// <reference path="../typings/promise.d.ts" />
88/// <reference path="../node_modules/@types/node/index.d.ts" />
99
10+ import * as ng from '@angular/language-service' ;
11+
1012import 'reflect-metadata' ;
1113import {
1214 IPCMessageReader , IPCMessageWriter ,
1315 createConnection , IConnection , TextDocumentSyncKind ,
1416 TextDocument , Diagnostic , DiagnosticSeverity ,
1517 InitializeParams , InitializeResult , TextDocumentPositionParams ,
16- CompletionItem , CompletionItemKind , Definition , TextDocumentIdentifier ,
17- Position , Range , TextEdit
18+ CompletionItem , CompletionItemKind , Definition , Location , TextDocumentIdentifier ,
19+ Position , Range , TextEdit , Hover
1820} from 'vscode-languageserver' ;
1921
20- import { TextDocuments , TextDocumentEvent } from './documents' ;
22+ import { TextDocuments , TextDocumentEvent , fileNameToUri } from './documents' ;
2123import { ErrorCollector } from './errors' ;
2224
2325import { Completion , Span } from '@angular/language-service' ;
@@ -60,7 +62,9 @@ connection.onInitialize((params): InitializeResult => {
6062 completionProvider : {
6163 resolveProvider : false ,
6264 triggerCharacters : [ '<' , '.' , '*' , '[' , '(' ]
63- }
65+ } ,
66+ definitionProvider : true ,
67+ hoverProvider : true
6468 }
6569 }
6670} ) ;
@@ -93,7 +97,6 @@ function insertionToEdit(range: Range, insertText: string): TextEdit {
9397 }
9498}
9599
96-
97100function getReplaceRange ( document : TextDocumentIdentifier , offset : number ) : Range {
98101 const line = documents . getDocumentLine ( document , offset ) ;
99102 if ( line && line . text && line . start <= offset && line . start + line . text . length >= offset ) {
@@ -146,5 +149,54 @@ connection.onCompletion((textDocumentPosition: TextDocumentPositionParams): Comp
146149 }
147150} ) ;
148151
152+ function ngDefintionToDefintion ( definition : ng . Definition ) : Definition {
153+ const locations = definition . map ( d => {
154+ const document = TextDocumentIdentifier . create ( fileNameToUri ( d . fileName ) ) ;
155+ const positions = documents . offsetsToPositions ( document , [ d . span . start , d . span . end ] ) ;
156+ return { document, positions}
157+ } ) . filter ( d => d . positions . length > 0 ) . map ( d => {
158+ const range = Range . create ( d . positions [ 0 ] , d . positions [ 1 ] ) ;
159+ return Location . create ( d . document . uri , range ) ;
160+ } ) ;
161+ if ( locations && locations . length ) {
162+ return locations ;
163+ }
164+ }
165+
166+ connection . onDefinition ( ( textDocumentPosition : TextDocumentPositionParams ) : Definition => {
167+ const { fileName, service, offset, languageId} = documents . getServiceInfo ( textDocumentPosition . textDocument ,
168+ textDocumentPosition . position )
169+ if ( fileName && service && offset != null ) {
170+ let result = service . getDefinitionAt ( fileName , offset ) ;
171+ if ( result ) {
172+ return ngDefintionToDefintion ( result ) ;
173+ }
174+ }
175+ } ) ;
176+
177+ function ngHoverToHover ( hover : ng . Hover , document : TextDocumentIdentifier ) : Hover {
178+ if ( hover ) {
179+ const positions = documents . offsetsToPositions ( document , [ hover . span . start , hover . span . end ] ) ;
180+ if ( positions ) {
181+ const range = Range . create ( positions [ 0 ] , positions [ 1 ] ) ;
182+ return {
183+ contents : { language : 'typescript' , value : hover . text . map ( t => t . text ) . join ( '' ) } ,
184+ range
185+ } ;
186+ }
187+ }
188+ }
189+
190+ connection . onHover ( ( textDocumentPosition : TextDocumentPositionParams ) : Hover => {
191+ const { fileName, service, offset, languageId} = documents . getServiceInfo ( textDocumentPosition . textDocument ,
192+ textDocumentPosition . position )
193+ if ( fileName && service && offset != null ) {
194+ let result = service . getHoverAt ( fileName , offset ) ;
195+ if ( result ) {
196+ return ngHoverToHover ( result , textDocumentPosition . textDocument ) ;
197+ }
198+ }
199+ } ) ;
200+
149201// Listen on the connection
150202connection . listen ( ) ;
0 commit comments