Skip to content

Commit

Permalink
Add spport for code generation
Browse files Browse the repository at this point in the history
Commands "Generate Genmodel" and "Generate Code" added

Resolves: eclipsesource#33
Signed-off-by: leodennis <[email protected]>
  • Loading branch information
leodennis committed Jan 30, 2020
1 parent fa2d6d2 commit 4c187ab
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
import { FrontendApplication, OpenerService, QuickOpenOptions, QuickOpenService } from "@theia/core/lib/browser";
import { FrontendApplication, OpenerService, /* QuickOpenOptions, */ QuickOpenService } from "@theia/core/lib/browser";
import { Command, CommandContribution, CommandRegistry } from "@theia/core/lib/common/command";
import { MessageService } from "@theia/core/lib/common/message-service";
import { ProgressService } from "@theia/core/lib/common/progress-service";
Expand Down Expand Up @@ -60,7 +60,7 @@ export class CreateProjectCommandContribution implements CommandContribution {
registry.registerCommand(CREATE_NEW_PROJECT, this.newWorkspaceRootUriAwareCommandHandler({
execute: uri => this.getDirectory(uri).then(parent => {
if (parent) {
const parentUri = new URI(parent.uri);
//const parentUri = new URI(parent.uri);
// @Leo hier wird die Methode zum generieren aufgerufen.
// Die Variable uri ist das aktuell markierte Element
// und parentUri ist dann dementsprechend der Ordner darüber(wrsl der Workspace)
Expand Down Expand Up @@ -100,6 +100,7 @@ export class CreateProjectCommandContribution implements CommandContribution {
return this.fileSystem.getFileStat(candidate.parent.toString());
}

/*
private getOptions(placeholder: string, fuzzyMatchLabel: boolean = true, onClose: (canceled: boolean) => void = () => { }): QuickOpenOptions {
return QuickOpenOptions.resolve({
placeholder,
Expand All @@ -108,6 +109,7 @@ export class CreateProjectCommandContribution implements CommandContribution {
onClose
});
}
*/
}

export class WorkspaceRootUriAwareCommandHandler extends UriAwareCommandHandler<URI> {
Expand Down
13 changes: 2 additions & 11 deletions client/theia-ecore/src/browser/EcoreCommandContribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,7 @@
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
import {
FrontendApplication,
open,
OpenerService,
QuickOpenItem,
QuickOpenMode,
QuickOpenModel,
QuickOpenOptions,
QuickOpenService
} from "@theia/core/lib/browser";
import { FrontendApplication, open, OpenerService, QuickOpenItem, QuickOpenMode, QuickOpenModel, QuickOpenOptions, QuickOpenService } from "@theia/core/lib/browser";
import { Command, CommandContribution, CommandRegistry } from "@theia/core/lib/common/command";
import { MessageService } from "@theia/core/lib/common/message-service";
import { ProgressService } from "@theia/core/lib/common/progress-service";
Expand All @@ -35,11 +26,11 @@ import { FileStat, FileSystem } from "@theia/filesystem/lib/common/filesystem";
import { NAVIGATOR_CONTEXT_MENU } from "@theia/navigator/lib/browser/navigator-contribution";
import { WorkspaceService } from "@theia/workspace/lib/browser";
import { inject, injectable } from "inversify";

import { FileGenServer } from "../common/generate-protocol";




export const EXAMPLE_NAVIGATOR = [...NAVIGATOR_CONTEXT_MENU, 'example'];
export const EXAMPLE_EDITOR = [...EDITOR_CONTEXT_MENU, 'example'];

Expand Down
71 changes: 65 additions & 6 deletions client/theia-ecore/src/browser/GenerateCodeCommandContribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
import { FrontendApplication, OpenerService, QuickOpenOptions, QuickOpenService } from "@theia/core/lib/browser";
import {
QuickOpenItem,
QuickOpenMode,
QuickOpenModel
} from "@theia/core/lib/browser";
import { open, FrontendApplication, OpenerService, QuickOpenOptions, QuickOpenService } from "@theia/core/lib/browser";
import { Command, CommandContribution, CommandRegistry } from "@theia/core/lib/common/command";
import { MessageService } from "@theia/core/lib/common/message-service";
import { ProgressService } from "@theia/core/lib/common/progress-service";
Expand Down Expand Up @@ -61,12 +66,39 @@ export class GenerateCodeCommandContribution implements CommandContribution {
execute: uri => this.getDirectory(uri).then(parent => {
if (parent) {
const parentUri = new URI(parent.uri);
// @Leo hier wird die Methode zum generieren aufgerufen.
// Die Variable uri ist das aktuell markierte Element
// und parentUri ist dann dementsprechend der Ordner darüber(wrsl der Workspace)
this.fileGenServer.generateCode().then(() => {
// @Leo hier kannst du die files nachdem sie generiert wurden öffnen

const showInput = (hint: string, prefix: string, onEnter: (result: string) => void) => {
const quickOpenModel: QuickOpenModel = {
onType(lookFor: string, acceptor: (items: QuickOpenItem[]) => void): void {
const dynamicItems: QuickOpenItem[] = [];
const suffix = "Press 'Enter' to confirm or 'Escape' to cancel.";

dynamicItems.push(new SingleStringInputOpenItem(
`${prefix}: ${lookFor}. ${suffix}`,
() => onEnter(lookFor),
(mode: QuickOpenMode) => mode === QuickOpenMode.OPEN,
() => false
));

acceptor(dynamicItems);
}
};
this.quickOpenService.open(quickOpenModel, this.getOptions(hint, false));
};

showInput("Output folder name", "folder name", (folderName) => {
const extensionStart = uri.displayName.lastIndexOf('.');
const ecoreName = uri.displayName.substring(0, extensionStart);
if (folderName.trim() === '') {
folderName = ecoreName;
}
folderName = parentUri.path.toString() + '/' + folderName;
this.fileGenServer.generateCode(uri.path.toString(), folderName, ecoreName).then(() => {
open(this.openerService, uri);
});
});


}
})
}));
Expand Down Expand Up @@ -100,6 +132,7 @@ export class GenerateCodeCommandContribution implements CommandContribution {
return this.fileSystem.getFileStat(candidate.parent.toString());
}


private getOptions(placeholder: string, fuzzyMatchLabel: boolean = true, onClose: (canceled: boolean) => void = () => { }): QuickOpenOptions {
return QuickOpenOptions.resolve({
placeholder,
Expand All @@ -108,6 +141,7 @@ export class GenerateCodeCommandContribution implements CommandContribution {
onClose
});
}

}

export class WorkspaceRootUriAwareCommandHandler extends UriAwareCommandHandler<URI> {
Expand Down Expand Up @@ -141,3 +175,28 @@ export class WorkspaceRootUriAwareCommandHandler extends UriAwareCommandHandler<
return undefined;
}
}

class SingleStringInputOpenItem extends QuickOpenItem {

constructor(
private readonly label: string,
private readonly execute: (item: QuickOpenItem) => void = () => { },
private readonly canRun: (mode: QuickOpenMode) => boolean = mode => mode === QuickOpenMode.OPEN,
private readonly canClose: (mode: QuickOpenMode) => boolean = mode => true) {

super();
}

getLabel(): string {
return this.label;
}

run(mode: QuickOpenMode): boolean {
if (!this.canRun(mode)) {
return false;
}
this.execute(this);
return this.canClose(mode);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
import { FrontendApplication, OpenerService, QuickOpenOptions, QuickOpenService } from "@theia/core/lib/browser";

import {
open
} from "@theia/core/lib/browser";
import { FrontendApplication, OpenerService, QuickOpenService } from "@theia/core/lib/browser";
import { Command, CommandContribution, CommandRegistry } from "@theia/core/lib/common/command";
import { MessageService } from "@theia/core/lib/common/message-service";
import { ProgressService } from "@theia/core/lib/common/progress-service";
Expand All @@ -30,12 +34,9 @@ import { inject, injectable } from "inversify";
import { FileGenServer } from "../common/generate-protocol";



export const EXAMPLE_NAVIGATOR = [...NAVIGATOR_CONTEXT_MENU, 'example'];
export const EXAMPLE_EDITOR = [...EDITOR_CONTEXT_MENU, 'example'];



export const GENERATE_GENMODEL: Command = {
id: 'file.generateGenModel',
category: 'File',
Expand All @@ -55,17 +56,18 @@ export class GenerateGenModelCommandContribution implements CommandContribution
@inject(ProgressService) protected readonly progressService: ProgressService;
@inject(QuickOpenService) protected readonly quickOpenService: QuickOpenService;
@inject(FileGenServer) private readonly fileGenServer: FileGenServer;

registerCommands(registry: CommandRegistry): void {
registry.registerCommand(GENERATE_GENMODEL, this.newWorkspaceRootUriAwareCommandHandler({
execute: uri => this.getDirectory(uri).then(parent => {
if (parent) {
const parentUri = new URI(parent.uri);
// @Leo hier wird die Methode zum generieren aufgerufen.
// Die Variable uri ist das aktuell markierte Element
// und parentUri ist dann dementsprechend der Ordner darüber(wrsl der Workspace)
this.fileGenServer.generateGenModel().then(() => {
// @Leo hier kannst du die files nachdem sie generiert wurden öffnen

this.fileGenServer.generateGenModel(uri.path.toString()).then(() => {
const extensionStart = uri.displayName.lastIndexOf('.');
const genmodelPath = parentUri.toString() + '/' + uri.displayName.substring(0, extensionStart) + '.genmodel';
const fileUri = new URI(genmodelPath);
open(this.openerService, fileUri);
});
}
})
Expand Down Expand Up @@ -99,15 +101,6 @@ export class GenerateGenModelCommandContribution implements CommandContribution
protected getParent(candidate: URI): Promise<FileStat | undefined> {
return this.fileSystem.getFileStat(candidate.parent.toString());
}

private getOptions(placeholder: string, fuzzyMatchLabel: boolean = true, onClose: (canceled: boolean) => void = () => { }): QuickOpenOptions {
return QuickOpenOptions.resolve({
placeholder,
fuzzyMatchLabel,
fuzzySort: false,
onClose
});
}
}

export class WorkspaceRootUriAwareCommandHandler extends UriAwareCommandHandler<URI> {
Expand Down
5 changes: 2 additions & 3 deletions client/theia-ecore/src/common/generate-protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ export const FILEGEN_SERVICE_PATH = '/services/codegen';

export interface FileGenServer extends JsonRpcServer<undefined> {
generateEcore(name: string, prefix: string, uri: string, path: string): Promise<string>
// @Leo hier ist das Interface. Parameter müssen hier wahrscheinlich noch angepasst werden.
generateCode(): Promise<String>
generateGenModel(): Promise<String>
generateCode(genmodelPath: string, outputFolder: string, ecoreName: string): Promise<String>
generateGenModel(ecorePath: string): Promise<String>
createNewProject(): Promise<String>
}
75 changes: 69 additions & 6 deletions client/theia-ecore/src/node/ecore-file-generation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,76 @@ export class EcoreFileGenServer implements FileGenServer, BackendApplicationCont
});
}

generateCode(): Promise<String> {
// @Leo hier wird die Methode dann implementiert. Wie du ne Jar findest und aufrufst ist ein
// Beispiel in der Methode drüber. Die Jars sollen in theia-ecore/server liegen.
throw new Error("Method not implemented.");
generateCode(genmodelPath: string, outputFolder: string, ecoreName: string): Promise<String> {
const jarPath = path.resolve(__dirname, '..', '..',
'server', 'eclipse', 'plugins', 'org.eclipse.equinox.launcher_1.5.500.v20190715-1310.jar');
if (jarPath.length === 0) {
throw new Error('The eclipse.equinox.launcher is not found. ');
}

const command = 'java';
const args: string[] = [];

args.push(
'-jar', jarPath,
'-application', 'org.eclipse.emf.codegen.ecore.Generator',
'-data', outputFolder,
'-nosplash', genmodelPath,
outputFolder + '/' + ecoreName + '/code'
);

return new Promise(resolve => {
const process = this.spawnProcess(command, args);
if (process === undefined || process.process === undefined || process === null || process.process === null) {
resolve('Process not spawned');
return;
}

process.process.on('exit', (code: any) => {
switch (code) {
case 0: resolve('OK'); break;
default: resolve('UNKNOWN ERROR ' + code); break;
}
});
});
}

generateGenModel(): Promise<String> {
throw new Error("Method not implemented.");
generateGenModel(ecorePath: string): Promise<String> {
const jarPath = path.resolve(__dirname, '..', '..',
'server', 'ecore2GenModel.jar');
if (jarPath.length === 0) {
throw new Error('The EcoreGeneration.jar is not found. ');
}

const laucherPath = path.resolve(__dirname, '..', '..',
'server', 'eclipse', 'plugins', 'org.eclipse.equinox.launcher_1.5.500.v20190715-1310.jar');
if (laucherPath.length === 0) {
throw new Error('The eclipse.equinox.launcher is not found. ');
}

const command = 'java';
const args: string[] = [];

args.push(
'-jar', jarPath,
'-ecore', ecorePath,
'-launcher', laucherPath
);

return new Promise(resolve => {
const process = this.spawnProcess(command, args);
if (process === undefined || process.process === undefined || process === null || process.process === null) {
resolve('Process not spawned');
return;
}

process.process.on('exit', (code: any) => {
switch (code) {
case 0: resolve('OK'); break;
default: resolve('UNKNOWN ERROR ' + code); break;
}
});
});
}

createNewProject(): Promise<String> {
Expand All @@ -104,6 +166,7 @@ export class EcoreFileGenServer implements FileGenServer, BackendApplicationCont
private spawnProcess(command: string, args?: string[]): RawProcess | undefined {
const rawProcess = this.processFactory({ command, args });
if (rawProcess.process === undefined) {
this.logError("Error creating process");
return undefined;
}
rawProcess.process.on('error', this.onDidFailSpawnProcess.bind(this));
Expand Down

0 comments on commit 4c187ab

Please sign in to comment.