mirror of
https://github.com/ilyakooo0/intellij-haskell.git
synced 2024-10-26 15:13:25 +03:00
Various improvements;
Started with support for formatting (under construction);
This commit is contained in:
parent
e855b5507e
commit
9ce4d08f80
@ -1,6 +1,6 @@
|
||||
<idea-plugin version="2">
|
||||
<id>com.powertuple.intellij.haskell</id>
|
||||
<name>Haskell plugin for IntelliJ</name>
|
||||
<name>Haskell</name>
|
||||
<version>0.1</version>
|
||||
<vendor email="rikvdkleij@gmail.com" url="http://www.powertuple.com">PowerTuple</vendor>
|
||||
|
||||
@ -39,6 +39,10 @@
|
||||
<applicationConfigurable instance="com.powertuple.intellij.haskell.settings.HaskellConfigurable"/>
|
||||
|
||||
<applicationService serviceImplementation="com.powertuple.intellij.haskell.settings.HaskellSettings"/>
|
||||
|
||||
<lang.formatter language="Haskell" implementationClass="com.powertuple.intellij.haskell.formatter.HaskellFormattingModelBuilder"/>
|
||||
<codeStyleSettingsProvider implementation="com.powertuple.intellij.haskell.formatter.settings.HaskellCodeStyleSettingsProvider"/>
|
||||
<langCodeStyleSettingsProvider implementation="com.powertuple.intellij.haskell.formatter.settings.HaskellLanguageCodeStyleSettingsProvider"/>
|
||||
</extensions>
|
||||
|
||||
<application-components>
|
||||
|
@ -14,7 +14,7 @@ Other Haskell support by help from external tools as ghc-mod(i).
|
||||
In the meantime also Atsky started to create [Haskell-idea-plugin](https://github.com/Atsky/haskell-idea-plugin) based on ideah plugin in Kotlin. First I saw clear difference
|
||||
in approach (besides language) but it looks like we are eventually using to same approach to support Haskell code in IntelliJ.
|
||||
|
||||
This plugin is written in Java/Scala and is mentioned not to support GHC/Cabal directly. Mine idea is to support sandbox projects
|
||||
This plugin is written in Java/Scala and is mentioned not to support GHC/Cabal directly. My idea is to support sandbox projects
|
||||
and doing the initial/basic Haskell configuration in terminal. This plugin will rely on external tools (mainly ghc-mod(i)) for Haskell language support in IntelliJ IDEA.
|
||||
The code in this project for setting the paths to external tools is based on Haskell-idea-plugin. I have no experience in creating IntelliJ
|
||||
plugins so it's 'inspiring' to look to code of other plugins :-)
|
||||
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2014 Rik van der Kleij
|
||||
|
||||
* 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
|
||||
*
|
||||
* http://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 com.powertuple.intellij.haskell
|
||||
|
||||
import com.intellij.notification.NotificationGroup
|
||||
import com.intellij.openapi.ui.MessageType
|
||||
|
||||
object HaskellNotificationGroup {
|
||||
|
||||
private val Group = NotificationGroup.balloonGroup("Haskell")
|
||||
|
||||
def notifyError(message: String) {
|
||||
Group.createNotification(message, MessageType.ERROR).notify(null)
|
||||
}
|
||||
}
|
@ -33,10 +33,25 @@ import com.powertuple.intellij.haskell.psi.HaskellFile;
|
||||
import com.powertuple.intellij.haskell.psi.HaskellTypes;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.powertuple.intellij.haskell.psi.HaskellTypes.*;
|
||||
|
||||
public class HaskellParserDefinition implements ParserDefinition {
|
||||
public static final TokenSet WHITE_SPACES = TokenSet.create(TokenType.WHITE_SPACE);
|
||||
public static final TokenSet COMMENTS = TokenSet.create(HaskellTypes.HS_COMMENT, HaskellTypes.HS_NCOMMENT);
|
||||
|
||||
public static final TokenSet RESERVED_IDS = TokenSet.create(
|
||||
HS_CASE, HS_CLASS, HS_DATA, HS_DEFAULT, HS_DERIVING, HS_DO, HS_ELSE, HS_FOREIGN,
|
||||
HS_IF, HS_IMPORT, HS_IN, HS_INFIX, HS_INFIXL, HS_INFIXR, HS_INSTANCE, HS_LET,
|
||||
HS_MODULE, HS_NEWTYPE, HS_OF, HS_THEN, HS_TYPE, HS_WHERE, HS_UNDERSCORE,
|
||||
HS_AS, HS_QUALIFIED, HS_HIDING
|
||||
);
|
||||
|
||||
public static final TokenSet OPERATORS = TokenSet.create(
|
||||
HS_DOT_DOT, HS_COLON, HS_COLON_COLON, HS_DEFINED_BY, HS_SLASH, HS_VERTICAL_BAR,
|
||||
HS_LEFT_ARROW, HS_RIGHT_ARROW, HS_AT, HS_TILDE, HS_DOUBLE_RIGHT_ARROW,
|
||||
HS_QVARSYM, HS_VARSYM, HS_QCONSYM, HS_CONSYM
|
||||
);
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Lexer createLexer(Project project) {
|
||||
@ -89,4 +104,4 @@ public class HaskellParserDefinition implements ParserDefinition {
|
||||
public SpaceRequirements spaceExistanceTypeBetweenTokens(ASTNode left, ASTNode right) {
|
||||
return SpaceRequirements.MAY;
|
||||
}
|
||||
}
|
||||
}
|
@ -18,9 +18,9 @@ import static com.powertuple.intellij.haskell.psi.HaskellTypes.*;
|
||||
%type IElementType
|
||||
%unicode
|
||||
|
||||
control_character = [\000 - \037]
|
||||
newline = \r|\n|\r\n|\f
|
||||
WHITECHAR = ({newline} | ' ' | \t | {control_character} | \ )
|
||||
control_character = [\000 - \037]
|
||||
NEWLINE = \r|\n|\r\n
|
||||
WHITE_SPACE = ([ \t\f] | {control_character})+
|
||||
|
||||
small = [a-z_] // ignoring any unicode lowercase letter for now
|
||||
large = [A-Z] // ignoring any unicode uppercase letter for now
|
||||
@ -36,7 +36,7 @@ OCTAL = 0[oO]{octit}+
|
||||
FLOAT = [-+]?([0-9]+(\\.[0-9]*)?|\\.[0-9]+)([eE][-+]?[0-9]+)?
|
||||
|
||||
COMMENT = "--"[^\r\n]*
|
||||
NCOMMENT = "{-" (.|{newline})* "-}"
|
||||
NCOMMENT = "{-" (.|{NEWLINE})* "-}"
|
||||
|
||||
CHARACTER_LITERAL = \' [^\'\\\r\n\f]* \'
|
||||
STRING_LITERAL = \" [^\"\\\r\n\f]* \"
|
||||
@ -47,10 +47,44 @@ CON_ID = {large} ({small} | {large})*
|
||||
%%
|
||||
<YYINITIAL> {
|
||||
|
||||
{WHITECHAR} { return HS_WHITE_CHAR;}
|
||||
|
||||
{COMMENT} { return HS_COMMENT; }
|
||||
{NCOMMENT} { return HS_NCOMMENT; }
|
||||
{NEWLINE} { return HS_NEWLINE; }
|
||||
{WHITE_SPACE} { return com.intellij.psi.TokenType.WHITE_SPACE; }
|
||||
|
||||
// not listed as reserved identifier but have meaning in certain context,
|
||||
// let's say specialreservedid
|
||||
"as" { return HS_AS; }
|
||||
"qualified" { return HS_QUALIFIED; }
|
||||
"hiding" { return HS_HIDING; }
|
||||
|
||||
// reservedid
|
||||
"case" { return HS_CASE; }
|
||||
"class" { return HS_CLASS; }
|
||||
"data" { return HS_DATA; }
|
||||
"default" { return HS_DEFAULT; }
|
||||
"deriving" { return HS_DERIVING; }
|
||||
"do" { return HS_DO; }
|
||||
"else" { return HS_ELSE; }
|
||||
"foreign" { return HS_FOREIGN; }
|
||||
"if" { return HS_IF; }
|
||||
"import" { return HS_IMPORT; }
|
||||
"in" { return HS_IN; }
|
||||
"infix" { return HS_INFIX; }
|
||||
"infixl" { return HS_INFIXL; }
|
||||
"infixr" { return HS_INFIXR; }
|
||||
"instance" { return HS_INSTANCE; }
|
||||
"let" { return HS_LET; }
|
||||
"module" { return HS_MODULE; }
|
||||
"newtype" { return HS_NEWTYPE; }
|
||||
"of" { return HS_OF; }
|
||||
"then" { return HS_THEN; }
|
||||
"type" { return HS_TYPE; }
|
||||
"where" { return HS_WHERE; }
|
||||
"_" { return HS_UNDERSCORE; }
|
||||
|
||||
{VAR_ID} { return HS_VAR_ID; }
|
||||
{CON_ID} { return HS_CON_ID; }
|
||||
|
||||
{CHARACTER_LITERAL} { return HS_CHARACTER_LITERAL; }
|
||||
{STRING_LITERAL} { return HS_STRING_LITERAL; }
|
||||
@ -91,7 +125,7 @@ CON_ID = {large} ({small} | {large})*
|
||||
".." { return HS_DOT_DOT; }
|
||||
"::" { return HS_COLON_COLON; }
|
||||
":" { return HS_COLON; }
|
||||
"=" { return HS_DEFINED_BY; }
|
||||
"=" { return HS_EQUAL; }
|
||||
"\\" { return HS_BACKSLASH; }
|
||||
"|" { return HS_VERTICAL_BAR; }
|
||||
"<-" { return HS_LEFT_ARROW; }
|
||||
@ -100,39 +134,5 @@ CON_ID = {large} ({small} | {large})*
|
||||
"~" { return HS_TILDE; }
|
||||
"=>" { return HS_DOUBLE_RIGHT_ARROW; }
|
||||
|
||||
// not listed as reserved identifier but have meaning in certain context,
|
||||
// let's say specialreservedid
|
||||
"as" { return HS_AS; }
|
||||
"qualified" { return HS_QUALIFIED; }
|
||||
"hiding" { return HS_HIDING; }
|
||||
|
||||
// reservedid
|
||||
"case" { return HS_CASE; }
|
||||
"class" { return HS_CLASS; }
|
||||
"data" { return HS_DATA; }
|
||||
"default" { return HS_DEFAULT; }
|
||||
"deriving" { return HS_DERIVING; }
|
||||
"do" { return HS_DO; }
|
||||
"else" { return HS_ELSE; }
|
||||
"foreign" { return HS_FOREIGN; }
|
||||
"if" { return HS_IF; }
|
||||
"import" { return HS_IMPORT; }
|
||||
"in" { return HS_IN; }
|
||||
"infix" { return HS_INFIX; }
|
||||
"infixl" { return HS_INFIXL; }
|
||||
"infixr" { return HS_INFIXR; }
|
||||
"instance" { return HS_INSTANCE; }
|
||||
"let" { return HS_LET; }
|
||||
"module" { return HS_MODULE; }
|
||||
"newtype" { return HS_NEWTYPE; }
|
||||
"of" { return HS_OF; }
|
||||
"then" { return HS_THEN; }
|
||||
"type" { return HS_TYPE; }
|
||||
"where" { return HS_WHERE; }
|
||||
"_" { return HS_UNDERSCORE; }
|
||||
|
||||
{VAR_ID} { return HS_VAR_ID; }
|
||||
{CON_ID} { return HS_CON_ID; }
|
||||
|
||||
[^] { return com.intellij.psi.TokenType.BAD_CHARACTER; }
|
||||
. { return com.intellij.psi.TokenType.BAD_CHARACTER; }
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* The following code was generated by JFlex 1.4.3 on 6/24/14 5:41 PM */
|
||||
/* The following code was generated by JFlex 1.4.3 on 7/4/14 11:04 AM */
|
||||
|
||||
package com.powertuple.intellij.haskell;
|
||||
import com.intellij.lexer.*;
|
||||
@ -9,7 +9,7 @@ import static com.powertuple.intellij.haskell.psi.HaskellTypes.*;
|
||||
/**
|
||||
* This class is a scanner generated by
|
||||
* <a href="http://www.jflex.de/">JFlex</a> 1.4.3
|
||||
* on 6/24/14 5:41 PM from the specification file
|
||||
* on 7/4/14 11:04 AM from the specification file
|
||||
* <tt>/home/rik/idea/intellij-haskell/src/com/powertuple/intellij/haskell/_HaskellLexer.flex</tt>
|
||||
*/
|
||||
public class _HaskellLexer implements FlexLexer {
|
||||
@ -33,14 +33,14 @@ public class _HaskellLexer implements FlexLexer {
|
||||
* Translates characters to character classes
|
||||
*/
|
||||
private static final String ZZ_CMAP_PACKED =
|
||||
"\1\1\10\0\1\1\1\3\1\0\1\4\1\2\21\0\1\1\1\1"+
|
||||
"\1\31\1\30\1\32\1\33\1\34\1\35\1\5\1\45\1\46\1\36"+
|
||||
"\1\21\1\47\1\25\1\37\1\40\1\13\7\16\2\10\1\54\1\50"+
|
||||
"\1\41\1\55\1\42\1\43\1\57\4\12\1\24\1\12\10\7\1\20"+
|
||||
"\10\7\1\15\2\7\1\51\1\22\1\52\1\44\1\104\1\53\1\61"+
|
||||
"\1\11\1\74\1\70\1\23\1\67\1\73\1\71\1\66\2\6\1\65"+
|
||||
"\1\100\1\72\1\17\1\101\1\63\1\76\1\62\1\75\1\64\1\77"+
|
||||
"\1\102\1\14\1\103\1\6\1\26\1\56\1\27\1\60\uff81\0";
|
||||
"\1\1\10\0\1\1\1\3\1\0\1\27\1\2\21\0\1\1\1\1"+
|
||||
"\1\55\1\30\1\56\1\57\1\60\1\61\1\26\1\71\1\72\1\62"+
|
||||
"\1\17\1\73\1\23\1\63\1\64\1\11\7\14\2\6\1\100\1\74"+
|
||||
"\1\65\1\101\1\66\1\67\1\103\4\10\1\22\1\10\10\5\1\16"+
|
||||
"\10\5\1\13\2\5\1\75\1\20\1\76\1\70\1\54\1\77\1\31"+
|
||||
"\1\7\1\44\1\40\1\21\1\37\1\43\1\41\1\36\2\4\1\35"+
|
||||
"\1\50\1\42\1\15\1\51\1\33\1\46\1\32\1\45\1\34\1\47"+
|
||||
"\1\52\1\12\1\53\1\4\1\24\1\102\1\25\1\104\uff81\0";
|
||||
|
||||
/**
|
||||
* Translates characters to character classes
|
||||
@ -53,22 +53,22 @@ public class _HaskellLexer implements FlexLexer {
|
||||
private static final int [] ZZ_ACTION = zzUnpackAction();
|
||||
|
||||
private static final String ZZ_ACTION_PACKED_0 =
|
||||
"\1\0\1\1\2\2\1\1\1\3\1\4\2\5\1\3"+
|
||||
"\1\6\1\7\1\3\1\10\1\11\1\12\1\1\1\13"+
|
||||
"\1\0\1\1\1\2\2\3\1\4\1\5\2\6\1\4"+
|
||||
"\1\7\1\10\1\4\1\11\1\12\1\13\2\1\14\4"+
|
||||
"\1\14\1\15\1\16\1\17\1\20\1\21\1\22\1\23"+
|
||||
"\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33"+
|
||||
"\1\34\1\35\1\36\1\37\1\40\1\41\1\42\14\3"+
|
||||
"\1\43\5\0\1\44\1\45\2\0\1\3\1\46\1\47"+
|
||||
"\2\0\1\50\1\51\1\52\1\53\1\54\1\55\2\3"+
|
||||
"\1\56\1\57\2\3\1\60\12\3\1\61\2\45\1\0"+
|
||||
"\1\62\1\63\1\3\1\0\1\3\1\64\17\3\1\65"+
|
||||
"\1\66\7\3\1\67\2\3\1\70\1\3\1\71\1\72"+
|
||||
"\4\3\1\73\6\3\1\74\1\3\1\75\2\3\1\76"+
|
||||
"\1\77\1\100\3\3\1\101\1\3\1\102\2\3\1\103"+
|
||||
"\1\104\1\3\1\105\1\3\1\106\1\107\1\110";
|
||||
"\1\34\1\35\1\36\1\37\1\40\1\41\1\42\1\43"+
|
||||
"\1\44\4\0\1\45\1\46\2\0\1\4\1\47\1\50"+
|
||||
"\2\0\1\51\1\0\1\52\1\53\2\4\1\54\1\55"+
|
||||
"\2\4\1\56\12\4\1\57\1\60\1\61\1\62\2\46"+
|
||||
"\1\0\1\63\1\64\1\4\1\0\1\4\1\65\17\4"+
|
||||
"\1\66\1\67\7\4\1\70\2\4\1\71\1\4\1\72"+
|
||||
"\1\73\4\4\1\74\6\4\1\75\1\4\1\76\2\4"+
|
||||
"\1\77\1\100\1\101\3\4\1\102\1\4\1\103\2\4"+
|
||||
"\1\104\1\105\1\4\1\106\1\4\1\107\1\110\1\111";
|
||||
|
||||
private static int [] zzUnpackAction() {
|
||||
int [] result = new int[167];
|
||||
int [] result = new int[168];
|
||||
int offset = 0;
|
||||
offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result);
|
||||
return result;
|
||||
@ -93,30 +93,30 @@ public class _HaskellLexer implements FlexLexer {
|
||||
private static final int [] ZZ_ROWMAP = zzUnpackRowMap();
|
||||
|
||||
private static final String ZZ_ROWMAP_PACKED_0 =
|
||||
"\0\0\0\105\0\105\0\212\0\317\0\u0114\0\u0159\0\u019e"+
|
||||
"\0\0\0\105\0\212\0\317\0\105\0\u0114\0\u0159\0\u019e"+
|
||||
"\0\u01e3\0\u0228\0\u026d\0\u02b2\0\u02f7\0\u033c\0\u0381\0\105"+
|
||||
"\0\u03c6\0\105\0\105\0\105\0\105\0\105\0\105\0\u040b"+
|
||||
"\0\105\0\u0450\0\105\0\105\0\105\0\105\0\105\0\105"+
|
||||
"\0\105\0\105\0\105\0\105\0\u0495\0\u04da\0\105\0\105"+
|
||||
"\0\105\0\u051f\0\u0564\0\u05a9\0\u05ee\0\u0633\0\u0678\0\u06bd"+
|
||||
"\0\u0702\0\u0747\0\u078c\0\u07d1\0\u0816\0\u0114\0\u085b\0\u08a0"+
|
||||
"\0\u03c6\0\u040b\0\u0450\0\u0495\0\u04da\0\u051f\0\u0564\0\u05a9"+
|
||||
"\0\u05ee\0\u0633\0\u0678\0\u06bd\0\u0702\0\u0747\0\u0114\0\105"+
|
||||
"\0\105\0\105\0\105\0\105\0\105\0\u078c\0\105\0\u07d1"+
|
||||
"\0\105\0\105\0\105\0\105\0\105\0\105\0\105\0\105"+
|
||||
"\0\105\0\105\0\u0816\0\u085b\0\105\0\105\0\105\0\u08a0"+
|
||||
"\0\u08e5\0\u092a\0\u096f\0\u0114\0\u09b4\0\u02b2\0\u09f9\0\u0a3e"+
|
||||
"\0\u0a83\0\105\0\u0ac8\0\u03c6\0\105\0\105\0\105\0\105"+
|
||||
"\0\105\0\u0114\0\u0b0d\0\u0b52\0\u0114\0\u0b97\0\u0bdc\0\u0c21"+
|
||||
"\0\u0114\0\u0c66\0\u0cab\0\u0cf0\0\u0d35\0\u0d7a\0\u0dbf\0\u0e04"+
|
||||
"\0\u0e49\0\u0e8e\0\u0ed3\0\105\0\u0f18\0\u0f5d\0\u0f5d\0\u092a"+
|
||||
"\0\u096f\0\u0fa2\0\u0fe7\0\u102c\0\u0114\0\u1071\0\u10b6\0\u10fb"+
|
||||
"\0\u1140\0\u1185\0\u11ca\0\u120f\0\u1254\0\u1299\0\u12de\0\u1323"+
|
||||
"\0\u1368\0\u13ad\0\u13f2\0\u1437\0\u0114\0\u0ac8\0\u147c\0\u14c1"+
|
||||
"\0\u1506\0\u154b\0\u1590\0\u15d5\0\u161a\0\u0114\0\u165f\0\u16a4"+
|
||||
"\0\u0114\0\u16e9\0\u0114\0\u0114\0\u172e\0\u1773\0\u17b8\0\u17fd"+
|
||||
"\0\u1842\0\u1887\0\u18cc\0\u1911\0\u1956\0\u199b\0\u19e0\0\u0114"+
|
||||
"\0\u1a25\0\u0114\0\u1a6a\0\u1aaf\0\u0114\0\u0114\0\u0114\0\u1af4"+
|
||||
"\0\u1b39\0\u1b7e\0\u0114\0\u1bc3\0\u0114\0\u1c08\0\u1c4d\0\u0114"+
|
||||
"\0\u0114\0\u1c92\0\u0114\0\u1cd7\0\u0114\0\u0114\0\u0114";
|
||||
"\0\u0a83\0\105\0\u0ac8\0\u03c6\0\105\0\u040b\0\105\0\u0114"+
|
||||
"\0\u0b0d\0\u0b52\0\u0114\0\u0b97\0\u0bdc\0\u0c21\0\u0114\0\u0c66"+
|
||||
"\0\u0cab\0\u0cf0\0\u0d35\0\u0d7a\0\u0dbf\0\u0e04\0\u0e49\0\u0e8e"+
|
||||
"\0\u0ed3\0\105\0\105\0\105\0\105\0\u0f18\0\u0f5d\0\u0f5d"+
|
||||
"\0\u092a\0\u096f\0\u0fa2\0\u0fe7\0\u102c\0\u0114\0\u1071\0\u10b6"+
|
||||
"\0\u10fb\0\u1140\0\u1185\0\u11ca\0\u120f\0\u1254\0\u1299\0\u12de"+
|
||||
"\0\u1323\0\u1368\0\u13ad\0\u13f2\0\u1437\0\u0114\0\u0ac8\0\u147c"+
|
||||
"\0\u14c1\0\u1506\0\u154b\0\u1590\0\u15d5\0\u161a\0\u0114\0\u165f"+
|
||||
"\0\u16a4\0\u0114\0\u16e9\0\u0114\0\u0114\0\u172e\0\u1773\0\u17b8"+
|
||||
"\0\u17fd\0\u1842\0\u1887\0\u18cc\0\u1911\0\u1956\0\u199b\0\u19e0"+
|
||||
"\0\u0114\0\u1a25\0\u0114\0\u1a6a\0\u1aaf\0\u0114\0\u0114\0\u0114"+
|
||||
"\0\u1af4\0\u1b39\0\u1b7e\0\u0114\0\u1bc3\0\u0114\0\u1c08\0\u1c4d"+
|
||||
"\0\u0114\0\u0114\0\u1c92\0\u0114\0\u1cd7\0\u0114\0\u0114\0\u0114";
|
||||
|
||||
private static int [] zzUnpackRowMap() {
|
||||
int [] result = new int[167];
|
||||
int [] result = new int[168];
|
||||
int offset = 0;
|
||||
offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result);
|
||||
return result;
|
||||
@ -139,114 +139,134 @@ public class _HaskellLexer implements FlexLexer {
|
||||
private static final int [] ZZ_TRANS = zzUnpackTrans();
|
||||
|
||||
private static final String ZZ_TRANS_PACKED_0 =
|
||||
"\1\2\1\3\1\4\2\3\1\5\1\6\1\7\1\10"+
|
||||
"\1\6\1\7\1\11\1\6\1\7\1\10\1\12\1\7"+
|
||||
"\1\13\1\14\1\15\1\7\1\16\1\17\1\20\1\21"+
|
||||
"\1\22\1\23\1\24\1\25\1\26\1\27\1\30\1\31"+
|
||||
"\1\32\1\33\1\34\1\35\1\36\1\37\1\40\1\41"+
|
||||
"\1\42\1\43\1\44\1\45\1\46\1\47\1\50\1\51"+
|
||||
"\1\52\1\6\1\53\1\6\1\54\1\55\1\56\1\57"+
|
||||
"\1\60\1\61\1\6\1\62\1\63\2\6\1\64\1\6"+
|
||||
"\1\65\1\6\1\66\110\0\1\3\101\0\2\67\3\0"+
|
||||
"\1\3\14\67\1\0\62\67\5\0\14\6\2\0\2\6"+
|
||||
"\34\0\24\6\6\0\2\7\1\0\2\7\1\0\2\7"+
|
||||
"\1\0\2\7\2\0\2\7\34\0\24\7\10\0\1\10"+
|
||||
"\1\2\1\3\1\4\1\5\1\6\1\7\1\10\1\6"+
|
||||
"\1\7\1\11\1\6\1\7\1\10\1\12\1\7\1\13"+
|
||||
"\1\14\1\15\1\7\1\16\1\17\1\20\1\21\1\3"+
|
||||
"\1\22\1\23\1\6\1\24\1\6\1\25\1\26\1\27"+
|
||||
"\1\30\1\31\1\32\1\6\1\33\1\34\2\6\1\35"+
|
||||
"\1\6\1\36\1\6\1\37\1\40\1\41\1\42\1\43"+
|
||||
"\1\44\1\45\1\46\1\47\1\50\1\51\1\52\1\53"+
|
||||
"\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63"+
|
||||
"\1\64\1\65\1\66\1\67\106\0\1\3\25\0\1\3"+
|
||||
"\60\0\1\5\105\0\13\6\2\0\2\6\3\0\1\6"+
|
||||
"\2\0\24\6\34\0\2\7\1\0\2\7\1\0\2\7"+
|
||||
"\1\0\2\7\2\0\2\7\6\0\24\7\36\0\1\10"+
|
||||
"\2\0\1\10\2\0\1\10\3\0\1\70\2\71\70\0"+
|
||||
"\1\10\2\0\1\10\2\72\1\10\2\73\1\0\1\70"+
|
||||
"\2\71\65\0\14\6\2\0\2\6\34\0\6\6\1\74"+
|
||||
"\15\6\10\0\1\75\2\0\1\75\2\0\1\75\3\0"+
|
||||
"\1\76\62\0\3\77\1\0\101\77\5\0\14\6\2\0"+
|
||||
"\2\6\34\0\4\6\1\100\17\6\10\0\1\75\2\0"+
|
||||
"\1\75\2\0\1\75\3\0\1\76\2\0\1\101\14\0"+
|
||||
"\1\102\67\0\1\103\57\0\2\104\3\0\15\104\1\0"+
|
||||
"\5\104\1\105\54\104\37\0\1\106\72\0\1\107\133\0"+
|
||||
"\1\110\72\0\1\111\47\0\14\6\2\0\2\6\34\0"+
|
||||
"\1\6\1\112\22\6\5\0\14\6\2\0\2\6\34\0"+
|
||||
"\3\6\1\113\20\6\5\0\14\6\2\0\1\114\1\6"+
|
||||
"\34\0\24\6\5\0\14\6\2\0\2\6\34\0\6\6"+
|
||||
"\1\115\2\6\1\116\5\6\1\117\4\6\5\0\12\6"+
|
||||
"\1\120\1\6\2\0\2\6\34\0\24\6\5\0\12\6"+
|
||||
"\1\121\1\6\2\0\1\122\1\6\34\0\1\123\23\6"+
|
||||
"\5\0\14\6\2\0\2\6\34\0\5\6\1\124\16\6"+
|
||||
"\5\0\14\6\2\0\1\125\1\6\34\0\24\6\5\0"+
|
||||
"\14\6\2\0\2\6\34\0\1\126\3\6\1\127\17\6"+
|
||||
"\5\0\14\6\2\0\2\6\34\0\10\6\1\130\11\6"+
|
||||
"\1\131\1\6\5\0\12\6\1\132\1\6\2\0\2\6"+
|
||||
"\34\0\24\6\5\0\14\6\2\0\2\6\34\0\10\6"+
|
||||
"\1\133\13\6\2\67\3\0\1\134\14\67\1\0\62\67"+
|
||||
"\3\135\1\0\101\135\10\0\1\136\2\0\1\136\2\0"+
|
||||
"\1\136\2\0\1\137\3\0\1\137\67\0\4\140\2\0"+
|
||||
"\1\140\4\0\2\140\34\0\1\140\5\0\2\140\3\0"+
|
||||
"\1\140\23\0\1\141\2\0\1\141\76\0\1\75\2\0"+
|
||||
"\1\75\2\0\1\75\3\0\1\70\2\71\70\0\1\135"+
|
||||
"\2\0\1\135\2\0\1\135\73\0\14\6\2\0\2\6"+
|
||||
"\34\0\1\6\1\142\22\6\2\101\2\0\101\101\25\103"+
|
||||
"\1\143\57\103\5\0\14\6\2\0\2\6\34\0\1\144"+
|
||||
"\23\6\5\0\14\6\2\0\2\6\34\0\14\6\1\145"+
|
||||
"\7\6\5\0\14\6\2\0\2\6\34\0\1\6\1\146"+
|
||||
"\4\6\1\147\15\6\5\0\14\6\2\0\2\6\34\0"+
|
||||
"\20\6\1\150\3\6\5\0\14\6\2\0\2\6\34\0"+
|
||||
"\15\6\1\151\6\6\5\0\14\6\2\0\2\6\34\0"+
|
||||
"\6\6\1\152\6\6\1\153\6\6\5\0\14\6\2\0"+
|
||||
"\2\6\34\0\14\6\1\154\7\6\5\0\14\6\2\0"+
|
||||
"\2\6\34\0\7\6\1\155\14\6\5\0\14\6\2\0"+
|
||||
"\2\6\34\0\21\6\1\156\2\6\5\0\14\6\2\0"+
|
||||
"\2\6\34\0\1\6\1\157\22\6\5\0\14\6\2\0"+
|
||||
"\2\6\34\0\1\160\23\6\5\0\14\6\2\0\1\161"+
|
||||
"\1\6\34\0\24\6\5\0\14\6\2\0\2\6\34\0"+
|
||||
"\20\6\1\162\3\6\5\0\14\6\2\0\2\6\34\0"+
|
||||
"\7\6\1\163\14\6\5\0\14\6\2\0\1\164\1\6"+
|
||||
"\34\0\24\6\10\0\1\135\2\0\1\135\2\0\1\135"+
|
||||
"\4\0\2\71\70\0\1\136\2\0\1\136\2\0\1\136"+
|
||||
"\73\0\14\6\2\0\1\165\1\6\34\0\24\6\25\103"+
|
||||
"\1\143\1\103\1\166\55\103\5\0\14\6\2\0\2\6"+
|
||||
"\34\0\4\6\1\167\17\6\5\0\14\6\2\0\2\6"+
|
||||
"\34\0\14\6\1\170\7\6\5\0\14\6\2\0\2\6"+
|
||||
"\34\0\5\6\1\171\16\6\5\0\12\6\1\172\1\6"+
|
||||
"\2\0\2\6\34\0\24\6\5\0\14\6\2\0\1\173"+
|
||||
"\1\6\34\0\24\6\5\0\14\6\2\0\2\6\34\0"+
|
||||
"\1\174\23\6\5\0\14\6\2\0\2\6\34\0\5\6"+
|
||||
"\1\175\16\6\5\0\14\6\2\0\2\6\34\0\1\176"+
|
||||
"\23\6\5\0\14\6\2\0\2\6\34\0\5\6\1\177"+
|
||||
"\16\6\5\0\14\6\2\0\2\6\34\0\14\6\1\200"+
|
||||
"\7\6\5\0\14\6\2\0\1\201\1\6\34\0\24\6"+
|
||||
"\5\0\14\6\2\0\2\6\34\0\1\6\1\202\22\6"+
|
||||
"\5\0\14\6\2\0\2\6\34\0\11\6\1\203\12\6"+
|
||||
"\5\0\14\6\2\0\1\204\1\6\34\0\24\6\5\0"+
|
||||
"\14\6\2\0\2\6\34\0\3\6\1\205\20\6\5\0"+
|
||||
"\14\6\2\0\2\6\34\0\15\6\1\206\6\6\5\0"+
|
||||
"\14\6\2\0\2\6\34\0\5\6\1\207\16\6\5\0"+
|
||||
"\14\6\2\0\2\6\34\0\1\210\23\6\5\0\7\6"+
|
||||
"\1\211\4\6\2\0\2\6\34\0\24\6\5\0\14\6"+
|
||||
"\2\0\2\6\34\0\15\6\1\212\6\6\5\0\14\6"+
|
||||
"\2\0\2\6\34\0\5\6\1\213\16\6\5\0\14\6"+
|
||||
"\2\0\2\6\34\0\3\6\1\214\20\6\5\0\14\6"+
|
||||
"\2\0\2\6\34\0\16\6\1\215\5\6\5\0\14\6"+
|
||||
"\2\0\2\6\34\0\11\6\1\216\12\6\5\0\14\6"+
|
||||
"\2\0\2\6\34\0\22\6\1\217\1\6\5\0\14\6"+
|
||||
"\2\0\2\6\34\0\1\6\1\220\22\6\5\0\14\6"+
|
||||
"\2\0\2\6\34\0\4\6\1\221\17\6\5\0\14\6"+
|
||||
"\2\0\1\222\1\6\34\0\24\6\5\0\14\6\2\0"+
|
||||
"\2\6\34\0\6\6\1\223\15\6\5\0\14\6\2\0"+
|
||||
"\2\6\34\0\11\6\1\224\12\6\5\0\14\6\2\0"+
|
||||
"\2\6\34\0\4\6\1\225\10\6\1\226\6\6\5\0"+
|
||||
"\14\6\2\0\2\6\34\0\14\6\1\227\7\6\5\0"+
|
||||
"\14\6\2\0\2\6\34\0\12\6\1\230\11\6\5\0"+
|
||||
"\14\6\2\0\2\6\34\0\4\6\1\231\17\6\5\0"+
|
||||
"\14\6\2\0\2\6\34\0\5\6\1\232\16\6\5\0"+
|
||||
"\14\6\2\0\2\6\34\0\12\6\1\233\11\6\5\0"+
|
||||
"\14\6\2\0\2\6\34\0\20\6\1\234\3\6\5\0"+
|
||||
"\14\6\2\0\1\235\1\6\34\0\24\6\5\0\14\6"+
|
||||
"\2\0\2\6\34\0\5\6\1\236\16\6\5\0\14\6"+
|
||||
"\2\0\2\6\34\0\13\6\1\237\10\6\5\0\14\6"+
|
||||
"\2\0\2\6\34\0\11\6\1\240\12\6\5\0\14\6"+
|
||||
"\2\0\2\6\34\0\14\6\1\241\7\6\5\0\14\6"+
|
||||
"\2\0\2\6\34\0\11\6\1\242\12\6\5\0\14\6"+
|
||||
"\2\0\1\243\1\6\34\0\24\6\5\0\14\6\2\0"+
|
||||
"\1\244\1\6\34\0\24\6\5\0\14\6\2\0\1\245"+
|
||||
"\1\6\34\0\24\6\5\0\14\6\2\0\2\6\34\0"+
|
||||
"\12\6\1\246\11\6\5\0\14\6\2\0\2\6\34\0"+
|
||||
"\7\6\1\247\14\6";
|
||||
"\2\71\66\0\13\6\2\0\2\6\3\0\1\6\2\0"+
|
||||
"\6\6\1\74\15\6\36\0\1\75\2\0\1\75\2\0"+
|
||||
"\1\75\3\0\1\76\64\0\3\77\1\0\101\77\4\0"+
|
||||
"\13\6\2\0\2\6\3\0\1\6\2\0\4\6\1\100"+
|
||||
"\17\6\36\0\1\75\2\0\1\75\2\0\1\75\3\0"+
|
||||
"\1\76\2\0\1\101\42\0\1\102\41\0\1\103\61\0"+
|
||||
"\2\104\2\0\14\104\1\0\5\104\1\105\1\0\55\104"+
|
||||
"\2\106\2\0\14\106\1\0\6\106\1\0\1\107\54\106"+
|
||||
"\4\0\13\6\2\0\2\6\3\0\1\6\2\0\1\6"+
|
||||
"\1\110\22\6\34\0\13\6\2\0\2\6\3\0\1\6"+
|
||||
"\2\0\3\6\1\111\20\6\34\0\13\6\2\0\1\112"+
|
||||
"\1\6\3\0\1\6\2\0\24\6\34\0\13\6\2\0"+
|
||||
"\2\6\3\0\1\6\2\0\6\6\1\113\2\6\1\114"+
|
||||
"\5\6\1\115\4\6\34\0\11\6\1\116\1\6\2\0"+
|
||||
"\2\6\3\0\1\6\2\0\24\6\34\0\11\6\1\117"+
|
||||
"\1\6\2\0\1\120\1\6\3\0\1\6\2\0\1\121"+
|
||||
"\23\6\34\0\13\6\2\0\2\6\3\0\1\6\2\0"+
|
||||
"\5\6\1\122\16\6\34\0\13\6\2\0\1\123\1\6"+
|
||||
"\3\0\1\6\2\0\24\6\34\0\13\6\2\0\2\6"+
|
||||
"\3\0\1\6\2\0\1\124\3\6\1\125\17\6\34\0"+
|
||||
"\13\6\2\0\2\6\3\0\1\6\2\0\10\6\1\126"+
|
||||
"\11\6\1\127\1\6\34\0\11\6\1\130\1\6\2\0"+
|
||||
"\2\6\3\0\1\6\2\0\24\6\34\0\13\6\2\0"+
|
||||
"\2\6\3\0\1\6\2\0\10\6\1\131\13\6\113\0"+
|
||||
"\1\132\44\0\1\133\161\0\1\134\72\0\1\135\16\0"+
|
||||
"\3\136\1\0\101\136\6\0\1\137\2\0\1\137\2\0"+
|
||||
"\1\137\2\0\1\140\3\0\1\140\67\0\4\141\2\0"+
|
||||
"\1\141\4\0\2\141\6\0\1\141\5\0\2\141\3\0"+
|
||||
"\1\141\51\0\1\142\2\0\1\142\76\0\1\75\2\0"+
|
||||
"\1\75\2\0\1\75\3\0\1\70\2\71\70\0\1\136"+
|
||||
"\2\0\1\136\2\0\1\136\74\0\13\6\2\0\2\6"+
|
||||
"\3\0\1\6\2\0\1\6\1\143\22\6\30\0\2\101"+
|
||||
"\2\0\101\101\23\103\1\144\61\103\4\0\13\6\2\0"+
|
||||
"\2\6\3\0\1\6\2\0\1\145\23\6\34\0\13\6"+
|
||||
"\2\0\2\6\3\0\1\6\2\0\14\6\1\146\7\6"+
|
||||
"\34\0\13\6\2\0\2\6\3\0\1\6\2\0\1\6"+
|
||||
"\1\147\4\6\1\150\15\6\34\0\13\6\2\0\2\6"+
|
||||
"\3\0\1\6\2\0\20\6\1\151\3\6\34\0\13\6"+
|
||||
"\2\0\2\6\3\0\1\6\2\0\15\6\1\152\6\6"+
|
||||
"\34\0\13\6\2\0\2\6\3\0\1\6\2\0\6\6"+
|
||||
"\1\153\6\6\1\154\6\6\34\0\13\6\2\0\2\6"+
|
||||
"\3\0\1\6\2\0\14\6\1\155\7\6\34\0\13\6"+
|
||||
"\2\0\2\6\3\0\1\6\2\0\7\6\1\156\14\6"+
|
||||
"\34\0\13\6\2\0\2\6\3\0\1\6\2\0\21\6"+
|
||||
"\1\157\2\6\34\0\13\6\2\0\2\6\3\0\1\6"+
|
||||
"\2\0\1\6\1\160\22\6\34\0\13\6\2\0\2\6"+
|
||||
"\3\0\1\6\2\0\1\161\23\6\34\0\13\6\2\0"+
|
||||
"\1\162\1\6\3\0\1\6\2\0\24\6\34\0\13\6"+
|
||||
"\2\0\2\6\3\0\1\6\2\0\20\6\1\163\3\6"+
|
||||
"\34\0\13\6\2\0\2\6\3\0\1\6\2\0\7\6"+
|
||||
"\1\164\14\6\34\0\13\6\2\0\1\165\1\6\3\0"+
|
||||
"\1\6\2\0\24\6\36\0\1\136\2\0\1\136\2\0"+
|
||||
"\1\136\4\0\2\71\70\0\1\137\2\0\1\137\2\0"+
|
||||
"\1\137\74\0\13\6\2\0\1\166\1\6\3\0\1\6"+
|
||||
"\2\0\24\6\30\0\23\103\1\144\1\103\1\167\57\103"+
|
||||
"\4\0\13\6\2\0\2\6\3\0\1\6\2\0\4\6"+
|
||||
"\1\170\17\6\34\0\13\6\2\0\2\6\3\0\1\6"+
|
||||
"\2\0\14\6\1\171\7\6\34\0\13\6\2\0\2\6"+
|
||||
"\3\0\1\6\2\0\5\6\1\172\16\6\34\0\11\6"+
|
||||
"\1\173\1\6\2\0\2\6\3\0\1\6\2\0\24\6"+
|
||||
"\34\0\13\6\2\0\1\174\1\6\3\0\1\6\2\0"+
|
||||
"\24\6\34\0\13\6\2\0\2\6\3\0\1\6\2\0"+
|
||||
"\1\175\23\6\34\0\13\6\2\0\2\6\3\0\1\6"+
|
||||
"\2\0\5\6\1\176\16\6\34\0\13\6\2\0\2\6"+
|
||||
"\3\0\1\6\2\0\1\177\23\6\34\0\13\6\2\0"+
|
||||
"\2\6\3\0\1\6\2\0\5\6\1\200\16\6\34\0"+
|
||||
"\13\6\2\0\2\6\3\0\1\6\2\0\14\6\1\201"+
|
||||
"\7\6\34\0\13\6\2\0\1\202\1\6\3\0\1\6"+
|
||||
"\2\0\24\6\34\0\13\6\2\0\2\6\3\0\1\6"+
|
||||
"\2\0\1\6\1\203\22\6\34\0\13\6\2\0\2\6"+
|
||||
"\3\0\1\6\2\0\11\6\1\204\12\6\34\0\13\6"+
|
||||
"\2\0\1\205\1\6\3\0\1\6\2\0\24\6\34\0"+
|
||||
"\13\6\2\0\2\6\3\0\1\6\2\0\3\6\1\206"+
|
||||
"\20\6\34\0\13\6\2\0\2\6\3\0\1\6\2\0"+
|
||||
"\15\6\1\207\6\6\34\0\13\6\2\0\2\6\3\0"+
|
||||
"\1\6\2\0\5\6\1\210\16\6\34\0\13\6\2\0"+
|
||||
"\2\6\3\0\1\6\2\0\1\211\23\6\34\0\6\6"+
|
||||
"\1\212\4\6\2\0\2\6\3\0\1\6\2\0\24\6"+
|
||||
"\34\0\13\6\2\0\2\6\3\0\1\6\2\0\15\6"+
|
||||
"\1\213\6\6\34\0\13\6\2\0\2\6\3\0\1\6"+
|
||||
"\2\0\5\6\1\214\16\6\34\0\13\6\2\0\2\6"+
|
||||
"\3\0\1\6\2\0\3\6\1\215\20\6\34\0\13\6"+
|
||||
"\2\0\2\6\3\0\1\6\2\0\16\6\1\216\5\6"+
|
||||
"\34\0\13\6\2\0\2\6\3\0\1\6\2\0\11\6"+
|
||||
"\1\217\12\6\34\0\13\6\2\0\2\6\3\0\1\6"+
|
||||
"\2\0\22\6\1\220\1\6\34\0\13\6\2\0\2\6"+
|
||||
"\3\0\1\6\2\0\1\6\1\221\22\6\34\0\13\6"+
|
||||
"\2\0\2\6\3\0\1\6\2\0\4\6\1\222\17\6"+
|
||||
"\34\0\13\6\2\0\1\223\1\6\3\0\1\6\2\0"+
|
||||
"\24\6\34\0\13\6\2\0\2\6\3\0\1\6\2\0"+
|
||||
"\6\6\1\224\15\6\34\0\13\6\2\0\2\6\3\0"+
|
||||
"\1\6\2\0\11\6\1\225\12\6\34\0\13\6\2\0"+
|
||||
"\2\6\3\0\1\6\2\0\4\6\1\226\10\6\1\227"+
|
||||
"\6\6\34\0\13\6\2\0\2\6\3\0\1\6\2\0"+
|
||||
"\14\6\1\230\7\6\34\0\13\6\2\0\2\6\3\0"+
|
||||
"\1\6\2\0\12\6\1\231\11\6\34\0\13\6\2\0"+
|
||||
"\2\6\3\0\1\6\2\0\4\6\1\232\17\6\34\0"+
|
||||
"\13\6\2\0\2\6\3\0\1\6\2\0\5\6\1\233"+
|
||||
"\16\6\34\0\13\6\2\0\2\6\3\0\1\6\2\0"+
|
||||
"\12\6\1\234\11\6\34\0\13\6\2\0\2\6\3\0"+
|
||||
"\1\6\2\0\20\6\1\235\3\6\34\0\13\6\2\0"+
|
||||
"\1\236\1\6\3\0\1\6\2\0\24\6\34\0\13\6"+
|
||||
"\2\0\2\6\3\0\1\6\2\0\5\6\1\237\16\6"+
|
||||
"\34\0\13\6\2\0\2\6\3\0\1\6\2\0\13\6"+
|
||||
"\1\240\10\6\34\0\13\6\2\0\2\6\3\0\1\6"+
|
||||
"\2\0\11\6\1\241\12\6\34\0\13\6\2\0\2\6"+
|
||||
"\3\0\1\6\2\0\14\6\1\242\7\6\34\0\13\6"+
|
||||
"\2\0\2\6\3\0\1\6\2\0\11\6\1\243\12\6"+
|
||||
"\34\0\13\6\2\0\1\244\1\6\3\0\1\6\2\0"+
|
||||
"\24\6\34\0\13\6\2\0\1\245\1\6\3\0\1\6"+
|
||||
"\2\0\24\6\34\0\13\6\2\0\1\246\1\6\3\0"+
|
||||
"\1\6\2\0\24\6\34\0\13\6\2\0\2\6\3\0"+
|
||||
"\1\6\2\0\12\6\1\247\11\6\34\0\13\6\2\0"+
|
||||
"\2\6\3\0\1\6\2\0\7\6\1\250\14\6\30\0";
|
||||
|
||||
private static int [] zzUnpackTrans() {
|
||||
int [] result = new int[7452];
|
||||
@ -290,13 +310,13 @@ public class _HaskellLexer implements FlexLexer {
|
||||
private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute();
|
||||
|
||||
private static final String ZZ_ATTRIBUTE_PACKED_0 =
|
||||
"\1\0\2\11\14\1\1\11\1\1\6\11\1\1\1\11"+
|
||||
"\1\1\12\11\2\1\3\11\15\1\5\0\2\1\2\0"+
|
||||
"\2\1\1\11\2\0\5\11\22\1\1\11\2\1\1\0"+
|
||||
"\3\1\1\0\104\1";
|
||||
"\1\0\1\11\2\1\1\11\12\1\1\11\17\1\6\11"+
|
||||
"\1\1\1\11\1\1\12\11\2\1\3\11\4\0\2\1"+
|
||||
"\2\0\2\1\1\11\2\0\1\11\1\0\1\11\22\1"+
|
||||
"\4\11\2\1\1\0\3\1\1\0\104\1";
|
||||
|
||||
private static int [] zzUnpackAttribute() {
|
||||
int [] result = new int[167];
|
||||
int [] result = new int[168];
|
||||
int offset = 0;
|
||||
offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result);
|
||||
return result;
|
||||
@ -591,294 +611,298 @@ public class _HaskellLexer implements FlexLexer {
|
||||
zzMarkedPos = zzMarkedPosL;
|
||||
|
||||
switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) {
|
||||
case 56:
|
||||
case 57:
|
||||
{ return HS_CASE;
|
||||
}
|
||||
case 73: break;
|
||||
case 50:
|
||||
case 74: break;
|
||||
case 51:
|
||||
{ return HS_HEXADECIMAL;
|
||||
}
|
||||
case 74: break;
|
||||
case 38:
|
||||
case 75: break;
|
||||
case 39:
|
||||
{ return HS_COMMENT;
|
||||
}
|
||||
case 75: break;
|
||||
case 43:
|
||||
case 76: break;
|
||||
case 49:
|
||||
{ return HS_COLON_COLON;
|
||||
}
|
||||
case 76: break;
|
||||
case 60:
|
||||
case 77: break;
|
||||
case 61:
|
||||
{ return HS_CLASS;
|
||||
}
|
||||
case 77: break;
|
||||
case 72:
|
||||
case 78: break;
|
||||
case 73:
|
||||
{ return HS_QUALIFIED;
|
||||
}
|
||||
case 78: break;
|
||||
case 69:
|
||||
case 79: break;
|
||||
case 70:
|
||||
{ return HS_NEWTYPE;
|
||||
}
|
||||
case 79: break;
|
||||
case 33:
|
||||
case 80: break;
|
||||
case 35:
|
||||
{ return HS_AT;
|
||||
}
|
||||
case 80: break;
|
||||
case 41:
|
||||
case 81: break;
|
||||
case 47:
|
||||
{ return HS_DOT_DOT;
|
||||
}
|
||||
case 81: break;
|
||||
case 46:
|
||||
case 82: break;
|
||||
case 44:
|
||||
{ return HS_IF;
|
||||
}
|
||||
case 82: break;
|
||||
case 26:
|
||||
{ return HS_SEMICOLON;
|
||||
}
|
||||
case 83: break;
|
||||
case 59:
|
||||
{ return HS_INFIX;
|
||||
case 3:
|
||||
{ return HS_NEWLINE;
|
||||
}
|
||||
case 84: break;
|
||||
case 45:
|
||||
{ return HS_AS;
|
||||
case 28:
|
||||
{ return HS_SEMICOLON;
|
||||
}
|
||||
case 85: break;
|
||||
case 37:
|
||||
{ return HS_FLOAT;
|
||||
case 60:
|
||||
{ return HS_INFIX;
|
||||
}
|
||||
case 86: break;
|
||||
case 24:
|
||||
{ return HS_RIGHT_PAREN;
|
||||
case 2:
|
||||
{ return com.intellij.psi.TokenType.WHITE_SPACE;
|
||||
}
|
||||
case 87: break;
|
||||
case 54:
|
||||
{ return HS_NCOMMENT;
|
||||
case 43:
|
||||
{ return HS_AS;
|
||||
}
|
||||
case 88: break;
|
||||
case 34:
|
||||
{ return HS_TILDE;
|
||||
case 38:
|
||||
{ return HS_FLOAT;
|
||||
}
|
||||
case 89: break;
|
||||
case 8:
|
||||
{ return HS_DASH;
|
||||
case 26:
|
||||
{ return HS_RIGHT_PAREN;
|
||||
}
|
||||
case 90: break;
|
||||
case 5:
|
||||
{ return HS_DECIMAL;
|
||||
case 55:
|
||||
{ return HS_NCOMMENT;
|
||||
}
|
||||
case 91: break;
|
||||
case 52:
|
||||
{ return HS_LET;
|
||||
case 36:
|
||||
{ return HS_TILDE;
|
||||
}
|
||||
case 92: break;
|
||||
case 18:
|
||||
{ return HS_SLASH;
|
||||
case 9:
|
||||
{ return HS_DASH;
|
||||
}
|
||||
case 93: break;
|
||||
case 61:
|
||||
{ return HS_WHERE;
|
||||
case 6:
|
||||
{ return HS_DECIMAL;
|
||||
}
|
||||
case 94: break;
|
||||
case 11:
|
||||
{ return HS_EXCLAMATION_MARK;
|
||||
case 53:
|
||||
{ return HS_LET;
|
||||
}
|
||||
case 95: break;
|
||||
case 40:
|
||||
{ return HS_STRING_LITERAL;
|
||||
case 20:
|
||||
{ return HS_SLASH;
|
||||
}
|
||||
case 96: break;
|
||||
case 42:
|
||||
{ return HS_LEFT_ARROW;
|
||||
case 62:
|
||||
{ return HS_WHERE;
|
||||
}
|
||||
case 97: break;
|
||||
case 66:
|
||||
{ return HS_MODULE;
|
||||
case 13:
|
||||
{ return HS_EXCLAMATION_MARK;
|
||||
}
|
||||
case 98: break;
|
||||
case 9:
|
||||
{ return HS_LEFT_BRACE;
|
||||
case 42:
|
||||
{ return HS_STRING_LITERAL;
|
||||
}
|
||||
case 99: break;
|
||||
case 55:
|
||||
{ return HS_DATA;
|
||||
case 48:
|
||||
{ return HS_LEFT_ARROW;
|
||||
}
|
||||
case 100: break;
|
||||
case 49:
|
||||
{ return HS_CHARACTER_LITERAL;
|
||||
case 67:
|
||||
{ return HS_MODULE;
|
||||
}
|
||||
case 101: break;
|
||||
case 3:
|
||||
{ return HS_VAR_ID;
|
||||
case 10:
|
||||
{ return HS_LEFT_BRACE;
|
||||
}
|
||||
case 102: break;
|
||||
case 35:
|
||||
{ return HS_UNDERSCORE;
|
||||
case 56:
|
||||
{ return HS_DATA;
|
||||
}
|
||||
case 103: break;
|
||||
case 6:
|
||||
{ return HS_PLUS;
|
||||
case 41:
|
||||
{ return HS_CHARACTER_LITERAL;
|
||||
}
|
||||
case 104: break;
|
||||
case 15:
|
||||
{ return HS_AMPERSAND;
|
||||
case 4:
|
||||
{ return HS_VAR_ID;
|
||||
}
|
||||
case 105: break;
|
||||
case 32:
|
||||
{ return HS_VERTICAL_BAR;
|
||||
case 12:
|
||||
{ return HS_UNDERSCORE;
|
||||
}
|
||||
case 106: break;
|
||||
case 58:
|
||||
{ return HS_TYPE;
|
||||
case 7:
|
||||
{ return HS_PLUS;
|
||||
}
|
||||
case 107: break;
|
||||
case 13:
|
||||
{ return HS_DOLLAR;
|
||||
case 17:
|
||||
{ return HS_AMPERSAND;
|
||||
}
|
||||
case 108: break;
|
||||
case 12:
|
||||
{ return HS_HASH;
|
||||
case 34:
|
||||
{ return HS_VERTICAL_BAR;
|
||||
}
|
||||
case 109: break;
|
||||
case 65:
|
||||
{ return HS_HIDING;
|
||||
case 59:
|
||||
{ return HS_TYPE;
|
||||
}
|
||||
case 110: break;
|
||||
case 14:
|
||||
{ return HS_PERCENTAGE;
|
||||
case 15:
|
||||
{ return HS_DOLLAR;
|
||||
}
|
||||
case 111: break;
|
||||
case 30:
|
||||
{ return HS_COLON;
|
||||
case 14:
|
||||
{ return HS_HASH;
|
||||
}
|
||||
case 112: break;
|
||||
case 70:
|
||||
{ return HS_INSTANCE;
|
||||
case 33:
|
||||
{ return HS_EQUAL;
|
||||
}
|
||||
case 113: break;
|
||||
case 28:
|
||||
{ return HS_RIGHT_BRACKET;
|
||||
case 66:
|
||||
{ return HS_HIDING;
|
||||
}
|
||||
case 114: break;
|
||||
case 23:
|
||||
{ return HS_LEFT_PAREN;
|
||||
case 16:
|
||||
{ return HS_PERCENTAGE;
|
||||
}
|
||||
case 115: break;
|
||||
case 29:
|
||||
{ return HS_BACKQUOTE;
|
||||
case 32:
|
||||
{ return HS_COLON;
|
||||
}
|
||||
case 116: break;
|
||||
case 19:
|
||||
{ return HS_LT;
|
||||
case 71:
|
||||
{ return HS_INSTANCE;
|
||||
}
|
||||
case 117: break;
|
||||
case 27:
|
||||
{ return HS_LEFT_BRACKET;
|
||||
case 30:
|
||||
{ return HS_RIGHT_BRACKET;
|
||||
}
|
||||
case 118: break;
|
||||
case 21:
|
||||
{ return HS_QUESTION_MARK;
|
||||
case 25:
|
||||
{ return HS_LEFT_PAREN;
|
||||
}
|
||||
case 119: break;
|
||||
case 62:
|
||||
{ return HS_INFIXL;
|
||||
case 31:
|
||||
{ return HS_BACKQUOTE;
|
||||
}
|
||||
case 120: break;
|
||||
case 64:
|
||||
{ return HS_IMPORT;
|
||||
case 21:
|
||||
{ return HS_LT;
|
||||
}
|
||||
case 121: break;
|
||||
case 71:
|
||||
{ return HS_DERIVING;
|
||||
case 29:
|
||||
{ return HS_LEFT_BRACKET;
|
||||
}
|
||||
case 122: break;
|
||||
case 4:
|
||||
{ return HS_CON_ID;
|
||||
case 23:
|
||||
{ return HS_QUESTION_MARK;
|
||||
}
|
||||
case 123: break;
|
||||
case 48:
|
||||
{ return HS_DO;
|
||||
case 63:
|
||||
{ return HS_INFIXL;
|
||||
}
|
||||
case 124: break;
|
||||
case 17:
|
||||
{ return HS_DOT;
|
||||
case 65:
|
||||
{ return HS_IMPORT;
|
||||
}
|
||||
case 125: break;
|
||||
case 47:
|
||||
{ return HS_IN;
|
||||
case 72:
|
||||
{ return HS_DERIVING;
|
||||
}
|
||||
case 126: break;
|
||||
case 51:
|
||||
{ return HS_OCTAL;
|
||||
case 5:
|
||||
{ return HS_CON_ID;
|
||||
}
|
||||
case 127: break;
|
||||
case 63:
|
||||
{ return HS_INFIXR;
|
||||
case 46:
|
||||
{ return HS_DO;
|
||||
}
|
||||
case 128: break;
|
||||
case 22:
|
||||
{ return HS_CARET;
|
||||
case 19:
|
||||
{ return HS_DOT;
|
||||
}
|
||||
case 129: break;
|
||||
case 45:
|
||||
{ return HS_IN;
|
||||
}
|
||||
case 130: break;
|
||||
case 52:
|
||||
{ return HS_OCTAL;
|
||||
}
|
||||
case 131: break;
|
||||
case 64:
|
||||
{ return HS_INFIXR;
|
||||
}
|
||||
case 132: break;
|
||||
case 24:
|
||||
{ return HS_CARET;
|
||||
}
|
||||
case 133: break;
|
||||
case 1:
|
||||
{ return com.intellij.psi.TokenType.BAD_CHARACTER;
|
||||
}
|
||||
case 130: break;
|
||||
case 68:
|
||||
case 134: break;
|
||||
case 69:
|
||||
{ return HS_DEFAULT;
|
||||
}
|
||||
case 131: break;
|
||||
case 44:
|
||||
case 135: break;
|
||||
case 50:
|
||||
{ return HS_DOUBLE_RIGHT_ARROW;
|
||||
}
|
||||
case 132: break;
|
||||
case 53:
|
||||
case 136: break;
|
||||
case 54:
|
||||
{ return HS_ELSE;
|
||||
}
|
||||
case 133: break;
|
||||
case 25:
|
||||
case 137: break;
|
||||
case 27:
|
||||
{ return HS_COMMA;
|
||||
}
|
||||
case 134: break;
|
||||
case 20:
|
||||
case 138: break;
|
||||
case 22:
|
||||
{ return HS_GT;
|
||||
}
|
||||
case 135: break;
|
||||
case 31:
|
||||
{ return HS_DEFINED_BY;
|
||||
}
|
||||
case 136: break;
|
||||
case 16:
|
||||
case 139: break;
|
||||
case 18:
|
||||
{ return HS_STAR;
|
||||
}
|
||||
case 137: break;
|
||||
case 7:
|
||||
case 140: break;
|
||||
case 8:
|
||||
{ return HS_BACKSLASH;
|
||||
}
|
||||
case 138: break;
|
||||
case 2:
|
||||
{ return HS_WHITE_CHAR;
|
||||
}
|
||||
case 139: break;
|
||||
case 36:
|
||||
case 141: break;
|
||||
case 37:
|
||||
{ return HS_OF;
|
||||
}
|
||||
case 140: break;
|
||||
case 67:
|
||||
case 142: break;
|
||||
case 68:
|
||||
{ return HS_FOREIGN;
|
||||
}
|
||||
case 141: break;
|
||||
case 57:
|
||||
case 143: break;
|
||||
case 58:
|
||||
{ return HS_THEN;
|
||||
}
|
||||
case 142: break;
|
||||
case 39:
|
||||
case 144: break;
|
||||
case 40:
|
||||
{ return HS_RIGHT_ARROW;
|
||||
}
|
||||
case 143: break;
|
||||
case 10:
|
||||
case 145: break;
|
||||
case 11:
|
||||
{ return HS_RIGHT_BRACE;
|
||||
}
|
||||
case 144: break;
|
||||
case 146: break;
|
||||
default:
|
||||
if (zzInput == YYEOF && zzStartRead == zzCurrentPos) {
|
||||
zzAtEOF = true;
|
||||
|
@ -16,26 +16,17 @@
|
||||
|
||||
package com.powertuple.intellij.haskell.annotator
|
||||
|
||||
import com.intellij.lang.annotation.{AnnotationHolder, ExternalAnnotator}
|
||||
import com.intellij.notification.NotificationGroup
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.openapi.application.{ModalityState, ApplicationManager}
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager
|
||||
import com.intellij.execution.process.ProcessOutput
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer
|
||||
import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl
|
||||
import com.intellij.openapi.ui.MessageType
|
||||
import scala.collection.JavaConversions._
|
||||
import com.intellij.lang.annotation.{AnnotationHolder, ExternalAnnotator}
|
||||
import com.intellij.openapi.application.{ApplicationManager, ModalityState}
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.powertuple.intellij.haskell.HaskellFileType
|
||||
import com.powertuple.intellij.haskell.external.GhciModManager
|
||||
|
||||
class GhcModiExternalAnnotator extends ExternalAnnotator[GhcModInitialInfo, GhcModResult] {
|
||||
private val Log = Logger.getInstance(classOf[GhcModiExternalAnnotator])
|
||||
|
||||
private val GhcModNotificationGroup = NotificationGroup.balloonGroup("Ghc-mod inspections")
|
||||
class GhcModiExternalAnnotator extends ExternalAnnotator[GhcModInitialInfo, GhcModiResult] {
|
||||
|
||||
/**
|
||||
* Returning null will cause doAnnotate() not to be called by Intellij API.
|
||||
@ -50,7 +41,7 @@ class GhcModiExternalAnnotator extends ExternalAnnotator[GhcModInitialInfo, GhcM
|
||||
}
|
||||
}
|
||||
|
||||
override def doAnnotate(initialInfoGhcMod: GhcModInitialInfo): GhcModResult = {
|
||||
override def doAnnotate(initialInfoGhcMod: GhcModInitialInfo): GhcModiResult = {
|
||||
ApplicationManager.getApplication.invokeAndWait(new Runnable() {
|
||||
override def run() {
|
||||
FileDocumentManager.getInstance.saveDocument(FileDocumentManager.getInstance().getDocument(initialInfoGhcMod.psiFile.getVirtualFile))
|
||||
@ -58,16 +49,16 @@ class GhcModiExternalAnnotator extends ExternalAnnotator[GhcModInitialInfo, GhcM
|
||||
}, ModalityState.any())
|
||||
|
||||
val ghcModi = GhciModManager.getGhcMod(initialInfoGhcMod.psiFile.getProject)
|
||||
val ghcModOutput = ghcModi.execute("check " + initialInfoGhcMod.filePath)
|
||||
val ghcModiOutput = ghcModi.execute("check " + initialInfoGhcMod.filePath)
|
||||
|
||||
if (ghcModOutput.outputLines.isEmpty) {
|
||||
new GhcModResult(Seq())
|
||||
if (ghcModiOutput.outputLines.isEmpty) {
|
||||
new GhcModiResult(Seq())
|
||||
} else {
|
||||
new GhcModResult(ghcModOutput.outputLines.map(parseGhcModOutputLine))
|
||||
new GhcModiResult(ghcModiOutput.outputLines.map(parseGhcModiOutputLine))
|
||||
}
|
||||
}
|
||||
|
||||
override def apply(psiFile: PsiFile, ghcModResult: GhcModResult, holder: AnnotationHolder) {
|
||||
override def apply(psiFile: PsiFile, ghcModResult: GhcModiResult, holder: AnnotationHolder) {
|
||||
if (ghcModResult.problems.nonEmpty && psiFile.isValid) {
|
||||
for (annotation <- createAnnotations(ghcModResult, psiFile.getText)) {
|
||||
annotation match {
|
||||
@ -85,20 +76,15 @@ class GhcModiExternalAnnotator extends ExternalAnnotator[GhcModInitialInfo, GhcM
|
||||
fileStatusMap.markFileScopeDirty(document, new TextRange(0, document.getTextLength), psiFile.getTextLength)
|
||||
}
|
||||
|
||||
private def startOffSetForProblem(lengthPerLine: Array[Int], problem: GhcModProblem): Int = {
|
||||
val lineNr = problem.lineNr
|
||||
(if (lineNr <= 1) {
|
||||
0
|
||||
} else {
|
||||
lengthPerLine.take(lineNr - 1).sum
|
||||
}) + problem.columnNr - 1
|
||||
private def startOffSetForProblem(lengthPerLine: Iterator[Int], problem: GhcModiProblem): Int = {
|
||||
lengthPerLine.take(problem.lineNr - 1).map(_ + 1).sum + problem.columnNr
|
||||
}
|
||||
|
||||
private[annotator] def createAnnotations(ghcModResult: GhcModResult, text: String): Seq[Annotation] = {
|
||||
val lengthPerLine = StringUtil.splitByLines(text, false).map(_.size + 1)
|
||||
private[annotator] def createAnnotations(ghcModResult: GhcModiResult, text: String): Seq[Annotation] = {
|
||||
val lengthPerLine = text.lines.map(_.size)
|
||||
for (problem <- ghcModResult.problems) yield {
|
||||
val startOffSet = startOffSetForProblem(lengthPerLine, problem)
|
||||
val textRange = TextRange.create(startOffSet, startOffSet + 1)
|
||||
val textRange = TextRange.create(startOffSet - 1, startOffSet)
|
||||
if (problem.description.startsWith("Warning:")) {
|
||||
WarningAnnotation(textRange, problem.description)
|
||||
} else {
|
||||
@ -107,25 +93,18 @@ class GhcModiExternalAnnotator extends ExternalAnnotator[GhcModInitialInfo, GhcM
|
||||
}
|
||||
}
|
||||
|
||||
private[annotator] def parseGhcModOutput(ghcModOutput: ProcessOutput): Seq[GhcModProblem] = {
|
||||
ghcModOutput match {
|
||||
case gmo if !gmo.getStderrLines.isEmpty => GhcModNotificationGroup.createNotification(s"Ghc-mod error output: ${gmo.getStderr}", MessageType.ERROR); Seq()
|
||||
case gmo => gmo.getStdoutLines.map(parseGhcModOutputLine)
|
||||
}
|
||||
}
|
||||
|
||||
private def parseGhcModOutputLine(ghcModOutput: String): GhcModProblem = {
|
||||
private[annotator] def parseGhcModiOutputLine(ghcModOutput: String): GhcModiProblem = {
|
||||
val ghcModProblemPattern = """.+:([\d]+):([\d]+):(.+)""".r
|
||||
val ghcModProblemPattern(lineNr, columnNr, description) = ghcModOutput
|
||||
new GhcModProblem(lineNr.toInt, columnNr.toInt - 1, description)
|
||||
new GhcModiProblem(lineNr.toInt, columnNr.toInt, description)
|
||||
}
|
||||
}
|
||||
|
||||
case class GhcModInitialInfo(psiFile: PsiFile, filePath: String)
|
||||
|
||||
case class GhcModResult(problems: Seq[GhcModProblem] = Seq())
|
||||
case class GhcModiResult(problems: Seq[GhcModiProblem] = Seq())
|
||||
|
||||
case class GhcModProblem(lineNr: Int, columnNr: Int, description: String)
|
||||
case class GhcModiProblem(lineNr: Int, columnNr: Int, description: String)
|
||||
|
||||
abstract class Annotation
|
||||
|
||||
|
@ -17,10 +17,11 @@
|
||||
package com.powertuple.intellij.haskell.external
|
||||
|
||||
import java.io._
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.{Executors, TimeoutException}
|
||||
|
||||
import com.intellij.openapi.components.ProjectComponent
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.powertuple.intellij.haskell.HaskellNotificationGroup
|
||||
import com.powertuple.intellij.haskell.settings.HaskellSettings
|
||||
|
||||
import scala.collection.mutable.ListBuffer
|
||||
@ -41,7 +42,6 @@ class GhcModi(val project: Project, val settings: HaskellSettings) extends Proje
|
||||
def reportFailure(t: Throwable) {}
|
||||
}
|
||||
|
||||
private[this] var process: Process = _
|
||||
private[this] var outputStream: OutputStream = _
|
||||
private[this] val stdOutListBuffer = ListBuffer[String]()
|
||||
private[this] val stdErrListBuffer = ListBuffer[String]()
|
||||
@ -49,51 +49,79 @@ class GhcModi(val project: Project, val settings: HaskellSettings) extends Proje
|
||||
private val OK = "OK"
|
||||
|
||||
def execute(command: String): GhcModiOutput = synchronized {
|
||||
if (outputStream == null) {
|
||||
// creating Process has failed in #startGhcModi
|
||||
return GhcModiOutput()
|
||||
}
|
||||
|
||||
stdOutListBuffer.clear()
|
||||
stdErrListBuffer.clear()
|
||||
try {
|
||||
outputStream.write((command + "\n").getBytes)
|
||||
outputStream.flush()
|
||||
|
||||
outputStream.write((command + "\n").getBytes)
|
||||
outputStream.flush()
|
||||
val waitForOutput = Future {
|
||||
while (stdOutListBuffer.lastOption != Some(OK)) {
|
||||
Thread.sleep(5)
|
||||
}
|
||||
}
|
||||
Await.result(waitForOutput, 2.second)
|
||||
|
||||
val waitForOutput = Future {
|
||||
while (stdOutListBuffer.lastOption != Some(OK)) {
|
||||
Thread.sleep(5)
|
||||
if (stdErrListBuffer.nonEmpty) {
|
||||
HaskellNotificationGroup.notifyError(s"ghc-modi error output: ${stdErrListBuffer.mkString}")
|
||||
GhcModiOutput()
|
||||
} else {
|
||||
GhcModiOutput(stdOutListBuffer.filter(_ != OK))
|
||||
}
|
||||
}
|
||||
catch {
|
||||
case _: TimeoutException | _: IOException => {
|
||||
HaskellNotificationGroup.notifyError("Error in communication with ghc-modi. ghc-modi will be restarted.")
|
||||
reinit()
|
||||
GhcModiOutput()
|
||||
}
|
||||
}
|
||||
Await.result(waitForOutput, 2.second)
|
||||
|
||||
GhcModiOutput(stdOutListBuffer.filter(_ != OK), stdErrListBuffer)
|
||||
}
|
||||
|
||||
def exit() {
|
||||
outputStream.close()
|
||||
private def exit() {
|
||||
if (outputStream != null) {
|
||||
outputStream.close()
|
||||
}
|
||||
}
|
||||
|
||||
private def startGhcModi() {
|
||||
try {
|
||||
Process(settings.getState.ghcModiPath, new File(project.getBasePath)).run(
|
||||
new ProcessIO(
|
||||
stdin => outputStream = stdin,
|
||||
stdout => Source.fromInputStream(stdout).getLines.foreach(stdOutListBuffer.+=),
|
||||
stderr => Source.fromInputStream(stderr).getLines.foreach(stdErrListBuffer.+=)
|
||||
))
|
||||
}
|
||||
catch {
|
||||
case e: IOException => {
|
||||
HaskellNotificationGroup.notifyError("Can not get connection with ghc-modi. Make sure you have set right path in settings to ghc-modi.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def reinit() {
|
||||
exit()
|
||||
initComponent()
|
||||
startGhcModi()
|
||||
}
|
||||
|
||||
override def projectOpened(): Unit = {}
|
||||
override def projectOpened(): Unit = {
|
||||
startGhcModi()
|
||||
}
|
||||
|
||||
override def projectClosed(): Unit = {
|
||||
exit()
|
||||
}
|
||||
|
||||
override def initComponent(): Unit = {
|
||||
Process(settings.getState.ghcModiPath, new File(project.getBasePath)).run(
|
||||
new ProcessIO(
|
||||
stdin => outputStream = stdin,
|
||||
stdout => Source.fromInputStream(stdout).getLines.foreach(stdOutListBuffer.+=),
|
||||
stderr => Source.fromInputStream(stderr).getLines.foreach(stdErrListBuffer.+=)
|
||||
))
|
||||
}
|
||||
override def initComponent(): Unit = {}
|
||||
|
||||
override def disposeComponent(): Unit = {}
|
||||
|
||||
override def getComponentName: String = "ghcModi"
|
||||
|
||||
|
||||
}
|
||||
|
||||
case class GhcModiOutput(outputLines: Seq[String], errorLines: Seq[String])
|
||||
case class GhcModiOutput(outputLines: Seq[String] = Seq())
|
@ -0,0 +1,258 @@
|
||||
/*
|
||||
* Copyright 2014 Rik van der Kleij
|
||||
|
||||
* 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
|
||||
*
|
||||
* http://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 com.powertuple.intellij.haskell.formatter;
|
||||
|
||||
import com.intellij.formatting.*;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.TokenType;
|
||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
|
||||
import com.intellij.psi.formatter.FormatterUtil;
|
||||
import com.intellij.psi.impl.source.tree.FileElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.powertuple.intellij.haskell.formatter.settings.HaskellCodeStyleSettings;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.powertuple.intellij.haskell.psi.HaskellTypes.*;
|
||||
|
||||
/**
|
||||
* Formatter which use blank line as start of new definition.
|
||||
*/
|
||||
public class HaskellFormattingBlock implements ASTBlock {
|
||||
|
||||
@NotNull
|
||||
protected final ASTNode node;
|
||||
@Nullable
|
||||
protected final Wrap wrap;
|
||||
@Nullable
|
||||
protected final Alignment alignment;
|
||||
private final CommonCodeStyleSettings settings;
|
||||
private final HaskellCodeStyleSettings haskellSettings;
|
||||
private final SpacingBuilder spacingBuilder;
|
||||
private List<Block> subBlocks;
|
||||
private Boolean incomplete;
|
||||
|
||||
private boolean indentWithTabSize;
|
||||
private int indentCounter;
|
||||
private static final TokenSet ReservedIdsToIndent = TokenSet.create(HS_VERTICAL_BAR);
|
||||
public static final TokenSet RESERVED_IDS_TO_INDENT = TokenSet.create(HS_WHERE, HS_THEN, HS_DO);
|
||||
public static final TokenSet RESERVED_IDS_TO_BACK_INDENT = TokenSet.create(HS_ELSE);
|
||||
private final TokenSet INDENT_PREV_RESERVED_IDS = TokenSet.create(HS_WHERE, HS_DO, HS_THEN, HS_ELSE);
|
||||
|
||||
public HaskellFormattingBlock(@NotNull ASTNode node,
|
||||
@NotNull CommonCodeStyleSettings settings,
|
||||
@NotNull HaskellCodeStyleSettings haskellSettings,
|
||||
@NotNull SpacingBuilder spacingBuilder,
|
||||
@Nullable Wrap wrap,
|
||||
int indentCounter,
|
||||
boolean indentWithTabSize,
|
||||
@Nullable Alignment alignment) {
|
||||
this.node = node;
|
||||
this.wrap = wrap;
|
||||
this.alignment = alignment;
|
||||
this.settings = settings;
|
||||
this.haskellSettings = haskellSettings;
|
||||
this.spacingBuilder = spacingBuilder;
|
||||
this.indentCounter = indentCounter;
|
||||
this.indentWithTabSize = indentWithTabSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ASTNode getNode() {
|
||||
return node;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public TextRange getTextRange() {
|
||||
return node.getTextRange();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<Block> getSubBlocks() {
|
||||
if (subBlocks == null) {
|
||||
subBlocks = buildSubBlocks();
|
||||
}
|
||||
return new ArrayList<Block>(subBlocks);
|
||||
}
|
||||
|
||||
private List<Block> buildSubBlocks() {
|
||||
final List<Block> blocks = new ArrayList<Block>();
|
||||
|
||||
if (!(node instanceof FileElement)) {
|
||||
return Collections.unmodifiableList(blocks);
|
||||
}
|
||||
|
||||
ASTNode prevNode = null;
|
||||
Alignment alignment = null;
|
||||
|
||||
boolean startNewlineInDefinition = false;
|
||||
boolean startOfNewDefinition = false;
|
||||
boolean notIndentAgain = false;
|
||||
|
||||
for (ASTNode child = node.getFirstChildNode(); child != null; child = child.getTreeNext()) {
|
||||
if (child.getElementType() == HS_NEWLINE) {
|
||||
if (startNewlineInDefinition) {
|
||||
startOfNewDefinition = true;
|
||||
indentCounter = 0;
|
||||
alignment = null;
|
||||
notIndentAgain = false;
|
||||
} else {
|
||||
startNewlineInDefinition = true;
|
||||
}
|
||||
continue;
|
||||
} else if (child.getElementType() == TokenType.WHITE_SPACE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
indentWithTabSize = false;
|
||||
|
||||
if (isReservedIdToIndent(child) && startNewlineInDefinition && !startOfNewDefinition) {
|
||||
if (typeExistsFor(child, HS_WHERE)) {
|
||||
if (indentCounter > 0) {
|
||||
indentCounter--;
|
||||
}
|
||||
if (haskellSettings.INDENT_WHERE_WITH_TAB_SIZE) {
|
||||
indentWithTabSize = true;
|
||||
} else {
|
||||
indentCounter += 1;
|
||||
}
|
||||
} else {
|
||||
indentCounter += 1;
|
||||
}
|
||||
alignment = null;
|
||||
notIndentAgain = false;
|
||||
} else if (isReservedIdToBackIndent(child) && startNewlineInDefinition) {
|
||||
if (indentCounter > 0) {
|
||||
indentCounter -= 1;
|
||||
} else {
|
||||
indentCounter = 0;
|
||||
}
|
||||
alignment = null;
|
||||
notIndentAgain = false;
|
||||
} else if (isReservedOpToIndent(child) && startNewlineInDefinition && !notIndentAgain) {
|
||||
indentCounter += 1;
|
||||
notIndentAgain = true;
|
||||
} else if (prevNode != null) {
|
||||
if (typeExistsFor(prevNode, HS_EQUAL) && startNewlineInDefinition) {
|
||||
indentCounter += 1;
|
||||
alignment = Alignment.createAlignment(true);
|
||||
notIndentAgain = false;
|
||||
} else if (indentBecausePrevReservedId(prevNode) && !startOfNewDefinition && startNewlineInDefinition) {
|
||||
indentCounter += 1;
|
||||
alignment = Alignment.createAlignment(true);
|
||||
notIndentAgain = false;
|
||||
} else if ((prevNode.getElementType() == HS_LEFT_PAREN) && startNewlineInDefinition) {
|
||||
indentCounter += 1;
|
||||
alignment = Alignment.createAlignment(true);
|
||||
notIndentAgain = false;
|
||||
}
|
||||
}
|
||||
|
||||
blocks.add(new HaskellFormattingBlock(child, settings, haskellSettings, spacingBuilder, getWrap(), indentCounter, indentWithTabSize, alignment));
|
||||
|
||||
startOfNewDefinition = false;
|
||||
startNewlineInDefinition = false;
|
||||
prevNode = child;
|
||||
}
|
||||
return Collections.unmodifiableList(blocks);
|
||||
}
|
||||
|
||||
private boolean isReservedOpToIndent(ASTNode node) {
|
||||
return node.findChildByType(ReservedIdsToIndent) != null;
|
||||
}
|
||||
|
||||
private boolean isReservedIdToIndent(ASTNode node) {
|
||||
return node.findChildByType(RESERVED_IDS_TO_INDENT) != null;
|
||||
}
|
||||
|
||||
private boolean isReservedIdToBackIndent(ASTNode node) {
|
||||
return node.findChildByType(RESERVED_IDS_TO_BACK_INDENT) != null;
|
||||
}
|
||||
|
||||
private boolean indentBecausePrevReservedId(ASTNode node) {
|
||||
return node.findChildByType(INDENT_PREV_RESERVED_IDS) != null;
|
||||
}
|
||||
|
||||
private boolean typeExistsFor(ASTNode node, IElementType elementType) {
|
||||
return node.findChildByType(elementType) != null;
|
||||
}
|
||||
|
||||
private int getTabSize() {
|
||||
return settings.getIndentOptions().TAB_SIZE;
|
||||
}
|
||||
|
||||
private int getIndentSize() {
|
||||
return settings.getIndentOptions().INDENT_SIZE;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Indent getIndent() {
|
||||
return Indent.getSpaceIndent(indentCounter * getIndentSize() + (indentWithTabSize ? getTabSize() : 0));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Wrap getWrap() {
|
||||
return wrap;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Alignment getAlignment() {
|
||||
return alignment;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Spacing getSpacing(@Nullable Block child1, @NotNull Block child2) {
|
||||
return spacingBuilder.getSpacing(this, child1, child2);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ChildAttributes getChildAttributes(int newChildIndex) {
|
||||
Block block = getSubBlocks().get(newChildIndex - 1);
|
||||
return new ChildAttributes(block.getIndent(), block.getAlignment());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIncomplete() {
|
||||
if (incomplete == null) {
|
||||
incomplete = FormatterUtil.isIncomplete(getNode());
|
||||
}
|
||||
return incomplete;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLeaf() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return node.getText() + " " + getTextRange();
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2014 Rik van der Kleij
|
||||
|
||||
* 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
|
||||
*
|
||||
* http://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 com.powertuple.intellij.haskell.formatter;
|
||||
|
||||
import com.intellij.formatting.*;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
|
||||
import com.powertuple.intellij.haskell.HaskellLanguage;
|
||||
import com.powertuple.intellij.haskell.HaskellParserDefinition;
|
||||
import com.powertuple.intellij.haskell.formatter.settings.HaskellCodeStyleSettings;
|
||||
import com.powertuple.intellij.haskell.psi.HaskellElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static com.powertuple.intellij.haskell.psi.HaskellTypes.HS_COMMA;
|
||||
import static com.powertuple.intellij.haskell.psi.HaskellTypes.HS_NEWLINE;
|
||||
import static com.powertuple.intellij.haskell.psi.HaskellTypes.HS_TYPE;
|
||||
|
||||
public class HaskellFormattingModelBuilder implements FormattingModelBuilder {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public FormattingModel createModel(PsiElement element, CodeStyleSettings settings) {
|
||||
CommonCodeStyleSettings commonSettings = settings.getCommonSettings(HaskellLanguage.INSTANCE);
|
||||
HaskellCodeStyleSettings haskellSettings = settings.getCustomSettings(HaskellCodeStyleSettings.class);
|
||||
SpacingBuilder spacingBuilder = createSpacingBuilder(commonSettings, haskellSettings);
|
||||
HaskellFormattingBlock block = new HaskellFormattingBlock(element.getNode(), commonSettings, haskellSettings, spacingBuilder, Wrap.createWrap(WrapType.NONE, true), 0, false, null);
|
||||
return FormattingModelProvider.createFormattingModelForPsiFile(element.getContainingFile(), block, settings);
|
||||
}
|
||||
|
||||
private static SpacingBuilder createSpacingBuilder(CommonCodeStyleSettings settings, HaskellCodeStyleSettings haskellCodeStyleSettings) {
|
||||
return new SpacingBuilder(settings.getRootSettings(), HaskellLanguage.INSTANCE)
|
||||
.before(HS_COMMA).spaceIf(settings.SPACE_BEFORE_COMMA)
|
||||
.after(HS_COMMA).spaceIf(settings.SPACE_AFTER_COMMA)
|
||||
|
||||
.around(HaskellParserDefinition.RESERVED_IDS).spaces(1);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TextRange getRangeAffectingIndent(PsiFile file, int offset, ASTNode elementAtOffset) {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2014 Rik van der Kleij
|
||||
|
||||
* 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
|
||||
*
|
||||
* http://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 com.powertuple.intellij.haskell.formatter.settings;
|
||||
|
||||
import com.intellij.application.options.CodeStyleAbstractConfigurable;
|
||||
import com.intellij.application.options.CodeStyleAbstractPanel;
|
||||
import com.intellij.application.options.TabbedLanguageCodeStylePanel;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.powertuple.intellij.haskell.HaskellLanguage;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class HaskellCodeStyleConfigurable extends CodeStyleAbstractConfigurable {
|
||||
public HaskellCodeStyleConfigurable(@NotNull CodeStyleSettings settings, CodeStyleSettings cloneSettings) {
|
||||
super(settings, cloneSettings, "Haskell");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CodeStyleAbstractPanel createPanel(CodeStyleSettings settings) {
|
||||
return new HaskellCodeStyleMainPanel(getCurrentSettings(), settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpTopic() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static class HaskellCodeStyleMainPanel extends TabbedLanguageCodeStylePanel {
|
||||
private HaskellCodeStyleMainPanel(CodeStyleSettings currentSettings, CodeStyleSettings settings) {
|
||||
super(HaskellLanguage.INSTANCE, currentSettings, settings);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2014 Rik van der Kleij
|
||||
|
||||
* 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
|
||||
*
|
||||
* http://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 com.powertuple.intellij.haskell.formatter.settings;
|
||||
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CustomCodeStyleSettings;
|
||||
|
||||
public class HaskellCodeStyleSettings extends CustomCodeStyleSettings {
|
||||
protected HaskellCodeStyleSettings(CodeStyleSettings settings) {
|
||||
super("HaskellCodeStyleSettings", settings);
|
||||
}
|
||||
|
||||
public boolean INDENT_WHERE_WITH_TAB_SIZE = true;
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2014 Rik van der Kleij
|
||||
|
||||
* 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
|
||||
*
|
||||
* http://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 com.powertuple.intellij.haskell.formatter.settings;
|
||||
|
||||
import com.intellij.openapi.options.Configurable;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsProvider;
|
||||
import com.intellij.psi.codeStyle.CustomCodeStyleSettings;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class HaskellCodeStyleSettingsProvider extends CodeStyleSettingsProvider {
|
||||
@Override
|
||||
public String getConfigurableDisplayName() {
|
||||
return "Haskell";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Configurable createSettingsPage(CodeStyleSettings settings, CodeStyleSettings originalSettings) {
|
||||
return new HaskellCodeStyleConfigurable(settings, originalSettings);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public CustomCodeStyleSettings createCustomSettings(CodeStyleSettings settings) {
|
||||
return new HaskellCodeStyleSettings(settings);
|
||||
}
|
||||
}
|
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2014 Rik van der Kleij
|
||||
|
||||
* 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
|
||||
*
|
||||
* http://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 com.powertuple.intellij.haskell.formatter.settings;
|
||||
|
||||
import com.intellij.application.options.IndentOptionsEditor;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsCustomizable;
|
||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider;
|
||||
import com.powertuple.intellij.haskell.HaskellLanguage;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class HaskellLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSettingsProvider {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Language getLanguage() {
|
||||
return HaskellLanguage.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCodeSample(@NotNull SettingsType settingsType) {
|
||||
if (settingsType == SettingsType.SPACING_SETTINGS) {
|
||||
return SPACING_CODE_SAMPLE;
|
||||
} else if (settingsType == SettingsType.WRAPPING_AND_BRACES_SETTINGS) {
|
||||
return DEFAULT_CODE_SAMPLE;
|
||||
} else if (settingsType == SettingsType.INDENT_SETTINGS) {
|
||||
return INDENT_CODE_SAMPLE;
|
||||
}
|
||||
return DEFAULT_CODE_SAMPLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IndentOptionsEditor getIndentOptionsEditor() {
|
||||
return new HaskellSmartIndentOptionsEditor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonCodeStyleSettings getDefaultCommonSettings() {
|
||||
CommonCodeStyleSettings defaultSettings = new CommonCodeStyleSettings(getLanguage());
|
||||
CommonCodeStyleSettings.IndentOptions indentOptions = defaultSettings.initIndentOptions();
|
||||
indentOptions.INDENT_SIZE = 4;
|
||||
indentOptions.CONTINUATION_INDENT_SIZE = 8;
|
||||
indentOptions.TAB_SIZE = 2;
|
||||
|
||||
return defaultSettings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customizeSettings(@NotNull CodeStyleSettingsCustomizable consumer, @NotNull SettingsType settingsType) {
|
||||
if (settingsType == SettingsType.SPACING_SETTINGS) {
|
||||
consumer.showStandardOptions(
|
||||
"SPACE_AFTER_COMMA",
|
||||
"SPACE_BEFORE_COMMA"
|
||||
);
|
||||
|
||||
// consumer.showCustomOption(HaskellCodeStyleSettings.class, "SPACE_AROUND_OPERATORS", "Operator", CodeStyleSettingsCustomizable.SPACES_AROUND_OPERATORS);
|
||||
}
|
||||
// else if (settingsType == SettingsType.BLANK_LINES_SETTINGS) {
|
||||
// consumer.showStandardOptions("KEEP_BLANK_LINES_IN_CODE");
|
||||
// }
|
||||
}
|
||||
|
||||
private static final String SPACING_CODE_SAMPLE =
|
||||
"l = [1,2,3]";
|
||||
|
||||
private static final String INDENT_CODE_SAMPLE =
|
||||
"module SayHello\n" +
|
||||
"(\n" +
|
||||
"sayHello\n" +
|
||||
") where\n" +
|
||||
"\n" +
|
||||
"sayHello :: IO ()\n" +
|
||||
"sayHello = do\n" +
|
||||
"name <- getLine\n" +
|
||||
"putStrLn $ greeting name\n" +
|
||||
"where\n" +
|
||||
"greeting name = \"Hello, \" ++ name ++ \"!\"";
|
||||
|
||||
private static final String DEFAULT_CODE_SAMPLE =
|
||||
"module Quicksort where\n" +
|
||||
"\n" +
|
||||
"quicksort :: (Ord t) => [t] -> [t]\n" +
|
||||
"quicksort [] = []\n" +
|
||||
"quicksort (x:xs) = quicksort smallerOrEqual ++ [x] ++ quicksort larger\n" +
|
||||
"where smallerOrEqual = [y | y <- xs, y <= x]\n" +
|
||||
"larger = [y | y <- xs, y > x]\n" +
|
||||
"\n" +
|
||||
"result = quicksort [1,2]";
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2014 Rik van der Kleij
|
||||
|
||||
* 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
|
||||
*
|
||||
* http://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 com.powertuple.intellij.haskell.formatter.settings;
|
||||
|
||||
import com.intellij.application.options.SmartIndentOptionsEditor;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class HaskellSmartIndentOptionsEditor extends SmartIndentOptionsEditor {
|
||||
|
||||
private JCheckBox indentWhereWithTabSizeCheckBox;
|
||||
|
||||
protected void addComponents() {
|
||||
super.addComponents();
|
||||
|
||||
indentWhereWithTabSizeCheckBox = new JCheckBox("Indent 'where' with tab size");
|
||||
add(indentWhereWithTabSizeCheckBox, true);
|
||||
}
|
||||
|
||||
public boolean isModified(final CodeStyleSettings settings, final CommonCodeStyleSettings.IndentOptions options) {
|
||||
boolean isModified = super.isModified(settings, options);
|
||||
|
||||
isModified |= isFieldModified(indentWhereWithTabSizeCheckBox, getHaskellCodeStyleSettings(settings).INDENT_WHERE_WITH_TAB_SIZE);
|
||||
|
||||
return isModified;
|
||||
}
|
||||
|
||||
public void apply(final CodeStyleSettings settings, final CommonCodeStyleSettings.IndentOptions options) {
|
||||
super.apply(settings, options);
|
||||
|
||||
getHaskellCodeStyleSettings(settings).INDENT_WHERE_WITH_TAB_SIZE = indentWhereWithTabSizeCheckBox.isSelected();
|
||||
}
|
||||
|
||||
public void reset(@NotNull final CodeStyleSettings settings, @NotNull final CommonCodeStyleSettings.IndentOptions options) {
|
||||
super.reset(settings, options);
|
||||
|
||||
indentWhereWithTabSizeCheckBox.setSelected(getHaskellCodeStyleSettings(settings).INDENT_WHERE_WITH_TAB_SIZE);
|
||||
}
|
||||
|
||||
public void setEnabled(final boolean enabled) {
|
||||
super.setEnabled(enabled);
|
||||
indentWhereWithTabSizeCheckBox.setEnabled(enabled);
|
||||
}
|
||||
|
||||
private HaskellCodeStyleSettings getHaskellCodeStyleSettings(final CodeStyleSettings settings) {
|
||||
return settings.getCustomSettings(HaskellCodeStyleSettings.class);
|
||||
}
|
||||
}
|
@ -20,43 +20,38 @@
|
||||
tokens = [
|
||||
]
|
||||
|
||||
name(".*")='varide'
|
||||
// name(".*")='varide'
|
||||
// extends(".*")=lexeme
|
||||
}
|
||||
|
||||
program ::= (lexeme | whitespace)*
|
||||
whitespace ::= (whitestuff)+
|
||||
whitestuff ::= WHITE_CHAR | COMMENT | NCOMMENT
|
||||
lexeme ::= qvarid | qconid | qvarsym | qconsym | literal | special | reservedop | reservedid | specialreservedid
|
||||
private whitespace ::= (whitestuff)+
|
||||
private whitestuff ::= WHITE_CHAR | COMMENT | NCOMMENT | NEWLINE
|
||||
private lexeme ::= qvarid | varid | qconid | conid | qconsym | consym | qvarsym | varsym | literal
|
||||
| special | reservedop | reservedid | specialreservedid
|
||||
|
||||
literal ::= DECIMAL | HEXADECIMAL | OCTAL | FLOAT | CHARACTER_LITERAL | STRING_LITERAL
|
||||
|
||||
special ::= LEFT_PAREN | RIGHT_PAREN | COMMA | SEMICOLON | LEFT_BRACKET | RIGHT_BRACKET
|
||||
private special ::= LEFT_PAREN | RIGHT_PAREN | COMMA | SEMICOLON | LEFT_BRACKET | RIGHT_BRACKET
|
||||
| BACKQUOTE | LEFT_BRACE | RIGHT_BRACE
|
||||
|
||||
ascSymbolExcReservedopDash ::= EXCLAMATION_MARK | HASH | DOLLAR| PERCENTAGE | AMPERSAND | STAR
|
||||
| PLUS | DOT | BACKSLASH | LT | GT | QUESTION_MARK | CARET
|
||||
ascSymbolExcReservedop ::= ascSymbolExcReservedopDash | DASH
|
||||
private ascSymbol ::= EXCLAMATION_MARK | HASH | DOLLAR| PERCENTAGE | AMPERSAND | STAR
|
||||
| PLUS | DOT | SLASH | LT | EQUAL | GT | QUESTION_MARK | AT | BACKSLASH | CARET
|
||||
| VERTICAL_BAR | TILDE | COLON | DASH
|
||||
|
||||
symbolExcReservedopDash ::= ascSymbolExcReservedopDash // ignoring unicode symbols
|
||||
private symbol ::= ascSymbol // ignoring unicode symbols
|
||||
|
||||
varsym ::= (symbolExcReservedopDash (symbolExcReservedopDash | ':')*) // operator
|
||||
consym ::= (':' (symbolExcReservedopDash | ':')*) // operator constructor
|
||||
varsym ::= (symbol (symbol | ':')*) // operator
|
||||
consym ::= (':' (symbol | ':')*) // operator constructor
|
||||
|
||||
varid ::= VAR_ID // variables
|
||||
conid ::= CON_ID // constructors
|
||||
tyvar ::= varid // type variables
|
||||
tycon ::= conid // type constructors
|
||||
tycls ::= conid // type classes
|
||||
modid ::= (conid '.')* conid // modules
|
||||
private varid ::= VAR_ID // variables and type variables
|
||||
private conid ::= CON_ID // constructors, type constructors and type classes
|
||||
|
||||
qvarid ::= (modid '.')? varid
|
||||
qconid ::= (modid '.')? conid
|
||||
qtycon ::= (modid '.')? tycon
|
||||
qtycls ::= (modid '.')? tycls
|
||||
|
||||
qvarsym ::= (modid '.')? varsym
|
||||
qconsym ::= (modid '.')? consym
|
||||
qvarid ::= (conid '.')+ varid
|
||||
qconid ::= (conid '.')+ conid
|
||||
|
||||
qvarsym ::= (conid '.')+ varsym
|
||||
qconsym ::= (conid '.')+ consym
|
||||
|
||||
reservedid ::= CASE | CLASS | DATA | DEFAULT | DERIVING | DO | ELSE
|
||||
| FOREIGN | IF | IMPORT | IN | INFIX | INFIXL | INFIXR
|
||||
|
@ -84,7 +84,8 @@ public class HaskellColorSettingsPage implements ColorSettingsPage {
|
||||
"-- line comment\n" +
|
||||
"{- nested \n" +
|
||||
"comment -}\n" +
|
||||
"data Bool = True | False";
|
||||
"data Bool = True | False\n" +
|
||||
"let l = [1,2] ";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
@ -18,16 +18,18 @@ package com.powertuple.intellij.haskell.highlighter;
|
||||
|
||||
import com.intellij.lexer.Lexer;
|
||||
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors;
|
||||
import com.intellij.openapi.editor.colors.CodeInsightColors;
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey;
|
||||
import com.intellij.openapi.fileTypes.SyntaxHighlighterBase;
|
||||
import com.intellij.psi.TokenType;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.powertuple.intellij.haskell.HaskellLexer;
|
||||
import com.powertuple.intellij.haskell.HaskellParserDefinition;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.intellij.openapi.editor.colors.TextAttributesKey.createTextAttributesKey;
|
||||
import static com.powertuple.intellij.haskell.HaskellParserDefinition.OPERATORS;
|
||||
import static com.powertuple.intellij.haskell.HaskellParserDefinition.RESERVED_IDS;
|
||||
import static com.powertuple.intellij.haskell.psi.HaskellTypes.*;
|
||||
|
||||
public class HaskellSyntaxHighlighter extends SyntaxHighlighterBase {
|
||||
@ -41,20 +43,7 @@ public class HaskellSyntaxHighlighter extends SyntaxHighlighterBase {
|
||||
public static final TextAttributesKey BRACE = createTextAttributesKey("HSL_BRACE", DefaultLanguageHighlighterColors.BRACES);
|
||||
public static final TextAttributesKey BRACKET = createTextAttributesKey("HS_BRACKET", DefaultLanguageHighlighterColors.BRACKETS);
|
||||
public static final TextAttributesKey SYMBOL = createTextAttributesKey("HS_SYMBOL", DefaultLanguageHighlighterColors.IDENTIFIER);
|
||||
public static final TextAttributesKey CONSTRUCTOR = createTextAttributesKey("HS_CONSTRUCTOR", DefaultLanguageHighlighterColors.FUNCTION_DECLARATION);
|
||||
|
||||
private static final TokenSet RESERVED_IDS = TokenSet.create(
|
||||
HS_CASE, HS_CLASS, HS_DATA, HS_DEFAULT, HS_DERIVING, HS_DO, HS_ELSE, HS_FOREIGN,
|
||||
HS_IF, HS_IMPORT, HS_IN, HS_INFIX, HS_INFIXL, HS_INFIXR, HS_INSTANCE, HS_LET,
|
||||
HS_MODULE, HS_NEWTYPE, HS_OF, HS_THEN, HS_TYPE, HS_WHERE, HS_UNDERSCORE
|
||||
);
|
||||
|
||||
private static final TokenSet RESERVED_OPS = TokenSet.create(
|
||||
HS_DOT_DOT, HS_COLON, HS_COLON_COLON, HS_DEFINED_BY, HS_SLASH, HS_VERTICAL_BAR,
|
||||
HS_LEFT_ARROW, HS_RIGHT_ARROW, HS_AT, HS_TILDE, HS_DOUBLE_RIGHT_ARROW
|
||||
);
|
||||
|
||||
private static final TokenSet SPECIAL_RESERVED_OPS = TokenSet.create(HS_AS, HS_QUALIFIED, HS_HIDING);
|
||||
public static final TextAttributesKey CONSTRUCTOR = createTextAttributesKey("HS_CONSTRUCTOR", CodeInsightColors.CONSTRUCTOR_CALL_ATTRIBUTES);
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
@ -80,7 +69,7 @@ public class HaskellSyntaxHighlighter extends SyntaxHighlighterBase {
|
||||
if (RESERVED_IDS.contains(type)) {
|
||||
return pack(KEYWORD);
|
||||
}
|
||||
if (RESERVED_OPS.contains(type) || SPECIAL_RESERVED_OPS.contains(type)) {
|
||||
if (OPERATORS.contains(type)) {
|
||||
return pack(OPERATOR);
|
||||
}
|
||||
if (type == HS_LEFT_PAREN || type == HS_RIGHT_PAREN) {
|
||||
|
@ -27,36 +27,14 @@ import org.jetbrains.annotations.NotNull;
|
||||
)
|
||||
public class HaskellSettings implements PersistentStateComponent<HaskellSettings.HaskellSettingsState> {
|
||||
|
||||
private HaskellSettingsState haskellSettingsState = new HaskellSettingsState();
|
||||
|
||||
@NotNull
|
||||
public static HaskellSettings getInstance() {
|
||||
HaskellSettings persisted = ServiceManager.getService(HaskellSettings.class);
|
||||
if (persisted == null) {
|
||||
persisted = new HaskellSettings();
|
||||
}
|
||||
|
||||
if (persisted.getState().ghcModPath == null) {
|
||||
persisted.getState().ghcModPath = "ghc-mod";
|
||||
}
|
||||
|
||||
if (persisted.getState().ghcModiPath == null) {
|
||||
persisted.getState().ghcModiPath = "ghc-modi";
|
||||
}
|
||||
|
||||
if (persisted.getState().hdocsPath == null) {
|
||||
persisted.getState().hdocsPath = "hdocs";
|
||||
}
|
||||
|
||||
return persisted;
|
||||
final HaskellSettings haskellSettings = ServiceManager.getService(HaskellSettings.class);
|
||||
return haskellSettings != null ? haskellSettings : new HaskellSettings();
|
||||
}
|
||||
|
||||
public static class HaskellSettingsState {
|
||||
public String ghcModPath;
|
||||
public String ghcModiPath;
|
||||
public String hdocsPath;
|
||||
}
|
||||
|
||||
private HaskellSettingsState haskellSettingsState = new HaskellSettingsState();
|
||||
|
||||
@NotNull
|
||||
public HaskellSettingsState getState() {
|
||||
return haskellSettingsState;
|
||||
@ -65,4 +43,10 @@ public class HaskellSettings implements PersistentStateComponent<HaskellSettings
|
||||
public void loadState(HaskellSettingsState haskellSettingsState) {
|
||||
this.haskellSettingsState = haskellSettingsState;
|
||||
}
|
||||
|
||||
public static class HaskellSettingsState {
|
||||
public String ghcModPath = "ghc-mod";
|
||||
public String ghcModiPath = "ghc-modi";
|
||||
public String hdocsPath = "hdocs";
|
||||
}
|
||||
}
|
||||
|
@ -16,35 +16,23 @@
|
||||
|
||||
package com.powertuple.intellij.haskell.annotator
|
||||
|
||||
import org.scalatest.{BeforeAndAfterEach, GivenWhenThen, Matchers, FunSpec}
|
||||
import com.intellij.execution.process.ProcessOutput
|
||||
import org.scalatest.{BeforeAndAfterEach, FunSpec, GivenWhenThen, Matchers}
|
||||
|
||||
class GhcModExternalAnnotatorSpec extends FunSpec with Matchers with GivenWhenThen with BeforeAndAfterEach {
|
||||
|
||||
val ghcModExternalAnnotator = new GhcModiExternalAnnotator
|
||||
val ghcModiExternalAnnotator = new GhcModiExternalAnnotator
|
||||
|
||||
describe("Parsing ghc-mod output") {
|
||||
Given("output of ghc-mod")
|
||||
val output = new ProcessOutput()
|
||||
output.appendStdout("file/path/HaskellFile.hs:1:11:parse error on input\n")
|
||||
output.appendStdout("file/path/HaskellFile.hs:12:5:another parse error on input")
|
||||
describe("Parsing ghc-modi output") {
|
||||
Given("output of ghc-modi")
|
||||
val output = "file/path/HaskellFile.hs:1:11:parse error on input"
|
||||
|
||||
When("parsed to problem list")
|
||||
val problems = ghcModExternalAnnotator.parseGhcModOutput(output)
|
||||
When("parsed to ghc-modi problem")
|
||||
val ghcModiProblem = ghcModiExternalAnnotator.parseGhcModiOutputLine(output)
|
||||
|
||||
Then("list should have size 2")
|
||||
problems should have size 2
|
||||
val problem1 = problems(0)
|
||||
val problem2 = problems(1)
|
||||
|
||||
And("contain right data")
|
||||
problem1.lineNr should equal(1)
|
||||
problem1.columnNr should equal(11)
|
||||
problem1.description should equal("parse error on input")
|
||||
|
||||
problem2.lineNr should equal(12)
|
||||
problem2.columnNr should equal(5)
|
||||
problem2.description should equal("another parse error on input")
|
||||
Then("it should contain right data")
|
||||
ghcModiProblem.lineNr should equal(1)
|
||||
ghcModiProblem.columnNr should equal(11)
|
||||
ghcModiProblem.description should equal("parse error on input")
|
||||
}
|
||||
|
||||
describe("Determine annotation offset when compile error") {
|
||||
@ -52,20 +40,20 @@ class GhcModExternalAnnotatorSpec extends FunSpec with Matchers with GivenWhenTh
|
||||
val someCode =
|
||||
"""
|
||||
|Some Haskell code
|
||||
|which does not
|
||||
| which does not
|
||||
|
|
||||
|com pile
|
||||
""".stripMargin
|
||||
|
||||
When("ghc-mod is executed")
|
||||
val ghcModResult = GhcModResult(Seq(GhcModProblem(4, 3, "something wrong")))
|
||||
val annotations = ghcModExternalAnnotator.createAnnotations(ghcModResult, someCode)
|
||||
When("ghc-modi is called")
|
||||
val ghcModiResult = GhcModiResult(Seq(GhcModiProblem(4, 3, "something wrong")))
|
||||
val annotations = ghcModiExternalAnnotator.createAnnotations(ghcModiResult, someCode)
|
||||
|
||||
Then("annotation holder should contain right annotation")
|
||||
annotations should have length 1
|
||||
|
||||
val annotation = annotations(0)
|
||||
annotation.asInstanceOf[ErrorAnnotation].textRange.getStartOffset should equal(36)
|
||||
annotation.asInstanceOf[ErrorAnnotation].textRange.getStartOffset should equal(38)
|
||||
}
|
||||
|
||||
describe("Determine annotation offset when compile warning") {
|
||||
@ -75,9 +63,9 @@ class GhcModExternalAnnotatorSpec extends FunSpec with Matchers with GivenWhenTh
|
||||
|some code
|
||||
""".stripMargin
|
||||
|
||||
When("ghc-mod is executed")
|
||||
val ghcModResult = GhcModResult(Seq(GhcModProblem(1, 1, "Warning: some warning")))
|
||||
val annotations = ghcModExternalAnnotator.createAnnotations(ghcModResult, someCode)
|
||||
When("ghc-modi is executed")
|
||||
val ghcModiResult = GhcModiResult(Seq(GhcModiProblem(1, 1, "Warning: some warning")))
|
||||
val annotations = ghcModiExternalAnnotator.createAnnotations(ghcModiResult, someCode)
|
||||
|
||||
Then("annotation holder should contain right annotation")
|
||||
annotations should have length 1
|
||||
|
Loading…
Reference in New Issue
Block a user