diff --git a/.gitignore b/.gitignore index ab75a6c8..20cd4cfc 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,11 @@ spring-javaformat/spring-javaformat-formatter-eclipse-rewriter/bin build.log pid .factorypath + +# npm +node_modules/ + +# vscode +spring-javaformat-vscode/spring-javaformat/out/ +spring-javaformat-vscode/spring-javaformat/runtime/ +*.vsix diff --git a/README.adoc b/README.adoc index 5ffd15a1..bce16e52 100644 --- a/README.adoc +++ b/README.adoc @@ -263,6 +263,9 @@ Once the configuration file is created, configure your IDE to use it: * Specify the appropriate `Checkstyle version` * Add your Checkstyle configuration file +=== Visual Studio Code +The vscode extension provides custom formatter support for Visual Studio Code. +The extension is automatically activated whenever a `.java` file is opened. And it requires a few seconds to warm-up while you start with the first workspace. === About the Conventions diff --git a/spring-javaformat-vscode/README.md b/spring-javaformat-vscode/README.md new file mode 100644 index 00000000..e6dea6c9 --- /dev/null +++ b/spring-javaformat-vscode/README.md @@ -0,0 +1,19 @@ +# spring-javaformat-vscode + +`spring-javaformat` extension for visual studio code. + +![](./format.gif) + +## Prerequisites + +* Install [node.js](https://nodejs.org/en/download/) +* Install [yarn](https://yarnpkg.com/en/docs/install) +* Install [vsce](https://code.visualstudio.com/api/working-with-extensions/publishing-extension#vsce) + +## Generate extension + +Just `mvn clean package` + + +> `spring-javaformat-1.0.0.vsix` will be generated there + diff --git a/spring-javaformat-vscode/format.gif b/spring-javaformat-vscode/format.gif new file mode 100644 index 00000000..fd1fdacd Binary files /dev/null and b/spring-javaformat-vscode/format.gif differ diff --git a/spring-javaformat-vscode/pom.xml b/spring-javaformat-vscode/pom.xml new file mode 100644 index 00000000..0ffbcbae --- /dev/null +++ b/spring-javaformat-vscode/pom.xml @@ -0,0 +1,22 @@ + + + 4.0.0 + + io.spring.javaformat + spring-javaformat-build + 0.0.16-SNAPSHOT + + spring-javaformat-vscode + pom + Spring JavaFormat Visual Studio Code + + ${basedir}/.. + + + + spring-javaformat-format-service + + + diff --git a/spring-javaformat-vscode/spring-javaformat-format-service/.vscode/launch.json b/spring-javaformat-vscode/spring-javaformat-format-service/.vscode/launch.json new file mode 100644 index 00000000..40ef0758 --- /dev/null +++ b/spring-javaformat-vscode/spring-javaformat-format-service/.vscode/launch.json @@ -0,0 +1,11 @@ +{ + "configurations": [ + { + "type": "java", + "name": "CodeLens (Launch) - FormatterWebApplication", + "request": "launch", + "mainClass": "io.spring.format.FormatterWebApplication", + "projectName": "spring-javaformat-format-service" + } + ] +} \ No newline at end of file diff --git a/spring-javaformat-vscode/spring-javaformat-format-service/.vscode/settings.json b/spring-javaformat-vscode/spring-javaformat-format-service/.vscode/settings.json new file mode 100644 index 00000000..0e0c2a50 --- /dev/null +++ b/spring-javaformat-vscode/spring-javaformat-format-service/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "editor.formatOnSave": true, + "java.format.enabled": false +} diff --git a/spring-javaformat-vscode/spring-javaformat-format-service/pom.xml b/spring-javaformat-vscode/spring-javaformat-format-service/pom.xml new file mode 100644 index 00000000..8b09b585 --- /dev/null +++ b/spring-javaformat-vscode/spring-javaformat-format-service/pom.xml @@ -0,0 +1,129 @@ + + + 4.0.0 + + io.spring.javaformat + spring-javaformat-vscode + 0.0.16-SNAPSHOT + + spring-javaformat-format-service + jar + Spring JavaFormat format-service + + ${basedir}/../.. + + + + + + + org.springframework.boot + spring-boot-maven-plugin + 2.1.8.RELEASE + + ${main.basedir}/spring-javaformat-vscode/spring-javaformat/runtime/ + + + + + repackage + + + + + + + org.codehaus.mojo + exec-maven-plugin + + ${main.basedir}/spring-javaformat-vscode/spring-javaformat + + + + exec-yarn-install + compile + + yarn + + + exec + + + + exec-package + package + + vsce + + package + + + + exec + + + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + + + checkstyle-validation + validate + + **/*/FormatterWebApplication.java + + + + + + + io.spring.javaformat + spring-javaformat-maven-plugin + 0.0.16-SNAPSHOT + + + + + + + + + org.springframework.boot + spring-boot-dependencies + 2.1.6.RELEASE + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter + 2.1.6.RELEASE + + + org.springframework.boot + spring-boot-starter-web + 2.1.6.RELEASE + + + io.spring.javaformat + spring-javaformat-formatter + ${project.version} + + + + io.spring.javaformat + spring-javaformat-formatter-eclipse-runtime + ${project.version} + provided + + + diff --git a/spring-javaformat-vscode/spring-javaformat-format-service/src/main/java/io/spring/format/FormatterWebApplication.java b/spring-javaformat-vscode/spring-javaformat-format-service/src/main/java/io/spring/format/FormatterWebApplication.java new file mode 100644 index 00000000..58f9980f --- /dev/null +++ b/spring-javaformat-vscode/spring-javaformat-format-service/src/main/java/io/spring/format/FormatterWebApplication.java @@ -0,0 +1,35 @@ +/* + * Copyright 2017-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.spring.format; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.scheduling.annotation.EnableScheduling; + +@EnableScheduling +@SpringBootApplication +public class FormatterWebApplication { + + public FormatterWebApplication() { + + } + + public static void main(String[] args) { + SpringApplication.run(FormatterWebApplication.class, args); + } + +} diff --git a/spring-javaformat-vscode/spring-javaformat-format-service/src/main/java/io/spring/format/controllers/FormatController.java b/spring-javaformat-vscode/spring-javaformat-format-service/src/main/java/io/spring/format/controllers/FormatController.java new file mode 100644 index 00000000..2ea27463 --- /dev/null +++ b/spring-javaformat-vscode/spring-javaformat-format-service/src/main/java/io/spring/format/controllers/FormatController.java @@ -0,0 +1,42 @@ +/* + * Copyright 2017-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.spring.format.controllers; + +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +import io.spring.format.request.FormatRequest; +import io.spring.format.tools.FormatContent; + +/** + * . + * + * @author Howard Zuo + */ +@RestController +public class FormatController { + + @RequestMapping(method = RequestMethod.POST, value = "/format/code") + String formatSource(@RequestBody FormatRequest req) { + + return FormatContent.formatContent(req.getSource()); + + } + +} diff --git a/spring-javaformat-vscode/spring-javaformat-format-service/src/main/java/io/spring/format/controllers/HealthController.java b/spring-javaformat-vscode/spring-javaformat-format-service/src/main/java/io/spring/format/controllers/HealthController.java new file mode 100644 index 00000000..43ccceda --- /dev/null +++ b/spring-javaformat-vscode/spring-javaformat-format-service/src/main/java/io/spring/format/controllers/HealthController.java @@ -0,0 +1,43 @@ +/* + * Copyright 2017-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.spring.format.controllers; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +import io.spring.format.services.HealthService; + +/** + * . + * + * @author Howard Zuo + */ +@RestController +public class HealthController { + + @Autowired + private HealthService service; + + @RequestMapping(method = RequestMethod.GET, value = "/health") + String heartbeat() { + this.service.setLastHeartbeat(System.currentTimeMillis()); + return ""; + } + +} diff --git a/spring-javaformat-vscode/spring-javaformat-format-service/src/main/java/io/spring/format/request/FormatRequest.java b/spring-javaformat-vscode/spring-javaformat-format-service/src/main/java/io/spring/format/request/FormatRequest.java new file mode 100644 index 00000000..d74555f9 --- /dev/null +++ b/spring-javaformat-vscode/spring-javaformat-format-service/src/main/java/io/spring/format/request/FormatRequest.java @@ -0,0 +1,36 @@ +/* + * Copyright 2017-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.spring.format.request; + +/** + * . + * + * @author Howard Zuo + */ +public class FormatRequest { + + private String source = ""; + + public void setSource(String source) { + this.source = source; + } + + public String getSource() { + return this.source; + } + +} diff --git a/spring-javaformat-vscode/spring-javaformat-format-service/src/main/java/io/spring/format/services/HealthService.java b/spring-javaformat-vscode/spring-javaformat-format-service/src/main/java/io/spring/format/services/HealthService.java new file mode 100644 index 00000000..574652a8 --- /dev/null +++ b/spring-javaformat-vscode/spring-javaformat-format-service/src/main/java/io/spring/format/services/HealthService.java @@ -0,0 +1,50 @@ +/* + * Copyright 2017-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.spring.format.services; + +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; + +/** + * . + * + * @author Howard Zuo + */ +@Service +public class HealthService { + + private Long lastHeartbeat; + + public Long getLastHeartbeat() { + return this.lastHeartbeat; + } + + public void setLastHeartbeat(Long lastHeartbeat) { + this.lastHeartbeat = lastHeartbeat; + } + + @Scheduled(fixedRate = 1000 * 60 * 5) + public void liveCheck() { + if (this.lastHeartbeat == null) { + return; + } + if ((System.currentTimeMillis() - this.lastHeartbeat) > (1000 * 60 * 5)) { + System.exit(0); + } + } + +} diff --git a/spring-javaformat-vscode/spring-javaformat-format-service/src/main/java/io/spring/format/tools/FormatContent.java b/spring-javaformat-vscode/spring-javaformat-format-service/src/main/java/io/spring/format/tools/FormatContent.java new file mode 100644 index 00000000..4079c720 --- /dev/null +++ b/spring-javaformat-vscode/spring-javaformat-format-service/src/main/java/io/spring/format/tools/FormatContent.java @@ -0,0 +1,62 @@ +/* + * Copyright 2017-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.spring.format.tools; + +import java.util.regex.Pattern; + +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.IDocument; +import org.eclipse.text.edits.TextEdit; + +import io.spring.javaformat.formatter.Formatter; + +/** + * . Format specified java content + * + * @author Howard Zuo + */ +final public class FormatContent { + + private static final Pattern TRAILING_WHITESPACE = Pattern.compile(" +$", Pattern.MULTILINE); + + private FormatContent() { + + } + + public static String formatContent(String source) { + if (source == null || "".equals(source)) { + return ""; + } + + try { + final Formatter formatter = new Formatter(); + TextEdit textEdit = formatter.format(source); + IDocument document = new Document(source); + textEdit.apply(document); + String formattedContent = document.get(); + return trimTrailingWhitespace(formattedContent); + } + catch (Exception e) { + return source; + } + } + + private static String trimTrailingWhitespace(String content) { + return TRAILING_WHITESPACE.matcher(content).replaceAll(""); + } + +} diff --git a/spring-javaformat-vscode/spring-javaformat-format-service/src/main/resources/config/application.yaml b/spring-javaformat-vscode/spring-javaformat-format-service/src/main/resources/config/application.yaml new file mode 100644 index 00000000..8a9d523c --- /dev/null +++ b/spring-javaformat-vscode/spring-javaformat-format-service/src/main/resources/config/application.yaml @@ -0,0 +1,5 @@ +# 基础应用配置 +spring: + application.name: Spring-Java-Formatter-Web +server: + port: ${port:9987} diff --git a/spring-javaformat-vscode/spring-javaformat/.prettierrc b/spring-javaformat-vscode/spring-javaformat/.prettierrc new file mode 100644 index 00000000..133b8992 --- /dev/null +++ b/spring-javaformat-vscode/spring-javaformat/.prettierrc @@ -0,0 +1,6 @@ +{ + "tabWidth": 2, + "semi": false, + "singleQuote": true, + "printWidth": 110 +} diff --git a/spring-javaformat-vscode/spring-javaformat/.vscode/extensions.json b/spring-javaformat-vscode/spring-javaformat/.vscode/extensions.json new file mode 100644 index 00000000..0a18b9c4 --- /dev/null +++ b/spring-javaformat-vscode/spring-javaformat/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "ms-vscode.vscode-typescript-tslint-plugin" + ] +} \ No newline at end of file diff --git a/spring-javaformat-vscode/spring-javaformat/.vscode/launch.json b/spring-javaformat-vscode/spring-javaformat/.vscode/launch.json new file mode 100644 index 00000000..f5197783 --- /dev/null +++ b/spring-javaformat-vscode/spring-javaformat/.vscode/launch.json @@ -0,0 +1,36 @@ +// A launch configuration that compiles the extension and then opens it inside a new window +// Use IntelliSense to learn about possible attributes. +// Hover to view descriptions of existing attributes. +// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Run Extension", + "type": "extensionHost", + "request": "launch", + "runtimeExecutable": "${execPath}", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder}" + ], + "outFiles": [ + "${workspaceFolder}/out/**/*.js" + ], + "preLaunchTask": "npm: watch" + }, + { + "name": "Extension Tests", + "type": "extensionHost", + "request": "launch", + "runtimeExecutable": "${execPath}", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder}", + "--extensionTestsPath=${workspaceFolder}/out/test/suite/index" + ], + "outFiles": [ + "${workspaceFolder}/out/test/**/*.js" + ], + "preLaunchTask": "npm: watch" + } + ] +} diff --git a/spring-javaformat-vscode/spring-javaformat/.vscode/settings.json b/spring-javaformat-vscode/spring-javaformat/.vscode/settings.json new file mode 100644 index 00000000..baa30361 --- /dev/null +++ b/spring-javaformat-vscode/spring-javaformat/.vscode/settings.json @@ -0,0 +1,15 @@ +// Place your settings in this file to overwrite default and user settings. +{ + "files.exclude": { + "out": false // set this to true to hide the "out" folder with the compiled JS files + }, + "search.exclude": { + "out": true // set this to false to include "out" folder in search results + }, + // Turn off tsc task auto detection since we have the necessary tasks as npm scripts + "typescript.tsc.autoDetect": "off", + "[typescript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "editor.formatOnSave": true +} \ No newline at end of file diff --git a/spring-javaformat-vscode/spring-javaformat/.vscode/tasks.json b/spring-javaformat-vscode/spring-javaformat/.vscode/tasks.json new file mode 100644 index 00000000..3b17e53b --- /dev/null +++ b/spring-javaformat-vscode/spring-javaformat/.vscode/tasks.json @@ -0,0 +1,20 @@ +// See https://go.microsoft.com/fwlink/?LinkId=733558 +// for the documentation about the tasks.json format +{ + "version": "2.0.0", + "tasks": [ + { + "type": "npm", + "script": "watch", + "problemMatcher": "$tsc-watch", + "isBackground": true, + "presentation": { + "reveal": "never" + }, + "group": { + "kind": "build", + "isDefault": true + } + } + ] +} diff --git a/spring-javaformat-vscode/spring-javaformat/.vscodeignore b/spring-javaformat-vscode/spring-javaformat/.vscodeignore new file mode 100644 index 00000000..ed3f9d37 --- /dev/null +++ b/spring-javaformat-vscode/spring-javaformat/.vscodeignore @@ -0,0 +1,10 @@ +.vscode/** +.vscode-test/** +out/test/** +src/** +.gitignore +vsc-extension-quickstart.md +**/tsconfig.json +**/tslint.json +**/*.map +**/*.ts \ No newline at end of file diff --git a/spring-javaformat-vscode/spring-javaformat/README.md b/spring-javaformat-vscode/spring-javaformat/README.md new file mode 100644 index 00000000..5f38bf4f --- /dev/null +++ b/spring-javaformat-vscode/spring-javaformat/README.md @@ -0,0 +1,6 @@ +# spring-javaformat + +> Format .java files in spring-javaformat way + + + diff --git a/spring-javaformat-vscode/spring-javaformat/package.json b/spring-javaformat-vscode/spring-javaformat/package.json new file mode 100644 index 00000000..0cc76709 --- /dev/null +++ b/spring-javaformat-vscode/spring-javaformat/package.json @@ -0,0 +1,42 @@ +{ + "name": "spring-javaformat", + "displayName": "spring-javaformat-vscode-extension", + "description": "Format .java files in spring-javaformat way", + "version": "1.0.0", + "publisher": "howardzuo", + "engines": { + "vscode": "^1.36.0" + }, + "repository": { + "type": "git", + "url": "https://github.com/spring-io/spring-javaformat.git" + }, + "scripts": { + "vscode:prepublish": "yarn run compile", + "compile": "tsc -p ./", + "watch": "tsc -watch -p ./" + }, + "categories": [ + "Formatters" + ], + "activationEvents": [ + "onLanguage:java", + "onLanguage:markdown" + ], + "main": "./out/extension.js", + "devDependencies": { + "@types/glob": "^7.1.1", + "@types/markdown-it": "^0.0.8", + "@types/node": "^10.12.21", + "@types/vscode": "^1.36.0", + "glob": "^7.1.4", + "tslint": "^5.18.0", + "typescript": "^3.5.3" + }, + "dependencies": { + "axios": "^0.19.0", + "markdown-it": "^10.0.0", + "portfinder": "^1.0.21", + "ps-list": "^6.3.0" + } +} diff --git a/spring-javaformat-vscode/spring-javaformat/src/SpringJavaFormatter.ts b/spring-javaformat-vscode/spring-javaformat/src/SpringJavaFormatter.ts new file mode 100644 index 00000000..d382b919 --- /dev/null +++ b/spring-javaformat-vscode/spring-javaformat/src/SpringJavaFormatter.ts @@ -0,0 +1,28 @@ +import { + DocumentFormattingEditProvider, + TextDocument, + FormattingOptions, + CancellationToken, + ProviderResult, + TextEdit, + Range +} from 'vscode' + +import { formatMarkdown } from './formatters/MarkdownFormatter' +import { formatJava } from './formatters/JavaFormatter' + +export default class SpringJavaFormatter implements DocumentFormattingEditProvider { + provideDocumentFormattingEdits( + document: TextDocument, + options: FormattingOptions, + token: CancellationToken + ): ProviderResult { + if (document.languageId === 'java') { + return formatJava(document) + } + if (document.languageId === 'markdown') { + return formatMarkdown(document) + } + return [] + } +} diff --git a/spring-javaformat-vscode/spring-javaformat/src/extension.ts b/spring-javaformat-vscode/spring-javaformat/src/extension.ts new file mode 100644 index 00000000..6b848bd1 --- /dev/null +++ b/spring-javaformat-vscode/spring-javaformat/src/extension.ts @@ -0,0 +1,31 @@ +// The module 'vscode' contains the VS Code extensibility API +// Import the module and reference it with the alias vscode in your code below +import * as vscode from 'vscode' +import SpringJavaFormatter from './SpringJavaFormatter' + +// this method is called when your extension is activated +// your extension is activated the very first time the command is executed +export function activate(context: vscode.ExtensionContext) { + // Use the console to output diagnostic information (console.log) and errors (console.error) + // This line of code will only be executed once when your extension is activated + console.log('Congratulations, your extension "spring-javaformat" is now active!') + + context.subscriptions.push( + vscode.languages.registerDocumentFormattingEditProvider( + [ + { + language: 'java', + scheme: 'file' + }, + { + language: 'markdown', + scheme: 'file' + } + ], + new SpringJavaFormatter() + ) + ) +} + +// this method is called when your extension is deactivated +export function deactivate() {} diff --git a/spring-javaformat-vscode/spring-javaformat/src/formatters/JavaFormatter.ts b/spring-javaformat-vscode/spring-javaformat/src/formatters/JavaFormatter.ts new file mode 100644 index 00000000..e66942c6 --- /dev/null +++ b/spring-javaformat-vscode/spring-javaformat/src/formatters/JavaFormatter.ts @@ -0,0 +1,10 @@ +import { TextDocument, Range, TextEdit } from 'vscode' + +import FormatService from '../services/FormatService' + +export async function formatJava(document: TextDocument): Promise> { + const code = await FormatService.getInstance().formatCode(document.getText()) + + const range = new Range(document.positionAt(0), document.positionAt(document.getText().length)) + return [TextEdit.replace(range, code)] +} diff --git a/spring-javaformat-vscode/spring-javaformat/src/formatters/MarkdownFormatter.ts b/spring-javaformat-vscode/spring-javaformat/src/formatters/MarkdownFormatter.ts new file mode 100644 index 00000000..e8c334f7 --- /dev/null +++ b/spring-javaformat-vscode/spring-javaformat/src/formatters/MarkdownFormatter.ts @@ -0,0 +1,28 @@ +import { TextDocument, Range, TextEdit } from 'vscode' + +import FormatService from '../services/FormatService' +import MarkdownIt from 'markdown-it' +import Token from 'markdown-it/lib/token' + +const md = new MarkdownIt() + +export async function formatMarkdown(document: TextDocument): Promise> { + const source = document.getText() + const tokens = md.parse(source, {}) + + const editsPromise = tokens + .filter((t): t is Token => t.type === 'fence' && t.tag === 'code' && t.info === 'java') + .map(async token => { + const startIndex = source.indexOf(token.content) + const code = await FormatService.getInstance().formatCode(token.content) + + const range = new Range( + document.positionAt(startIndex), + document.positionAt(startIndex + token.content.length) + ) + + return TextEdit.replace(range, code) + }) + + return Promise.all(editsPromise) +} diff --git a/spring-javaformat-vscode/spring-javaformat/src/services/FormatService.ts b/spring-javaformat-vscode/spring-javaformat/src/services/FormatService.ts new file mode 100644 index 00000000..062ba02e --- /dev/null +++ b/spring-javaformat-vscode/spring-javaformat/src/services/FormatService.ts @@ -0,0 +1,103 @@ +import * as child_process from 'child_process' +import * as portfinder from 'portfinder' +import psList from 'ps-list' +import axios from 'axios' +import { resolve } from 'path' +import { window } from 'vscode' + +const JAR_NAME = 'spring-javaformat-format-service-0.0.16-SNAPSHOT.jar' + +const RUNTIME_JAR_PATH = resolve(__dirname, '..', '..', 'runtime', JAR_NAME) + +export default class FormatService { + private static instance: FormatService = new FormatService() + private port: number = 9987 + + constructor() { + const hideFunc = window.setStatusBarMessage('spring-javaformat service initializing....') + this.init() + .catch(err => { + console.error('ERROR:', err) + }) + .finally(() => { + hideFunc.dispose() + }) + } + + private async init() { + this.startNextScheduledJob() + const proc = await this.getJavaFormatServiceProcessInfo() + if (proc) { + const matched = (proc.cmd || '').match(/-Dport=([0-9]+)\s/) + if (matched) { + this.port = +matched[1] + } + console.log('spring-javaformat service is running with other workspace, no need run again') + return + } + const port = await this.findAvailablePort() + this.port = port + await this.run(port) + console.log('spring-javaformat service running') + } + + private startNextScheduledJob() { + setTimeout(async () => { + const proc = await this.getJavaFormatServiceProcessInfo() + if (!proc) { + const port = await this.findAvailablePort() + this.port = port + await this.run(port) + } + await this.sendHeartbeat() + + this.startNextScheduledJob() + }, 1000 * 60) + } + + private async getJavaFormatServiceProcessInfo() { + const list = await psList() + return list.find(l => (l.cmd || '').includes(JAR_NAME)) + } + + private async findAvailablePort() { + const port = await portfinder.getPortPromise({ + port: 20000, + stopPort: 60000 + }) + return port + } + + private async run(port: number) { + return new Promise((resolve, reject) => { + const childProcess = child_process.exec(`java -Dport=${port} -jar ${RUNTIME_JAR_PATH} `, {}) + + childProcess.stdout.on('data', data => { + if (data.includes('Started FormatterWebApplication')) { + resolve() + } + }) + + childProcess.on('error', reject) + }) + } + + async formatCode(source: string): Promise { + try { + const result = await axios.post(`http://localhost:${this.port}/format/code`, { + source + }) + return result.data + } catch (error) { + throw new Error('spring-javaformat service is not ready, please hold for few seconds') + } + } + + async sendHeartbeat() { + return axios.get(`http://localhost:${this.port}/health`) + } + + static getInstance(): FormatService { + return this.instance + } +} diff --git a/spring-javaformat-vscode/spring-javaformat/tsconfig.json b/spring-javaformat-vscode/spring-javaformat/tsconfig.json new file mode 100644 index 00000000..7efb850e --- /dev/null +++ b/spring-javaformat-vscode/spring-javaformat/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es6", + "outDir": "out", + "esModuleInterop": true, + "lib": ["es6"], + "sourceMap": true, + "rootDir": "src", + "strict": true /* enable all strict type-checking options */ + /* Additional Checks */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + }, + "exclude": ["node_modules", ".vscode-test"] +} diff --git a/spring-javaformat-vscode/spring-javaformat/tslint.json b/spring-javaformat-vscode/spring-javaformat/tslint.json new file mode 100644 index 00000000..8b382dcf --- /dev/null +++ b/spring-javaformat-vscode/spring-javaformat/tslint.json @@ -0,0 +1,15 @@ +{ + "rules": { + "no-string-throw": true, + "no-unused-expression": true, + "no-duplicate-variable": true, + "curly": true, + "class-name": true, + "semicolon": [ + true, + "never" + ], + "triple-equals": true + }, + "defaultSeverity": "warning" +} diff --git a/spring-javaformat-vscode/spring-javaformat/yarn.lock b/spring-javaformat-vscode/spring-javaformat/yarn.lock new file mode 100644 index 00000000..976bbb83 --- /dev/null +++ b/spring-javaformat-vscode/spring-javaformat/yarn.lock @@ -0,0 +1,388 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@^7.0.0": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d" + integrity sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw== + dependencies: + "@babel/highlight" "^7.0.0" + +"@babel/highlight@^7.0.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.5.0.tgz#56d11312bd9248fa619591d02472be6e8cb32540" + integrity sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ== + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^4.0.0" + +"@types/events@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" + integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== + +"@types/glob@^7.1.1": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" + integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w== + dependencies: + "@types/events" "*" + "@types/minimatch" "*" + "@types/node" "*" + +"@types/linkify-it@*": + version "2.1.0" + resolved "https://registry.npm.taobao.org/@types/linkify-it/download/@types/linkify-it-2.1.0.tgz#ea3dd64c4805597311790b61e872cbd1ed2cd806" + integrity sha1-6j3WTEgFWXMReQth6HLL0e0s2AY= + +"@types/markdown-it@^0.0.8": + version "0.0.8" + resolved "https://registry.npm.taobao.org/@types/markdown-it/download/@types/markdown-it-0.0.8.tgz#9af8704acde87fec70475369ba0413d50717bd8d" + integrity sha1-mvhwSs3of+xwR1NpugQT1QcXvY0= + dependencies: + "@types/linkify-it" "*" + +"@types/minimatch@*": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" + integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== + +"@types/node@*": + version "12.6.8" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.8.tgz#e469b4bf9d1c9832aee4907ba8a051494357c12c" + integrity sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg== + +"@types/node@^10.12.21": + version "10.14.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.13.tgz#ac786d623860adf39a3f51d629480aacd6a6eec7" + integrity sha512-yN/FNNW1UYsRR1wwAoyOwqvDuLDtVXnaJTZ898XIw/Q5cCaeVAlVwvsmXLX5PuiScBYwZsZU4JYSHB3TvfdwvQ== + +"@types/vscode@^1.36.0": + version "1.36.0" + resolved "https://registry.yarnpkg.com/@types/vscode/-/vscode-1.36.0.tgz#ae60242e893d9eda9a0d96d51ef56f1a3fae14ed" + integrity sha512-SbHR3Q5g/C3N+Ila3KrRf1rSZiyHxWdOZ7X3yFHXzw6HrvRLuVZrxnwEX0lTBMRpH9LkwZdqRTgXW+D075jxkg== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +async@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= + +axios@^0.19.0: + version "0.19.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.0.tgz#8e09bff3d9122e133f7b8101c8fbdd00ed3d2ab8" + integrity sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ== + dependencies: + follow-redirects "1.5.10" + is-buffer "^2.0.2" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +builtin-modules@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= + +chalk@^2.0.0, chalk@^2.3.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +commander@^2.12.1: + version "2.20.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" + integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +debug@=3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +debug@^2.2.0: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +diff@^3.2.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + +entities@~2.0.0: + version "2.0.0" + resolved "https://registry.npm.taobao.org/entities/download/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" + integrity sha1-aNYITKsbB5dnVA2A5Wo5tCPkq/Q= + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= + +follow-redirects@1.5.10: + version "1.5.10" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" + integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== + dependencies: + debug "=3.1.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +glob@^7.1.1, glob@^7.1.4: + version "7.1.4" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" + integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-buffer@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.3.tgz#4ecf3fcf749cbd1e472689e109ac66261a25e725" + integrity sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw== + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.13.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +linkify-it@^2.0.0: + version "2.2.0" + resolved "https://registry.npm.taobao.org/linkify-it/download/linkify-it-2.2.0.tgz#e3b54697e78bf915c70a38acd78fd09e0058b1cf" + integrity sha1-47VGl+eL+RXHCjis14/QngBYsc8= + dependencies: + uc.micro "^1.0.1" + +markdown-it@^10.0.0: + version "10.0.0" + resolved "https://registry.npm.taobao.org/markdown-it/download/markdown-it-10.0.0.tgz#abfc64f141b1722d663402044e43927f1f50a8dc" + integrity sha1-q/xk8UGxci1mNAIETkOSfx9QqNw= + dependencies: + argparse "^1.0.7" + entities "~2.0.0" + linkify-it "^2.0.0" + mdurl "^1.0.1" + uc.micro "^1.0.5" + +mdurl@^1.0.1: + version "1.0.1" + resolved "https://registry.npm.taobao.org/mdurl/download/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= + +mkdirp@0.5.x, mkdirp@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= + dependencies: + minimist "0.0.8" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +portfinder@^1.0.21: + version "1.0.21" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.21.tgz#60e1397b95ac170749db70034ece306b9a27e324" + integrity sha512-ESabpDCzmBS3ekHbmpAIiESq3udRsCBGiBZLsC+HgBKv2ezb0R4oG+7RnYEVZ/ZCfhel5Tx3UzdNWA0Lox2QCA== + dependencies: + async "^1.5.2" + debug "^2.2.0" + mkdirp "0.5.x" + +ps-list@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/ps-list/-/ps-list-6.3.0.tgz#a2b775c2db7d547a28fbaa3a05e4c281771259be" + integrity sha512-qau0czUSB0fzSlBOQt0bo+I2v6R+xiQdj78e1BR/Qjfl5OHWJ/urXi8+ilw1eHe+5hSeDI1wrwVTgDp2wst4oA== + +resolve@^1.3.2: + version "1.11.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.1.tgz#ea10d8110376982fef578df8fc30b9ac30a07a3e" + integrity sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw== + dependencies: + path-parse "^1.0.6" + +semver@^5.3.0: + version "5.7.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" + integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +tslib@^1.8.0, tslib@^1.8.1: + version "1.10.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" + integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== + +tslint@^5.18.0: + version "5.18.0" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.18.0.tgz#f61a6ddcf372344ac5e41708095bbf043a147ac6" + integrity sha512-Q3kXkuDEijQ37nXZZLKErssQVnwCV/+23gFEMROi8IlbaBG6tXqLPQJ5Wjcyt/yHPKBC+hD5SzuGaMora+ZS6w== + dependencies: + "@babel/code-frame" "^7.0.0" + builtin-modules "^1.1.1" + chalk "^2.3.0" + commander "^2.12.1" + diff "^3.2.0" + glob "^7.1.1" + js-yaml "^3.13.1" + minimatch "^3.0.4" + mkdirp "^0.5.1" + resolve "^1.3.2" + semver "^5.3.0" + tslib "^1.8.0" + tsutils "^2.29.0" + +tsutils@^2.29.0: + version "2.29.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" + integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== + dependencies: + tslib "^1.8.1" + +typescript@^3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.3.tgz#c830f657f93f1ea846819e929092f5fe5983e977" + integrity sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g== + +uc.micro@^1.0.1, uc.micro@^1.0.5: + version "1.0.6" + resolved "https://registry.npm.taobao.org/uc.micro/download/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" + integrity sha1-nEEagCpAmpH8bPdAgbq6NLJEmaw= + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=