Skip to content
This repository has been archived by the owner on Nov 5, 2021. It is now read-only.

Export getTypeScriptWorker & getJavaScriptWorker to monaco.languages.typescript #8

Merged
merged 1 commit into from Aug 9, 2016

Conversation

paveldk
Copy link
Contributor

@paveldk paveldk commented Jul 29, 2016

The idea behind this pull request is to enable and export the typescript compilation for multiple files.

You can now create multiple models with:

resourceUri = Monaco.Uri.file(filePath);
model = Monaco.editor.createModel(fileContent, language, resourceUri);

(will be good idea to cache those)

In this way, you will feed the typescriptService host with all your available files and then you can simply call:

    Monaco.languages.typescript.getTypeScriptWorker()
            .then(function(worker) {
                worker(model.uri)
                      .then(function(client) {
                            client.getEmitOutput(model.uri.toString().then(function(r) {});
                      });
            });

Which will compile the file you have already created Model for.

We are attaching the function to the Monaco.languages.typescript object so we can use it for multiple files/models and not just the current one.

As this is my first PR I want to make a small step before exposing the whole API (will probably iterate through the worker functions and add those to exports)

Related to microsoft/monaco-editor#35

@msftclas
Copy link

Hi @paveldk, I'm your friendly neighborhood Microsoft Pull Request Bot (You can call me MSBOT). Thanks for your contribution!

In order for us to evaluate and accept your PR, we ask that you sign a contribution license agreement. It's all electronic and will take just minutes. I promise there's no faxing. https://cla.microsoft.com.

TTYL, MSBOT;

@paveldk paveldk force-pushed the pkolev/expose-ts-worker-func branch 2 times, most recently from 35de1f3 to 1885b53 Compare August 1, 2016 11:32
@paveldk
Copy link
Contributor Author

paveldk commented Aug 4, 2016

ping @jrieken

@jrieken jrieken self-assigned this Aug 4, 2016
const worker = (first: Uri, ...more: Uri[]): Promise<TypeScriptWorker> => {
return client.getLanguageServiceWorker(...[first].concat(more));
};
client = new WorkerManager(defaults);
Copy link
Member

@jrieken jrieken Aug 4, 2016

Choose a reason for hiding this comment

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

This won't work cos the method is being called twice which means either JS or TS wins and you never know what you got. I'd make the setupMode method return the client and inside setupTypeScript resp setupJavaScript set the proper state for getJavaScriptWorker and getTypeScriptWorker. Before that those method should simply reject

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup, just figured out the same thing a couple of hours ago. Will apply fix now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should there be just one worker for both JS and TS or 2 separate? If they are separate wouldn't the completion be laggy?

Copy link
Member

Choose a reason for hiding this comment

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

Two workers as we have it now. Since they are scoped one is asked for JS files and the other for TS files

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see how this is better and I can agree with this approach. But if we want to have cross-js-ts completions we either have to use one worker here or change how monaco works with SuggestAdapters and concat results from multiple that can be responsible for certain fail type.

Copy link
Member

Choose a reason for hiding this comment

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

No, both are two separate 'extensions' and cannot be married in that way cos it will disallow having different configurations (compiler options, extra libs) for each. That doesn't mean you cannot have JS files in TypeScript - use the allowJS-options and add them as extra lib or just add JS content as TS-file.

@paveldk paveldk force-pushed the pkolev/expose-ts-worker-func branch 2 times, most recently from 5554eb2 to 26c6e58 Compare August 8, 2016 12:46
@paveldk paveldk changed the title Export getEmitOutput to monaco.languages.typescript Export getTypeScriptWorker & getJavaScriptWorker to monaco.languages.typescript Aug 8, 2016
@paveldk paveldk force-pushed the pkolev/expose-ts-worker-func branch 2 times, most recently from 3fc9491 to e55e12e Compare August 8, 2016 12:52
@paveldk
Copy link
Contributor Author

paveldk commented Aug 8, 2016

@jrieken applied changes -> now exports the workers and all functions are available for use

@@ -53,6 +76,8 @@ function setupMode(defaults:LanguageServiceDefaultsImpl, modeId:string, language
disposables.push(new languageFeatures.DiagnostcsAdapter(defaults, modeId, worker));
disposables.push(monaco.languages.setLanguageConfiguration(modeId, richEditConfiguration));
disposables.push(monaco.languages.setTokensProvider(modeId, createTokenizationSupport(language)));

return client;
Copy link
Member

Choose a reason for hiding this comment

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

Instead of the client you could export the worker function here. It already does the right thing. Also note that you should have a signature that takes n resources otherwise there framework might drop them again

@paveldk paveldk force-pushed the pkolev/expose-ts-worker-func branch from e55e12e to 1bf301f Compare August 9, 2016 07:00
@jrieken
Copy link
Member

jrieken commented Aug 9, 2016

LGTM

@ErkoKnoll
Copy link

ErkoKnoll commented Nov 28, 2017

Works nicely, however I'm adding some additional libraries using monaco.languages.typescript.typescriptDefaults.addExtraLib function and when I compile using your proposed solution where the model is derived from the editor (editor.getModel()) then it only compiles what's written in the editor and everything that is added using addExtraLib function is ignored in the compiled output.

Is it possible to have compiler including also the files added using addExtraLib function so the compiled output contains everything in the context and not only whats written in the editor?

I guess it would be possible to manually concatenate everything that was added as extra libs including the editor content to a single model and then have it compiled but it seems rather manual.

@Viatorus
Copy link

Viatorus commented Jun 6, 2018

@ThorConzales
Did you solve the issue with additional libraries?

@ErkoKnoll
Copy link

I solved it by concatenating everything to a single file and compiling it with typescript-simple.

@rjamesnw
Copy link

rjamesnw commented Mar 12, 2019

Is there any docs on this yet? What functions are exposed? I was hoping to get access to the language service itself but it seems you made proxies using promises instead.

Some TypeScript definitions would have been enough; not sure why the service returns "any" when it could have returned the promise structures.

@rjamesnw
Copy link

rjamesnw commented Mar 12, 2019

After some more research and reviewing the debugger, I created this if it helps anyone:

namespace ts {
    export interface IMonacoTypeScriptServiceProxy {
        _getModel(uri: string): Promise<{ _eol: string, _lineStarts: any, _Lines: string[], length: number, _uri: monaco.Uri, _versionId: number }>;
        getCompilationSettings(): Promise<CompilerOptions>;
        getCompilerOptionsDiagnostics(): Promise<Diagnostic[]>;
        getCompletionEntryDetails(uri: string, position: number, name: string, formatOptions: FormatCodeOptions | FormatCodeSettings | undefined, source: string | undefined, preferences: UserPreferences | undefined): Promise<CompletionEntryDetails | undefined>;
        getCompletionsAtPosition(uri: string, position: number, options: GetCompletionsAtPositionOptions | undefined): Promise<WithMetadata<CompletionInfo> | undefined>;
        getCurrentDirectory(): Promise<string>;
        getDefaultLibFileName(options: CompilerOptions): Promise<string>;
        getDefinitionAtPosition(uri: string, position: number): Promise<ReadonlyArray<DefinitionInfo> | undefined>;
        getEmitOutput(uri: string, emitOnlyDtsFiles?: boolean): Promise<EmitOutput>;
        getFormattingEditsAfterKeystroke(uri: string, position: number, key: string, options: FormatCodeOptions | FormatCodeSettings): Promise<TextChange[]>;
        getFormattingEditsForDocument(uri: string, options: FormatCodeOptions | FormatCodeSettings): Promise<TextChange[]>;
        getFormattingEditsForRange(uri: string, start: number, end: number, options: FormatCodeOptions | FormatCodeSettings): Promise<TextChange[]>;
        getNavigationBarItems(uri: string): Promise<NavigationBarItem[]>;
        getOccurrencesAtPosition(uri: string, position: number): Promise<ReadonlyArray<ReferenceEntry> | undefined>;
        getQuickInfoAtPosition(uri: string, position: number): Promise<QuickInfo | undefined>;
        getReferencesAtPosition(uri: string, position: number): Promise<ReferenceEntry[] | undefined>;
        getScriptFileNames(): Promise<string[]>;
        getScriptKind(uri: string): Promise<ScriptKind>;
        getScriptSnapshot(uri: string): Promise<IScriptSnapshot | undefined>;
        getScriptVersion(uri: string): Promise<string>;
        /** The first time this is called, it will return global diagnostics (no location). */
        getSemanticDiagnostics(uri: string): Promise<Diagnostic[]>;
        getSignatureHelpItems(uri: string, position: number, options: SignatureHelpItemsOptions | undefined): Promise<SignatureHelpItems | undefined>;
        getSyntacticDiagnostics(uri: string): Promise<DiagnosticWithLocation[]>;
        isDefaultLibFileName(uri: string): Promise<boolean>;
    }
}

var editor = monaco.editor.create(...etc...);
var tsProxy: ts.IMonacoTypeScriptServiceProxy;

monaco.languages.typescript.getTypeScriptWorker()
            .then(function(worker: (v: monaco.Uri) => Promise<ts.IMonacoTypeScriptServiceProxy>) {
                worker(editor.getModel().uri)
                      .then(function(proxy) {
                            tsProxy = proxy;
                      });
            });

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
7 participants