From 69c1cc1703e1379a6f36c1dc28a9845349bb11ee Mon Sep 17 00:00:00 2001 From: m0rkeulv Date: Sun, 14 Feb 2021 17:59:41 +0100 Subject: [PATCH 1/3] Fix IDE freezing issue and make completion work for HXML files. (also adding haxe 4 arguments) --- grammar/hxml.bnf | 16 +++- .../haxe/haxelib/HaxelibCommandUtils.java | 64 +++++--------- ...ompilerArgumentsCompletionContributor.java | 88 ++++++++++++++----- .../ide/HXMLDefineCompletionContributor.java | 3 +- .../ide/HXMLHaxelibCompletionContributor.java | 5 +- 5 files changed, 108 insertions(+), 68 deletions(-) diff --git a/grammar/hxml.bnf b/grammar/hxml.bnf index 157899236..a044940cc 100644 --- a/grammar/hxml.bnf +++ b/grammar/hxml.bnf @@ -31,8 +31,16 @@ private line_recovery ::= !(eol_) private option_ ::= (lib | define | classpath | main | property | COMMENT) property ::= option value? {pin=1} -define ::= '-D' value {pin=1} -lib ::= '-lib' value (':' value)? {pin=1} -classpath ::= '-cp' value {pin=1} -main ::= '-main' qualifiedName {pin=1} +define ::= ('-D'|'--define') value {pin=1} +lib ::= (libHx3|libHx4) value (':' value)? {pin=1} +private libHx3 ::= '-lib' +private libHx4 ::= '-L'|'--library' + +classpath ::= (classpathHx3|classpathHx4) value {pin=1} +private classpathHx3 ::= '-cp' +private classpathHx4 ::= '-p' + +main ::= (mainHx3| mainHx4) qualifiedName {pin=1} +private mainHx3 ::= '-main' +private mainHx4 ::= '-m'| '--main' diff --git a/src/common/com/intellij/plugins/haxe/haxelib/HaxelibCommandUtils.java b/src/common/com/intellij/plugins/haxe/haxelib/HaxelibCommandUtils.java index 3c7c301ef..0a9c29a9e 100644 --- a/src/common/com/intellij/plugins/haxe/haxelib/HaxelibCommandUtils.java +++ b/src/common/com/intellij/plugins/haxe/haxelib/HaxelibCommandUtils.java @@ -39,6 +39,7 @@ import java.util.Collections; import java.util.List; import java.util.Scanner; +import java.util.concurrent.TimeUnit; /** * Utilities to run the haxelib command and capture its output. @@ -180,32 +181,24 @@ public static List getProcessStdout(@NotNull ArrayList commandLi Process process = builder.start(); InputStreamReader reader = new InputStreamReader(process.getInputStream()); Scanner scanner = new Scanner(reader); + process.waitFor(100, TimeUnit.MILLISECONDS); - while (scanner.hasNextLine()) { - String nextLine = scanner.nextLine(); - strings.add(nextLine); + if(reader.ready()) { + while (scanner.hasNextLine()) { + String nextLine = scanner.nextLine(); + strings.add(nextLine); + } } - process.waitFor(); - /* - try { - Thread.sleep(250); - try { - process.exitValue(); - } - catch (IllegalThreadStateException e) { + if(process.isAlive()) { + if(!process.waitFor(10, TimeUnit.MILLISECONDS)) { process.destroy(); } } - catch (InterruptedException e) { - e.printStackTrace(); - } - */ - } - catch (IOException e) { - e.printStackTrace(); + + } - catch (InterruptedException e) { + catch (IOException | InterruptedException e) { e.printStackTrace(); } @@ -224,34 +217,23 @@ public static List getProcessStderr(ArrayList commandLineArgumen InputStreamReader reader = new InputStreamReader(process.getErrorStream()); Scanner scanner = new Scanner(reader); - while (scanner.hasNextLine()) { - String nextLine = scanner.nextLine(); - strings.add(nextLine); - } - - //log.error(StringUtil.join(strings, "\n")); - process.waitFor(); - /* - try { - Thread.sleep(250); - try { - process.exitValue(); + if(reader.ready()) { + while (scanner.hasNextLine()) { + String nextLine = scanner.nextLine(); + strings.add(nextLine); } - catch (IllegalThreadStateException e) { + } + + if(process.isAlive()) { + if(!process.waitFor(10, TimeUnit.MILLISECONDS)) { process.destroy(); } } - catch (InterruptedException e) { - e.printStackTrace(); - } - */ - } - catch (IOException e) { - e.printStackTrace(); - //log.error(StringUtil.getMessage(e)); + + } - catch (InterruptedException e) { + catch (IOException | InterruptedException e) { e.printStackTrace(); //log.error(StringUtil.getMessage(e)); } diff --git a/src/common/com/intellij/plugins/haxe/ide/HXMLCompilerArgumentsCompletionContributor.java b/src/common/com/intellij/plugins/haxe/ide/HXMLCompilerArgumentsCompletionContributor.java index c4786d7d6..0d027b3cc 100644 --- a/src/common/com/intellij/plugins/haxe/ide/HXMLCompilerArgumentsCompletionContributor.java +++ b/src/common/com/intellij/plugins/haxe/ide/HXMLCompilerArgumentsCompletionContributor.java @@ -33,6 +33,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.StringJoiner; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -41,54 +42,99 @@ */ public class HXMLCompilerArgumentsCompletionContributor extends CompletionContributor { - public static List COMPILER_ARGUMENTS = null; - public static List COMPILER_ARGUMENTS2 = null; - public static final Pattern PATTERN = Pattern.compile("-([a-z-_0-9]+)[\\s](<[^>]+>)?[^:]+:[\\t\\s]+([^\\r\\n]+)"); - public static final Pattern PATTERN2 = Pattern.compile("--([a-z-_0-9]+)[^:]+:[\\t\\s]+([^\\r\\n]+)"); + public static List COMPILER_ARGUMENTS = new ArrayList<>();; + public static List COMPILER_ARGUMENTS2 = new ArrayList<>();; + public static final Pattern HAXE3_PATTERN = Pattern.compile("-([a-z-_0-9]+)[\\s](<[^>]+>)?[^:]+:[\\t\\s]+([^\\r\\n]+)"); + public static final Pattern HAXE3_PATTERN2 = Pattern.compile("--([a-z-_0-9]+)[^:]+:[\\t\\s]+([^\\r\\n]+)"); + + public static final Pattern HAXE4_PATTERN = Pattern.compile("(-((?([a-z_0-9]+)),\\s))?--(?[a-z-_0-9]+)[\\s](?<[^>]+>)?\\s*(?\\[.*\\])?\\s+[\\t\\s]+(?[^\\r\\n]+)", Pattern.CASE_INSENSITIVE); private void getCompilerArguments() { - List compilerArguments = new ArrayList(); - List compilerArguments2 = new ArrayList(); - ArrayList commandLine = new ArrayList(); + ArrayList commandLine = new ArrayList<>(); List strings = getStrings(commandLine); - Matcher matcher; + addHaxe4CompilerArguments(strings); + addHaxe3CompilerArguments(strings); + } + + private void addHaxe3CompilerArguments(List strings) { for (int i = 0; i < strings.size(); i++) { String text = strings.get(i); - matcher = PATTERN2.matcher(text); + Matcher matcher = HAXE3_PATTERN2.matcher(text); if (matcher.find()) { String group = matcher.group(1); - if (!compilerArguments2.contains(group)) { - compilerArguments2.add(new HXMLCompletionItem(group, matcher.group(2))); + if (!COMPILER_ARGUMENTS2.contains(group)) { + COMPILER_ARGUMENTS2.add(new HXMLCompletionItem(group, matcher.group(2))); } } else { - matcher = PATTERN.matcher(text); + matcher = HAXE3_PATTERN.matcher(text); if (matcher.find()) { String group = matcher.group(1); - if (!compilerArguments.contains(group)) { + if (!COMPILER_ARGUMENTS.contains(group)) { String description = matcher.group(3); String group2 = matcher.group(2); if (group2 != null) { group2 = group + " " + group2; } - compilerArguments.add(new HXMLCompletionItem(group, description, group2)); + COMPILER_ARGUMENTS.add(new HXMLCompletionItem(group, description, group2)); } } } } - if (!compilerArguments.contains("D")) { - compilerArguments.add(new HXMLCompletionItem("D")); + if (!COMPILER_ARGUMENTS.contains("D")) { + COMPILER_ARGUMENTS.add(new HXMLCompletionItem("D")); } + } + private void addHaxe4CompilerArguments(List strings) { + for (int i = 0; i < strings.size(); i++) { + String text = strings.get(i); + + Matcher matcher = HAXE4_PATTERN.matcher(text); - COMPILER_ARGUMENTS = compilerArguments; - COMPILER_ARGUMENTS2 = compilerArguments2; + if (matcher.find()) { + String shortCmd = getTextFromGroup(matcher, "short"); + String longCmd = getTextFromGroup(matcher, "long"); + + if (shortCmd != null && !COMPILER_ARGUMENTS.contains(shortCmd)) { + String description = getTextFromGroup(matcher, "description"); + StringJoiner presentation = new StringJoiner(" "); + String params = getTextFromGroup(matcher, "params"); + String params2 = getTextFromGroup(matcher, "params2"); + presentation.add(shortCmd); + if (params != null) presentation.add(params); + if (params2 != null) presentation.add(params2); + COMPILER_ARGUMENTS.add(new HXMLCompletionItem(shortCmd, description, presentation.toString())); + } + + if (longCmd != null && !COMPILER_ARGUMENTS2.contains(longCmd)) { + String description = getTextFromGroup(matcher, "description"); + StringJoiner presentation = new StringJoiner(" "); + String params = getTextFromGroup(matcher, "params"); + String params2 = getTextFromGroup(matcher, "params2"); + presentation.add(longCmd); + if (params != null) presentation.add(params); + if (params2 != null) presentation.add(params2); + + COMPILER_ARGUMENTS2.add(new HXMLCompletionItem(longCmd, description, presentation.toString())); + } + } + } + } + + private String getTextFromGroup(Matcher matcher, String groupName) { + try { + return matcher.group(groupName); + }catch (IllegalArgumentException e) { + // group not found + return null; + } } private List getStrings(ArrayList commandLine) { @@ -96,7 +142,7 @@ private List getStrings(ArrayList commandLine) { commandLine.add(HaxeHelpUtil.getHaxePath(module)); commandLine.add("--help"); - List strings = HaxelibCommandUtils.getProcessStderr(commandLine, HaxeSdkUtilBase.getSdkData(module)); + List strings = HaxelibCommandUtils.getProcessStdout(commandLine, HaxeSdkUtilBase.getSdkData(module)); if (strings.size() > 0) { strings.remove(0); } @@ -104,10 +150,10 @@ private List getStrings(ArrayList commandLine) { } public HXMLCompilerArgumentsCompletionContributor() { - if (COMPILER_ARGUMENTS == null) { + if (COMPILER_ARGUMENTS.isEmpty()) { getCompilerArguments(); } - extend(CompletionType.BASIC, PlatformPatterns.psiElement(HXMLTypes.OPTION).withLanguage(HXMLLanguage.INSTANCE), + extend(CompletionType.BASIC, PlatformPatterns.psiElement(HXMLTypes.KEY_TOKEN).withLanguage(HXMLLanguage.INSTANCE), new CompletionProvider() { @Override protected void addCompletions(@NotNull CompletionParameters parameters, diff --git a/src/common/com/intellij/plugins/haxe/ide/HXMLDefineCompletionContributor.java b/src/common/com/intellij/plugins/haxe/ide/HXMLDefineCompletionContributor.java index 1b838091e..7edf53cfc 100644 --- a/src/common/com/intellij/plugins/haxe/ide/HXMLDefineCompletionContributor.java +++ b/src/common/com/intellij/plugins/haxe/ide/HXMLDefineCompletionContributor.java @@ -22,6 +22,7 @@ import com.intellij.patterns.PlatformPatterns; import com.intellij.plugins.haxe.hxml.psi.HXMLDefine; import com.intellij.plugins.haxe.hxml.psi.HXMLTypes; +import com.intellij.plugins.haxe.hxml.psi.HXMLValue; import com.intellij.plugins.haxe.util.HaxeHelpCache; import com.intellij.util.ProcessingContext; import org.jetbrains.annotations.NotNull; @@ -34,7 +35,7 @@ public class HXMLDefineCompletionContributor extends CompletionContributor { public HXMLDefineCompletionContributor() { final List defines = HaxeHelpCache.getInstance().getDefines(); - extend(CompletionType.BASIC, PlatformPatterns.psiElement(HXMLTypes.VALUE).withParent(HXMLDefine.class), + extend(CompletionType.BASIC, PlatformPatterns.psiElement().withParent(HXMLValue.class).withSuperParent(2, HXMLDefine.class), new CompletionProvider() { @Override protected void addCompletions(@NotNull CompletionParameters parameters, diff --git a/src/common/com/intellij/plugins/haxe/ide/HXMLHaxelibCompletionContributor.java b/src/common/com/intellij/plugins/haxe/ide/HXMLHaxelibCompletionContributor.java index 9740278fc..028f8f991 100644 --- a/src/common/com/intellij/plugins/haxe/ide/HXMLHaxelibCompletionContributor.java +++ b/src/common/com/intellij/plugins/haxe/ide/HXMLHaxelibCompletionContributor.java @@ -20,10 +20,13 @@ import com.intellij.codeInsight.completion.*; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.patterns.PlatformPatterns; import com.intellij.plugins.haxe.haxelib.HaxelibCache; import com.intellij.plugins.haxe.hxml.HXMLLanguage; import com.intellij.plugins.haxe.hxml.psi.HXMLLib; +import com.intellij.plugins.haxe.hxml.psi.HXMLTokenType; import com.intellij.plugins.haxe.hxml.psi.HXMLTypes; +import com.intellij.plugins.haxe.hxml.psi.HXMLValue; import com.intellij.util.ProcessingContext; import org.jetbrains.annotations.NotNull; @@ -46,7 +49,7 @@ public HXMLHaxelibCompletionContributor() { availableHaxelibs = haxelibCache.getAvailableHaxelibs(); localHaxelibs = haxelibCache.getLocalHaxelibs(); - extend(CompletionType.BASIC, psiElement(HXMLTypes.VALUE).withParent(HXMLLib.class).withLanguage(HXMLLanguage.INSTANCE), + extend(CompletionType.BASIC, PlatformPatterns.psiElement().withParent(HXMLValue.class).withSuperParent(2, HXMLLib.class).withLanguage(HXMLLanguage.INSTANCE), new CompletionProvider() { @Override protected void addCompletions(@NotNull CompletionParameters parameters, From d6d683df70f8cc5c76b9a2d4aa0590af8c39e93c Mon Sep 17 00:00:00 2001 From: m0rkeulv Date: Sun, 14 Feb 2021 18:12:38 +0100 Subject: [PATCH 2/3] Make sure HXML completion works on intellij 2018 and earlier. --- .../ide/HXMLDefineCompletionContributor.java | 34 ++++++++++------ .../ide/HXMLHaxelibCompletionContributor.java | 39 +++++++++++-------- 2 files changed, 45 insertions(+), 28 deletions(-) diff --git a/src/common/com/intellij/plugins/haxe/ide/HXMLDefineCompletionContributor.java b/src/common/com/intellij/plugins/haxe/ide/HXMLDefineCompletionContributor.java index 7edf53cfc..508161dbe 100644 --- a/src/common/com/intellij/plugins/haxe/ide/HXMLDefineCompletionContributor.java +++ b/src/common/com/intellij/plugins/haxe/ide/HXMLDefineCompletionContributor.java @@ -29,23 +29,33 @@ import java.util.List; +import static com.intellij.patterns.PlatformPatterns.psiElement; + /** * Created by as3boyan on 19.11.14. */ public class HXMLDefineCompletionContributor extends CompletionContributor { public HXMLDefineCompletionContributor() { final List defines = HaxeHelpCache.getInstance().getDefines(); - extend(CompletionType.BASIC, PlatformPatterns.psiElement().withParent(HXMLValue.class).withSuperParent(2, HXMLDefine.class), - new CompletionProvider() { - @Override - protected void addCompletions(@NotNull CompletionParameters parameters, - ProcessingContext context, - @NotNull CompletionResultSet result) { - for (int i = 0; i < defines.size(); i++) { - HXMLCompletionItem completionItem = defines.get(i); - result.addElement(LookupElementBuilder.create(completionItem.name).withTailText(" " + completionItem.description, true)); - } - } - }); + + // intelliJ 2018 and older + extend(CompletionType.BASIC, PlatformPatterns.psiElement(HXMLTypes.VALUE).withParent(HXMLDefine.class), getProvider(defines)); + // intelliJ 2019 and newer + extend(CompletionType.BASIC, PlatformPatterns.psiElement().withParent(HXMLValue.class).withSuperParent(2, HXMLDefine.class), getProvider(defines)); + } + + @NotNull + private CompletionProvider getProvider(List defines) { + return new CompletionProvider() { + @Override + protected void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull CompletionResultSet result) { + for (int i = 0; i < defines.size(); i++) { + HXMLCompletionItem completionItem = defines.get(i); + result.addElement(LookupElementBuilder.create(completionItem.name).withTailText(" " + completionItem.description, true)); + } + } + }; } } diff --git a/src/common/com/intellij/plugins/haxe/ide/HXMLHaxelibCompletionContributor.java b/src/common/com/intellij/plugins/haxe/ide/HXMLHaxelibCompletionContributor.java index 028f8f991..afa1386f1 100644 --- a/src/common/com/intellij/plugins/haxe/ide/HXMLHaxelibCompletionContributor.java +++ b/src/common/com/intellij/plugins/haxe/ide/HXMLHaxelibCompletionContributor.java @@ -49,22 +49,29 @@ public HXMLHaxelibCompletionContributor() { availableHaxelibs = haxelibCache.getAvailableHaxelibs(); localHaxelibs = haxelibCache.getLocalHaxelibs(); - extend(CompletionType.BASIC, PlatformPatterns.psiElement().withParent(HXMLValue.class).withSuperParent(2, HXMLLib.class).withLanguage(HXMLLanguage.INSTANCE), - new CompletionProvider() { - @Override - protected void addCompletions(@NotNull CompletionParameters parameters, - ProcessingContext context, - @NotNull CompletionResultSet result) { - for (int i = 0; i < availableHaxelibs.size(); i++) { - result.addElement(LookupElementBuilder.create(availableHaxelibs.get(i)) - .withTailText(" available at haxelib", true)); - } + // intelliJ 2018 and older + extend(CompletionType.BASIC, psiElement(HXMLTypes.VALUE).withParent(HXMLLib.class).withLanguage(HXMLLanguage.INSTANCE), getProvider()); + // intelliJ 2019 and newer + extend(CompletionType.BASIC, PlatformPatterns.psiElement().withParent(HXMLValue.class).withSuperParent(2, HXMLLib.class).withLanguage(HXMLLanguage.INSTANCE), getProvider()); + } + + @NotNull + private CompletionProvider getProvider() { + return new CompletionProvider() { + @Override + protected void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull CompletionResultSet result) { + for (int i = 0; i < availableHaxelibs.size(); i++) { + result.addElement(LookupElementBuilder.create(availableHaxelibs.get(i)) + .withTailText(" available at haxelib", true)); + } - for (int i = 0; i < localHaxelibs.size(); i++) { - result.addElement(LookupElementBuilder.create(localHaxelibs.get(i)) - .withTailText(" installed", true)); - } - } - }); + for (int i = 0; i < localHaxelibs.size(); i++) { + result.addElement(LookupElementBuilder.create(localHaxelibs.get(i)) + .withTailText(" installed", true)); + } + } + }; } } From 5d92c9ce6cfe4ac4129ceafde87a4d1b849d8fa0 Mon Sep 17 00:00:00 2001 From: m0rkeulv Date: Mon, 15 Feb 2021 21:25:09 +0100 Subject: [PATCH 3/3] removing unused code and adding lines to change log. --- src/META-INF/plugin.xml | 2 + .../haxe/haxelib/HaxelibCommandUtils.java | 41 ------------------- 2 files changed, 2 insertions(+), 41 deletions(-) diff --git a/src/META-INF/plugin.xml b/src/META-INF/plugin.xml index 0fc2a3536..22eda0a38 100644 --- a/src/META-INF/plugin.xml +++ b/src/META-INF/plugin.xml @@ -85,6 +85,8 @@ Unreleased changes

    +
  • Add HXML completion for Haxe 4
  • +
  • Fixed issue where IDE would freeze when writing HXML files
  • Add HashLink target
  • improved block-statement parsing and added quickfix for missing semicolon
  • Add support for import.hx
  • diff --git a/src/common/com/intellij/plugins/haxe/haxelib/HaxelibCommandUtils.java b/src/common/com/intellij/plugins/haxe/haxelib/HaxelibCommandUtils.java index 0a9c29a9e..da78a2058 100644 --- a/src/common/com/intellij/plugins/haxe/haxelib/HaxelibCommandUtils.java +++ b/src/common/com/intellij/plugins/haxe/haxelib/HaxelibCommandUtils.java @@ -205,43 +205,6 @@ public static List getProcessStdout(@NotNull ArrayList commandLi return strings; } - - //private static Logger log = Logger.getInstance(HaxelibCommandUtils.class); - - public static List getProcessStderr(ArrayList commandLineArguments, File dir, @Nullable HaxeSdkAdditionalDataBase haxeSdkData) { - List strings = new ArrayList(); - - try { - ProcessBuilder builder = HaxeSdkUtilBase.createProcessBuilder(commandLineArguments, dir, haxeSdkData); - Process process = builder.start(); - InputStreamReader reader = new InputStreamReader(process.getErrorStream()); - Scanner scanner = new Scanner(reader); - - - if(reader.ready()) { - while (scanner.hasNextLine()) { - String nextLine = scanner.nextLine(); - strings.add(nextLine); - } - } - - if(process.isAlive()) { - if(!process.waitFor(10, TimeUnit.MILLISECONDS)) { - process.destroy(); - } - } - - - } - catch (IOException | InterruptedException e) { - e.printStackTrace(); - //log.error(StringUtil.getMessage(e)); - } - - return strings; - } - - /** * Run a shell command in the (IDEA's) current directory, capturing its standard output. * @@ -253,8 +216,4 @@ public static List getProcessStdout(@NotNull ArrayList commandLi return getProcessStdout(commandLineArguments, null, haxeSdkData); } - public static List getProcessStderr(ArrayList commandLineArguments, @Nullable HaxeSdkAdditionalDataBase haxeSdkData) { - return getProcessStderr(commandLineArguments, null, haxeSdkData); - } - }