• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2* Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3* Licensed under the Apache License, Version 2.0 (the "License");
4* you may not use this file except in compliance with the License.
5* You may obtain a copy of the License at
6*
7* http://www.apache.org/licenses/LICENSE-2.0
8*
9* Unless required by applicable law or agreed to in writing, software
10* distributed under the License is distributed on an "AS IS" BASIS,
11* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12* See the License for the specific language governing permissions and
13* limitations under the License.
14*/
15
16// The module 'vscode' contains the VS Code extensibility API
17// Import the module and reference it with the alias vscode in your code below
18const vscode = require('vscode');
19const fs = require('fs');
20const re = require("./gen/tools/VsPluginRe");
21const { VsPluginLog } = require("./gen/tools/VsPluginLog");
22const { detectPlatform, readFile } = require('./gen/tools/VsPluginTool');
23const path = require('path');
24var exeFilePath = null;
25var globalPanel = null;
26
27var importToolChain = false;
28var extensionIds = [];
29var nextPluginId = null;
30// this method is called when your extension is activated
31// your extension is activated the very first time the command is executed
32
33/**
34 * @param {vscode.ExtensionContext} context
35 */
36function activate(context) {
37	// Use the console to output diagnostic information (console.log) and errors (console.error)
38	// This line of code will only be executed once when your extension is activated
39	console.log('Congratulations, your extension "ts-gen" is now active!');
40	let disposable = register(context, 'generate_ts');
41	let disposableMenu = register(context, 'generate_ts_menu');
42	context.subscriptions.push(disposable);
43	context.subscriptions.push(disposableMenu);
44
45	var platform = detectPlatform();
46	if (platform == 'win') {
47		exeFilePath = __dirname + "/napi_generator-win.exe";
48	} else if (platform == 'mac') {
49		exeFilePath = __dirname + "/napi_generator-macos";
50	} else if (platform == 'Linux') {
51		exeFilePath = __dirname + "/napi_generator-linux";
52	}
53}
54
55function executorH2Ts(name, genDir) {
56	var command = exeFilePath + " -f " + name + " -o " + genDir + " -t true";
57	var exec = require('child_process').exec;
58	exec(command, function (error, stdout, stderr) {
59		VsPluginLog.logInfo('VsPlugin: stdout =' + stdout + ", stderr =" + stderr);
60		if (error || stdout.indexOf("success") < 0) {
61			vscode.window.showErrorMessage("genError:" + (error != null ? error : "") + stdout);
62			return VsPluginLog.logError("VsPlugin:" + error + stdout);
63		}
64		vscode.window.showInformationMessage("Generated successfully");
65	});
66}
67
68function exeFileExit() {
69	if (fs.existsSync(exeFilePath)) {
70		return true;
71	}
72	return false;
73}
74
75function register(context, command) {
76	let disposable = vscode.commands.registerCommand(command, function (uri, boolValue, items) {
77		// The code you place here will be executed every time your command is executed
78		// Display a message box to the user
79		globalPanel = vscode.window.createWebviewPanel(
80			'generate', // Identifies the type of WebView
81			'Generate Ts Frame', // Title of the panel displayed to the user
82			vscode.ViewColumn.Two, // Display the WebView panel in the form of new columns in the editor
83			{
84				enableScripts: true, // Enable or disable JS, default is Enable
85				retainContextWhenHidden: true, // Keep the WebView state when it is hidden to avoid being reset
86			}
87		);
88		if (typeof(boolValue) == 'boolean' && Array.isArray(items)) {
89			if (boolValue == true) {
90				//遍历数组item,查看当前插件id是数组的第几个元素,并拿出下一个元素,并判断当前id是否是最后一个元素并做相应处理
91				let myExtensionId = 'kaihong.ts-gen';
92				for (let i = 0; i < items.length; i++) {
93					if (myExtensionId == items[i] && (i == items.length - 1)) {
94						importToolChain = false;
95					} else if (myExtensionId == items[i] && (i != items.length - 1)) {
96						importToolChain = boolValue;
97						nextPluginId = items[i + 1];
98					}
99					extensionIds.push(items[i]);
100				}
101			}
102		}
103		globalPanel.webview.html = getWebviewContent(context, importToolChain);
104		let msg;
105		globalPanel.webview.onDidReceiveMessage(message => {
106			msg = message.msg;
107			if (msg == "cancel") {
108				globalPanel.dispose();
109			}
110			else if(msg == "h2ts") {
111				checkReceiveMsg(message);
112			}else {
113				selectPath(globalPanel, message);
114			}
115		}, undefined, context.subscriptions);
116		let fn = re.getFileInPath(uri.fsPath);
117		let tt = re.match("([a-zA-Z_0-9]+.h)", fn);
118		var result = {
119			msg: "selectHFilePath",
120			path: tt ? uri.fsPath : ""
121			}
122	    globalPanel.webview.postMessage(result);
123	});
124	return disposable;
125}
126
127function checkReceiveMsg(message) {
128	let name = message.fileNames;
129	let genDir = message.genDir;
130	let buttonName = message.buttonName;
131	name = re.replaceAll(name, " ", "");
132	if ("" == name) {
133		vscode.window.showErrorMessage("Please enter the path!");
134		return;
135	}
136	if (exeFileExit()) {
137		executorH2Ts(name, genDir);
138		if (buttonName == 'Next') {
139			startNextPlugin();
140		}
141	} else {
142		vscode.window.showInformationMessage("Copy executable program to " + __dirname);
143	}
144}
145
146/**
147* 获取插件执行命令
148*/
149function nextPluginExeCommand(nextPluginId) {
150    if (nextPluginId == "kaihong.ApiScan") {
151		return 'api_scan';
152	} else if (nextPluginId == "kaihong.gn-gen") {
153		return 'generate_gn';
154	} else if (nextPluginId == "kaihong.service-gen") {
155		return 'generate_service';
156	} else if (nextPluginId == "kaihong.ts-gen") {
157		return 'generate_ts';
158	} else if (nextPluginId == "kaihong.napi-gen") {
159		return 'generate_napi';
160	} else {
161		return null;
162	}
163}
164
165/**
166* 执行完毕后开启工具链中下一个插件
167*/
168function startNextPlugin() {
169	const extension = vscode.extensions.getExtension(nextPluginId);
170	if (extension) {
171		let startNextPlugin = nextPluginExeCommand(nextPluginId);
172		try {
173			vscode.commands.executeCommand(startNextPlugin, '', importToolChain, extensionIds);
174		} catch (error) {
175			console.error(error);
176		}
177	}
178}
179
180/**
181* 选择本地目录/文件夹
182*/
183 function selectPath(panel, message) {
184	let mode = 1;
185	if (message.mode != undefined) {
186		mode = message.mode;
187	}
188	const options = {
189		canSelectMany: mode == 0 ? true : false,//是否可以选择多个
190		openLabel: mode == 0 ? '选择文件' : '选择文件夹',//打开选择的右下角按钮label
191		canSelectFiles: mode == 0 ? true : false,//是否选择文件
192		canSelectFolders: mode == 0 ? false : true,//是否选择文件夹
193		defaultUri:vscode.Uri.file(''),//默认打开本地路径
194		filters: mode == 1 ? {} : { // 文件过滤选项,在文件夹选择模式下不可设置此配置,否则ubuntu系统下无法选择文件夹
195			'Text files': ['h']
196		}
197	};
198
199	return vscode.window.showOpenDialog(options).then(fileUri => {
200	   if (fileUri && fileUri[0]) {
201		   console.log('Selected file: ' + fileUri[0].fsPath);
202		   let filePath = "";
203		   for (let index = 0; index < fileUri.length; index++) {
204				filePath += fileUri[index].fsPath.concat(",");
205		   }
206		   var result = {
207				msg: message.msg,
208				path: filePath.length > 0 ? filePath.substring(0, filePath.length - 1) : filePath
209				}
210		   panel.webview.postMessage(result);
211		   return fileUri[0].fsPath
212	   }
213   });
214}
215
216// this method is called when your extension is deactivated
217function deactivate() { }
218
219function getWebviewContent(context, importToolChain) {
220	let data = readFile(__dirname + '/vs_plugin_view.html');
221	data = getWebViewContent(context, '/vs_plugin_view.html');
222	let content = data.toString();
223	if (importToolChain) {
224		content = content.replace('Ok', 'Next');
225	}
226	return content;
227}
228
229function getWebViewContent(context, templatePath) {
230    const resourcePath = path.join(context.extensionPath, templatePath);
231    const dirPath = path.dirname(resourcePath);
232    let html = fs.readFileSync(resourcePath, 'utf-8');
233    html = html.replace(/(<link.+?href="|<script.+?src="|<iframe.+?src="|<img.+?src=")(.+?)"/g, (m, $1, $2) => {
234        if ($2.indexOf("https://") < 0) {
235            return $1 + globalPanel.webview.asWebviewUri(vscode.Uri.file(path.resolve(dirPath, $2))) + '"';
236        } else {
237            return $1 + $2+'"';
238        }
239    });
240    return html;
241}
242
243module.exports = {
244	activate,
245	deactivate
246}