New: Code completion for local label definitions, suggesting undefined labels already referenced.
This commit is contained in:
parent
e0cdfef42b
commit
593719043e
@ -135,7 +135,7 @@ make it work with JUnit 5. Feel free to use the code (in package ```de.platon42.
|
|||||||
|
|
||||||
## Private TODO list
|
## Private TODO list
|
||||||
|
|
||||||
- code completion suggestion for unresolved local labels, global labels and symbols
|
- code completion suggestion for unresolved global labels and symbols
|
||||||
- support `include` directive
|
- support `include` directive
|
||||||
- support `opt` directive
|
- support `opt` directive
|
||||||
- suppression support via comments
|
- suppression support via comments
|
||||||
@ -149,6 +149,7 @@ make it work with JUnit 5. Feel free to use the code (in package ```de.platon42.
|
|||||||
- Enhancement: `opt` and several other directives (`printt`, `fail` etc.) no longer causes a syntax error when unquoted.
|
- Enhancement: `opt` and several other directives (`printt`, `fail` etc.) no longer causes a syntax error when unquoted.
|
||||||
- Enhancement: `include`, `incdir` and `incbin` and `output` with `<pathname>` quotes no longer cause syntax error.
|
- Enhancement: `include`, `incdir` and `incbin` and `output` with `<pathname>` quotes no longer cause syntax error.
|
||||||
- New: Files in `include` directives can be referenced and renamed/refactored.
|
- New: Files in `include` directives can be referenced and renamed/refactored.
|
||||||
|
- New: Code completion for local label definitions, suggesting undefined labels already referenced.
|
||||||
|
|
||||||
### V0.5 (06-Aug-21)
|
### V0.5 (06-Aug-21)
|
||||||
|
|
||||||
|
@ -62,6 +62,7 @@ patchPluginXml {
|
|||||||
<li>Enhancement: 'opt' and several other directives ('printt', 'fail' etc.) no longer causes a syntax error when unquoted.
|
<li>Enhancement: 'opt' and several other directives ('printt', 'fail' etc.) no longer causes a syntax error when unquoted.
|
||||||
<li>Enhancement: 'include', 'incdir' and 'incbin' and 'output' with '<pathname>' quotes no longer cause syntax error.
|
<li>Enhancement: 'include', 'incdir' and 'incbin' and 'output' with '<pathname>' quotes no longer cause syntax error.
|
||||||
<li>New: Files in 'include' directives can be referenced and renamed/refactored.
|
<li>New: Files in 'include' directives can be referenced and renamed/refactored.
|
||||||
|
<li>New: Code completion for local label definitions, suggesting undefined labels already referenced.
|
||||||
</ul>
|
</ul>
|
||||||
<h4>V0.5 (06-Aug-21)</h4>
|
<h4>V0.5 (06-Aug-21)</h4>
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -40,7 +40,7 @@ public class _M68kLexer implements FlexLexer {
|
|||||||
public static final int ASSIGNMENT = 12;
|
public static final int ASSIGNMENT = 12;
|
||||||
public static final int EXPR = 14;
|
public static final int EXPR = 14;
|
||||||
public static final int EXPR_OP = 16;
|
public static final int EXPR_OP = 16;
|
||||||
public static final int MACROCALL = 18;
|
public static final int PLAINPARAMS = 18;
|
||||||
public static final int WAITEOL = 20;
|
public static final int WAITEOL = 20;
|
||||||
public static final int MACRODEF = 22;
|
public static final int MACRODEF = 22;
|
||||||
public static final int MACROLINE = 24;
|
public static final int MACROLINE = 24;
|
||||||
@ -194,23 +194,23 @@ public class _M68kLexer implements FlexLexer {
|
|||||||
private static final int[] ZZ_ACTION = zzUnpackAction();
|
private static final int[] ZZ_ACTION = zzUnpackAction();
|
||||||
|
|
||||||
private static final String ZZ_ACTION_PACKED_0 =
|
private static final String ZZ_ACTION_PACKED_0 =
|
||||||
"\17\0\1\1\2\2\1\3\1\4\1\1\1\5\1\6" +
|
"\17\0\1\1\2\2\1\3\1\4\1\5\1\6\1\7" +
|
||||||
"\1\7\1\10\1\1\1\7\2\11\1\7\1\10\1\12" +
|
"\1\10\1\11\1\1\1\10\2\12\1\10\1\11\1\13" +
|
||||||
"\1\13\1\14\1\1\1\15\1\16\1\17\4\16\1\1" +
|
"\1\14\1\15\1\1\1\16\1\17\1\20\4\17\1\1" +
|
||||||
"\1\16\5\1\1\20\1\21\1\22\1\23\1\24\1\25" +
|
"\1\17\5\1\1\21\1\22\1\23\1\24\1\25\1\26" +
|
||||||
"\1\26\1\27\1\30\1\31\2\16\1\32\1\33\1\34" +
|
"\1\27\1\30\1\31\1\32\2\17\1\33\1\34\1\35" +
|
||||||
"\1\35\1\36\1\37\1\40\1\41\1\42\1\43\1\44" +
|
"\1\36\1\37\1\40\1\41\1\42\1\43\1\44\1\45" +
|
||||||
"\1\45\1\46\1\47\1\42\1\50\2\1\1\51\1\16" +
|
"\1\46\1\47\1\50\1\43\1\51\2\1\1\52\1\17" +
|
||||||
"\1\52\1\11\4\52\1\53\1\11\2\54\2\55\1\56" +
|
"\1\53\1\12\4\53\1\54\1\12\2\55\2\56\1\57" +
|
||||||
"\1\57\3\60\1\57\1\60\1\0\1\4\1\61\2\62" +
|
"\1\60\3\61\1\60\1\61\1\0\1\4\1\62\2\63" +
|
||||||
"\1\63\3\0\1\7\1\64\1\65\1\66\1\67\1\70" +
|
"\1\64\3\0\1\10\1\65\1\66\1\67\1\70\1\71" +
|
||||||
"\1\71\1\16\1\72\1\73\1\16\1\74\1\75\2\0" +
|
"\1\72\1\17\1\73\1\74\1\17\1\75\1\76\2\0" +
|
||||||
"\1\76\4\0\1\77\1\16\1\32\1\100\1\101\1\102" +
|
"\1\77\4\0\1\100\1\17\1\33\1\101\1\102\1\103" +
|
||||||
"\1\103\1\104\1\105\1\106\3\0\1\52\1\0\1\52" +
|
"\1\104\1\105\1\106\1\107\3\0\1\53\1\0\1\53" +
|
||||||
"\1\0\1\52\1\0\1\52\1\55\1\57\3\0\1\4" +
|
"\1\0\1\53\1\0\1\53\1\56\1\60\3\0\1\4" +
|
||||||
"\1\62\1\63\1\7\1\107\1\7\1\110\1\111\1\112" +
|
"\1\63\1\64\1\10\1\110\1\10\1\111\1\112\1\113" +
|
||||||
"\1\113\1\0\1\52\3\0\1\55\1\57\3\0\1\7" +
|
"\1\114\1\0\1\53\3\0\1\56\1\60\3\0\1\10" +
|
||||||
"\1\55\1\57\2\0\1\114\1\115\1\116\1\0\1\117";
|
"\1\56\1\60\2\0\1\115\1\116\1\117\1\0\1\120";
|
||||||
|
|
||||||
private static int[] zzUnpackAction() {
|
private static int[] zzUnpackAction() {
|
||||||
int[] result = new int[184];
|
int[] result = new int[184];
|
||||||
@ -814,14 +814,14 @@ public class _M68kLexer implements FlexLexer {
|
|||||||
return BAD_CHARACTER;
|
return BAD_CHARACTER;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 80:
|
case 81:
|
||||||
break;
|
break;
|
||||||
case 2: {
|
case 2: {
|
||||||
yybegin(YYINITIAL);
|
yybegin(YYINITIAL);
|
||||||
return WHITE_SPACE;
|
return WHITE_SPACE;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 81:
|
case 82:
|
||||||
break;
|
break;
|
||||||
case 3: {
|
case 3: {
|
||||||
yybegin(NOSOL);
|
yybegin(NOSOL);
|
||||||
@ -829,7 +829,7 @@ public class _M68kLexer implements FlexLexer {
|
|||||||
return WHITE_SPACE;
|
return WHITE_SPACE;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 82:
|
case 83:
|
||||||
break;
|
break;
|
||||||
case 4: {
|
case 4: {
|
||||||
yybegin(INSTRPART);
|
yybegin(INSTRPART);
|
||||||
@ -838,22 +838,30 @@ public class _M68kLexer implements FlexLexer {
|
|||||||
return GLOBAL_LABEL_DEF;
|
return GLOBAL_LABEL_DEF;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 83:
|
|
||||||
break;
|
|
||||||
case 5: {
|
|
||||||
yybegin(YYINITIAL);
|
|
||||||
return COMMENT;
|
|
||||||
}
|
|
||||||
// fall through
|
|
||||||
case 84:
|
case 84:
|
||||||
break;
|
break;
|
||||||
case 6: {
|
case 5: {
|
||||||
return WHITE_SPACE;
|
yybegin(INSTRPART);
|
||||||
|
eatOneWhitespace = false;
|
||||||
|
return LOCAL_LABEL_DEF;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 85:
|
case 85:
|
||||||
break;
|
break;
|
||||||
|
case 6: {
|
||||||
|
yybegin(YYINITIAL);
|
||||||
|
return COMMENT;
|
||||||
|
}
|
||||||
|
// fall through
|
||||||
|
case 86:
|
||||||
|
break;
|
||||||
case 7: {
|
case 7: {
|
||||||
|
return WHITE_SPACE;
|
||||||
|
}
|
||||||
|
// fall through
|
||||||
|
case 87:
|
||||||
|
break;
|
||||||
|
case 8: {
|
||||||
if (isAsmMnemonicWithSize(yytext())) {
|
if (isAsmMnemonicWithSize(yytext())) {
|
||||||
yybegin(ASMINSTR);
|
yybegin(ASMINSTR);
|
||||||
yypushback(2);
|
yypushback(2);
|
||||||
@ -868,7 +876,7 @@ public class _M68kLexer implements FlexLexer {
|
|||||||
return DATA_DIRECTIVE;
|
return DATA_DIRECTIVE;
|
||||||
}
|
}
|
||||||
if (isPlainDirective(yytext())) {
|
if (isPlainDirective(yytext())) {
|
||||||
yybegin(MACROCALL);
|
yybegin(PLAINPARAMS);
|
||||||
return OTHER_DIRECTIVE;
|
return OTHER_DIRECTIVE;
|
||||||
}
|
}
|
||||||
if (isOtherDirective(yytext())) {
|
if (isOtherDirective(yytext())) {
|
||||||
@ -878,498 +886,498 @@ public class _M68kLexer implements FlexLexer {
|
|||||||
return handleMacroMode(this);
|
return handleMacroMode(this);
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 86:
|
|
||||||
break;
|
|
||||||
case 8: {
|
|
||||||
return handleMacroMode(this);
|
|
||||||
}
|
|
||||||
// fall through
|
|
||||||
case 87:
|
|
||||||
break;
|
|
||||||
case 9: {
|
|
||||||
yybegin(YYINITIAL);
|
|
||||||
return EOL;
|
|
||||||
}
|
|
||||||
// fall through
|
|
||||||
case 88:
|
case 88:
|
||||||
break;
|
break;
|
||||||
case 10: {
|
case 9: {
|
||||||
return COLON;
|
return handleMacroMode(this);
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 89:
|
case 89:
|
||||||
break;
|
break;
|
||||||
case 11: {
|
case 10: {
|
||||||
yybegin(WAITEOL);
|
yybegin(YYINITIAL);
|
||||||
return COMMENT;
|
return EOL;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 90:
|
case 90:
|
||||||
break;
|
break;
|
||||||
case 12: {
|
case 11: {
|
||||||
startExpr(ASMOPS, ASMOPS_OP);
|
return COLON;
|
||||||
return WHITE_SPACE;
|
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 91:
|
case 91:
|
||||||
break;
|
break;
|
||||||
case 13: {
|
case 12: {
|
||||||
return handleEolCommentWhitespace(this);
|
yybegin(WAITEOL);
|
||||||
|
return COMMENT;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 92:
|
case 92:
|
||||||
break;
|
break;
|
||||||
case 14: {
|
case 13: {
|
||||||
yybegin(exprOpState);
|
startExpr(ASMOPS, ASMOPS_OP);
|
||||||
return SYMBOL;
|
return WHITE_SPACE;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 93:
|
case 93:
|
||||||
break;
|
break;
|
||||||
case 15: {
|
case 14: {
|
||||||
yybegin(exprOpState);
|
return handleEolCommentWhitespace(this);
|
||||||
return DECIMAL;
|
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 94:
|
case 94:
|
||||||
break;
|
break;
|
||||||
case 16: {
|
case 15: {
|
||||||
return SEPARATOR;
|
yybegin(exprOpState);
|
||||||
|
return SYMBOL;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 95:
|
case 95:
|
||||||
break;
|
break;
|
||||||
case 17: {
|
case 16: {
|
||||||
return HASH;
|
yybegin(exprOpState);
|
||||||
|
return DECIMAL;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 96:
|
case 96:
|
||||||
break;
|
break;
|
||||||
case 18: {
|
case 17: {
|
||||||
return OP_BITWISE_XOR;
|
return SEPARATOR;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 97:
|
case 97:
|
||||||
break;
|
break;
|
||||||
case 19: {
|
case 18: {
|
||||||
return ROUND_L;
|
return HASH;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 98:
|
case 98:
|
||||||
break;
|
break;
|
||||||
case 20: {
|
case 19: {
|
||||||
yybegin(exprOpState);
|
return OP_BITWISE_XOR;
|
||||||
return ROUND_R;
|
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 99:
|
case 99:
|
||||||
break;
|
break;
|
||||||
case 21: {
|
case 20: {
|
||||||
return OP_UNARY_NOT;
|
return ROUND_L;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 100:
|
case 100:
|
||||||
break;
|
break;
|
||||||
case 22: {
|
case 21: {
|
||||||
return OP_UNARY_COMPL;
|
yybegin(exprOpState);
|
||||||
|
return ROUND_R;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 101:
|
case 101:
|
||||||
break;
|
break;
|
||||||
case 23: {
|
case 22: {
|
||||||
return OP_PLUS;
|
return OP_UNARY_NOT;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 102:
|
case 102:
|
||||||
break;
|
break;
|
||||||
case 24: {
|
case 23: {
|
||||||
return OP_MINUS;
|
return OP_UNARY_COMPL;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 103:
|
case 103:
|
||||||
break;
|
break;
|
||||||
case 25: {
|
case 24: {
|
||||||
yybegin(exprOpState);
|
return OP_PLUS;
|
||||||
return CURRENT_PC_SYMBOL;
|
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 104:
|
case 104:
|
||||||
break;
|
break;
|
||||||
case 26: {
|
case 25: {
|
||||||
yybegin(exprState);
|
return OP_MINUS;
|
||||||
return OP_CMP_EQ;
|
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 105:
|
case 105:
|
||||||
break;
|
break;
|
||||||
case 27: {
|
case 26: {
|
||||||
yybegin(exprState);
|
yybegin(exprOpState);
|
||||||
return OP_AR_MOD;
|
return CURRENT_PC_SYMBOL;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 106:
|
case 106:
|
||||||
break;
|
break;
|
||||||
case 28: {
|
case 27: {
|
||||||
yybegin(exprState);
|
yybegin(exprState);
|
||||||
return OP_CMP_LT;
|
return OP_CMP_EQ;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 107:
|
case 107:
|
||||||
break;
|
break;
|
||||||
case 29: {
|
case 28: {
|
||||||
yybegin(exprState);
|
yybegin(exprState);
|
||||||
return OP_CMP_GT;
|
return OP_AR_MOD;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 108:
|
case 108:
|
||||||
break;
|
break;
|
||||||
case 30: {
|
case 29: {
|
||||||
yybegin(exprState);
|
yybegin(exprState);
|
||||||
return SEPARATOR;
|
return OP_CMP_LT;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 109:
|
case 109:
|
||||||
break;
|
break;
|
||||||
case 31: {
|
case 30: {
|
||||||
yybegin(exprState);
|
yybegin(exprState);
|
||||||
return OP_BITWISE_XOR;
|
return OP_CMP_GT;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 110:
|
case 110:
|
||||||
break;
|
break;
|
||||||
case 32: {
|
case 31: {
|
||||||
yybegin(exprState);
|
yybegin(exprState);
|
||||||
return ROUND_L;
|
return SEPARATOR;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 111:
|
case 111:
|
||||||
break;
|
break;
|
||||||
case 33: {
|
case 32: {
|
||||||
return ROUND_R;
|
yybegin(exprState);
|
||||||
|
return OP_BITWISE_XOR;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 112:
|
case 112:
|
||||||
break;
|
break;
|
||||||
case 34: {
|
case 33: {
|
||||||
yybegin(exprState);
|
yybegin(exprState);
|
||||||
return OP_BITWISE_OR;
|
return ROUND_L;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 113:
|
case 113:
|
||||||
break;
|
break;
|
||||||
case 35: {
|
case 34: {
|
||||||
yybegin(exprState);
|
return ROUND_R;
|
||||||
return OP_UNARY_COMPL;
|
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 114:
|
case 114:
|
||||||
break;
|
break;
|
||||||
case 36: {
|
case 35: {
|
||||||
yybegin(exprState);
|
yybegin(exprState);
|
||||||
return OP_PLUS;
|
return OP_BITWISE_OR;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 115:
|
case 115:
|
||||||
break;
|
break;
|
||||||
case 37: {
|
case 36: {
|
||||||
yybegin(exprState);
|
yybegin(exprState);
|
||||||
return OP_MINUS;
|
return OP_UNARY_COMPL;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 116:
|
case 116:
|
||||||
break;
|
break;
|
||||||
case 38: {
|
case 37: {
|
||||||
yybegin(exprState);
|
yybegin(exprState);
|
||||||
return OP_AR_MUL;
|
return OP_PLUS;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 117:
|
case 117:
|
||||||
break;
|
break;
|
||||||
case 39: {
|
case 38: {
|
||||||
yybegin(exprState);
|
yybegin(exprState);
|
||||||
return OP_BITWISE_AND;
|
return OP_MINUS;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 118:
|
case 118:
|
||||||
break;
|
break;
|
||||||
case 40: {
|
case 39: {
|
||||||
yybegin(exprState);
|
yybegin(exprState);
|
||||||
return OP_AR_DIV;
|
return OP_AR_MUL;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 119:
|
case 119:
|
||||||
break;
|
break;
|
||||||
case 41: {
|
case 40: {
|
||||||
startExpr(EXPR, EXPR_OP);
|
yybegin(exprState);
|
||||||
return OP_ASSIGN;
|
return OP_BITWISE_AND;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 120:
|
case 120:
|
||||||
break;
|
break;
|
||||||
case 42: {
|
case 41: {
|
||||||
return STRINGLIT;
|
yybegin(exprState);
|
||||||
|
return OP_AR_DIV;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 121:
|
case 121:
|
||||||
break;
|
break;
|
||||||
case 43: {
|
case 42: {
|
||||||
return COMMENT;
|
startExpr(EXPR, EXPR_OP);
|
||||||
|
return OP_ASSIGN;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 122:
|
case 122:
|
||||||
break;
|
break;
|
||||||
|
case 43: {
|
||||||
|
return STRINGLIT;
|
||||||
|
}
|
||||||
|
// fall through
|
||||||
|
case 123:
|
||||||
|
break;
|
||||||
case 44: {
|
case 44: {
|
||||||
|
return COMMENT;
|
||||||
|
}
|
||||||
|
// fall through
|
||||||
|
case 124:
|
||||||
|
break;
|
||||||
|
case 45: {
|
||||||
yybegin(MACROLINE);
|
yybegin(MACROLINE);
|
||||||
macroLines = 0;
|
macroLines = 0;
|
||||||
return WHITE_SPACE;
|
return WHITE_SPACE;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 123:
|
|
||||||
break;
|
|
||||||
case 45: {
|
|
||||||
return MACRO_NAME;
|
|
||||||
}
|
|
||||||
// fall through
|
|
||||||
case 124:
|
|
||||||
break;
|
|
||||||
case 46: {
|
|
||||||
yybegin(MACROWAITEOL);
|
|
||||||
return COMMENT;
|
|
||||||
}
|
|
||||||
// fall through
|
|
||||||
case 125:
|
case 125:
|
||||||
break;
|
break;
|
||||||
case 47: {
|
case 46: {
|
||||||
return MACRO_LINE;
|
return MACRO_NAME;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 126:
|
case 126:
|
||||||
break;
|
break;
|
||||||
case 48: {
|
case 47: {
|
||||||
return handleMacroLineEol(this);
|
yybegin(MACROWAITEOL);
|
||||||
|
return COMMENT;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 127:
|
case 127:
|
||||||
break;
|
break;
|
||||||
|
case 48: {
|
||||||
|
return MACRO_LINE;
|
||||||
|
}
|
||||||
|
// fall through
|
||||||
|
case 128:
|
||||||
|
break;
|
||||||
case 49: {
|
case 49: {
|
||||||
|
return handleMacroLineEol(this);
|
||||||
|
}
|
||||||
|
// fall through
|
||||||
|
case 129:
|
||||||
|
break;
|
||||||
|
case 50: {
|
||||||
yybegin(ASSIGNMENT);
|
yybegin(ASSIGNMENT);
|
||||||
eatOneWhitespace = true;
|
eatOneWhitespace = true;
|
||||||
yypushback(pushbackAssignment(yytext()));
|
yypushback(pushbackAssignment(yytext()));
|
||||||
return SYMBOLDEF;
|
return SYMBOLDEF;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 128:
|
case 130:
|
||||||
break;
|
break;
|
||||||
case 50: {
|
case 51: {
|
||||||
yybegin(INSTRPART);
|
yybegin(INSTRPART);
|
||||||
eatOneWhitespace = false;
|
eatOneWhitespace = false;
|
||||||
yypushback(pushbackLabelColons(yytext()));
|
yypushback(pushbackLabelColons(yytext()));
|
||||||
return LOCAL_LABEL_DEF;
|
return LOCAL_LABEL_DEF;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 129:
|
case 131:
|
||||||
break;
|
break;
|
||||||
case 51: {
|
case 52: {
|
||||||
yybegin(INSTRPART);
|
yybegin(INSTRPART);
|
||||||
yypushback(pushbackLabelColons(yytext()));
|
yypushback(pushbackLabelColons(yytext()));
|
||||||
return GLOBAL_LABEL_DEF;
|
return GLOBAL_LABEL_DEF;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 130:
|
|
||||||
break;
|
|
||||||
case 52: {
|
|
||||||
return OPSIZE_BS;
|
|
||||||
}
|
|
||||||
// fall through
|
|
||||||
case 131:
|
|
||||||
break;
|
|
||||||
case 53: {
|
|
||||||
return OPSIZE_W;
|
|
||||||
}
|
|
||||||
// fall through
|
|
||||||
case 132:
|
case 132:
|
||||||
break;
|
break;
|
||||||
case 54: {
|
case 53: {
|
||||||
return OPSIZE_L;
|
return OPSIZE_BS;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 133:
|
case 133:
|
||||||
break;
|
break;
|
||||||
case 55: {
|
case 54: {
|
||||||
yybegin(exprOpState);
|
return OPSIZE_W;
|
||||||
return AREG;
|
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 134:
|
case 134:
|
||||||
break;
|
break;
|
||||||
case 56: {
|
case 55: {
|
||||||
yybegin(exprOpState);
|
return OPSIZE_L;
|
||||||
return REG_SP;
|
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 135:
|
case 135:
|
||||||
break;
|
break;
|
||||||
case 57: {
|
case 56: {
|
||||||
yybegin(exprOpState);
|
yybegin(exprOpState);
|
||||||
return DREG;
|
return AREG;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 136:
|
case 136:
|
||||||
break;
|
break;
|
||||||
case 58: {
|
case 57: {
|
||||||
yybegin(exprOpState);
|
yybegin(exprOpState);
|
||||||
return REG_SR;
|
return REG_SP;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 137:
|
case 137:
|
||||||
break;
|
break;
|
||||||
case 59: {
|
case 58: {
|
||||||
yybegin(exprOpState);
|
yybegin(exprOpState);
|
||||||
return HEXADECIMAL;
|
return DREG;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 138:
|
case 138:
|
||||||
break;
|
break;
|
||||||
case 60: {
|
case 59: {
|
||||||
yybegin(exprOpState);
|
yybegin(exprOpState);
|
||||||
return BINARY;
|
return REG_SR;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 139:
|
case 139:
|
||||||
break;
|
break;
|
||||||
case 61: {
|
case 60: {
|
||||||
yybegin(exprOpState);
|
yybegin(exprOpState);
|
||||||
return OCTAL;
|
return HEXADECIMAL;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 140:
|
case 140:
|
||||||
break;
|
break;
|
||||||
case 62: {
|
case 61: {
|
||||||
yybegin(exprOpState);
|
yybegin(exprOpState);
|
||||||
return STRINGLIT;
|
return BINARY;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 141:
|
case 141:
|
||||||
break;
|
break;
|
||||||
case 63: {
|
case 62: {
|
||||||
yybegin(exprOpState);
|
yybegin(exprOpState);
|
||||||
return PC;
|
return OCTAL;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 142:
|
case 142:
|
||||||
break;
|
break;
|
||||||
case 64: {
|
case 63: {
|
||||||
yybegin(exprState);
|
yybegin(exprOpState);
|
||||||
return OP_CMP_LT_EQ;
|
return STRINGLIT;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 143:
|
case 143:
|
||||||
break;
|
break;
|
||||||
case 65: {
|
case 64: {
|
||||||
yybegin(exprState);
|
yybegin(exprOpState);
|
||||||
return OP_AR_SHIFT_L;
|
return PC;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 144:
|
case 144:
|
||||||
break;
|
break;
|
||||||
case 66: {
|
case 65: {
|
||||||
yybegin(exprState);
|
yybegin(exprState);
|
||||||
return OP_CMP_NOT_EQ;
|
return OP_CMP_LT_EQ;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 145:
|
case 145:
|
||||||
break;
|
break;
|
||||||
case 67: {
|
case 66: {
|
||||||
yybegin(exprState);
|
yybegin(exprState);
|
||||||
return OP_CMP_GT_EQ;
|
return OP_AR_SHIFT_L;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 146:
|
case 146:
|
||||||
break;
|
break;
|
||||||
case 68: {
|
case 67: {
|
||||||
yybegin(exprState);
|
yybegin(exprState);
|
||||||
return OP_AR_SHIFT_R;
|
return OP_CMP_NOT_EQ;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 147:
|
case 147:
|
||||||
break;
|
break;
|
||||||
case 69: {
|
case 68: {
|
||||||
yybegin(exprState);
|
yybegin(exprState);
|
||||||
return OP_LOGICAL_AND;
|
return OP_CMP_GT_EQ;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 148:
|
case 148:
|
||||||
break;
|
break;
|
||||||
case 70: {
|
case 69: {
|
||||||
yybegin(exprState);
|
yybegin(exprState);
|
||||||
return OP_LOGICAL_OR;
|
return OP_AR_SHIFT_R;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 149:
|
case 149:
|
||||||
break;
|
break;
|
||||||
|
case 70: {
|
||||||
|
yybegin(exprState);
|
||||||
|
return OP_LOGICAL_AND;
|
||||||
|
}
|
||||||
|
// fall through
|
||||||
|
case 150:
|
||||||
|
break;
|
||||||
case 71: {
|
case 71: {
|
||||||
|
yybegin(exprState);
|
||||||
|
return OP_LOGICAL_OR;
|
||||||
|
}
|
||||||
|
// fall through
|
||||||
|
case 151:
|
||||||
|
break;
|
||||||
|
case 72: {
|
||||||
yybegin(INSTRPART);
|
yybegin(INSTRPART);
|
||||||
yypushback(pushbackLabelColons(yytext()));
|
yypushback(pushbackLabelColons(yytext()));
|
||||||
return LOCAL_LABEL_DEF;
|
return LOCAL_LABEL_DEF;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 150:
|
case 152:
|
||||||
break;
|
break;
|
||||||
case 72: {
|
case 73: {
|
||||||
yybegin(exprOpState);
|
yybegin(exprOpState);
|
||||||
return REG_USP;
|
return REG_USP;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 151:
|
case 153:
|
||||||
break;
|
break;
|
||||||
case 73: {
|
case 74: {
|
||||||
yybegin(exprOpState);
|
yybegin(exprOpState);
|
||||||
return REG_CCR;
|
return REG_CCR;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 152:
|
case 154:
|
||||||
break;
|
break;
|
||||||
case 74: {
|
case 75: {
|
||||||
yybegin(exprOpState);
|
yybegin(exprOpState);
|
||||||
return REG_VBR;
|
return REG_VBR;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 153:
|
case 155:
|
||||||
break;
|
break;
|
||||||
case 75: {
|
case 76: {
|
||||||
startExpr(EXPR, EXPR_OP);
|
startExpr(EXPR, EXPR_OP);
|
||||||
return EQU;
|
return EQU;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 154:
|
case 156:
|
||||||
break;
|
break;
|
||||||
case 76: {
|
case 77: {
|
||||||
yybegin(MACRODEF);
|
yybegin(MACRODEF);
|
||||||
return MACRO_TAG;
|
return MACRO_TAG;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 155:
|
case 157:
|
||||||
break;
|
break;
|
||||||
case 77: {
|
case 78: {
|
||||||
return MACRO_TAG;
|
return MACRO_TAG;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 156:
|
case 158:
|
||||||
break;
|
break;
|
||||||
case 78: {
|
case 79: {
|
||||||
yybegin(MACROTERMINATION);
|
yybegin(MACROTERMINATION);
|
||||||
return MACRO_END_TAG;
|
return MACRO_END_TAG;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 157:
|
case 159:
|
||||||
break;
|
break;
|
||||||
case 79: {
|
case 80: {
|
||||||
yybegin(MACRODEF);
|
yybegin(MACRODEF);
|
||||||
yypushback(pushbackAfterFirstToken(yytext()));
|
yypushback(pushbackAfterFirstToken(yytext()));
|
||||||
return MACRO_NAME;
|
return MACRO_NAME;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case 158:
|
case 160:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
zzScanError(ZZ_NO_MATCH);
|
zzScanError(ZZ_NO_MATCH);
|
||||||
|
@ -1239,11 +1239,21 @@ public class M68kParser implements PsiParser, LightPsiParser {
|
|||||||
if (!recursion_guard_(b, l, "statement_recover")) return false;
|
if (!recursion_guard_(b, l, "statement_recover")) return false;
|
||||||
boolean r;
|
boolean r;
|
||||||
Marker m = enter_section_(b, l, _NOT_);
|
Marker m = enter_section_(b, l, _NOT_);
|
||||||
r = !consumeToken(b, EOL);
|
r = !statement_recover_0(b, l + 1);
|
||||||
exit_section_(b, l, m, r, false, null);
|
exit_section_(b, l, m, r, false, null);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// (EOL)
|
||||||
|
private static boolean statement_recover_0(PsiBuilder b, int l) {
|
||||||
|
if (!recursion_guard_(b, l, "statement_recover_0")) return false;
|
||||||
|
boolean r;
|
||||||
|
Marker m = enter_section_(b);
|
||||||
|
r = consumeTokenFast(b, EOL);
|
||||||
|
exit_section_(b, m, null, r);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
/* ********************************************************** */
|
/* ********************************************************** */
|
||||||
// Expression root: expr
|
// Expression root: expr
|
||||||
// Operator priority table:
|
// Operator priority table:
|
||||||
|
@ -79,18 +79,12 @@ class M68kRegisterFlowDocumentationProvider : AbstractDocumentationProvider() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
backtrace.addAll(analyseFlow(register, missingBits, true, initialStatement, linesLimit) {
|
backtrace.addAll(analyseFlow(register, missingBits, true, initialStatement, linesLimit) {
|
||||||
PsiTreeUtil.getPrevSiblingOfType(
|
PsiTreeUtil.getPrevSiblingOfType(it, M68kStatement::class.java)
|
||||||
it,
|
|
||||||
M68kStatement::class.java
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
backtrace.reverse()
|
backtrace.reverse()
|
||||||
val traceBits = (cursorRwm or (cursorRwm ushr RWM_MODIFY_SHIFT) or (cursorRwm ushr RWM_READ_SHIFT)) and RWM_SIZE_MASK
|
val traceBits = (cursorRwm or (cursorRwm ushr RWM_MODIFY_SHIFT) or (cursorRwm ushr RWM_READ_SHIFT)) and RWM_SIZE_MASK
|
||||||
backtrace.addAll(analyseFlow(register, traceBits, false, initialStatement, linesLimit) {
|
backtrace.addAll(analyseFlow(register, traceBits, false, initialStatement, linesLimit) {
|
||||||
PsiTreeUtil.getNextSiblingOfType(
|
PsiTreeUtil.getNextSiblingOfType(it, M68kStatement::class.java)
|
||||||
it,
|
|
||||||
M68kStatement::class.java
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
val statementRows = HtmlBuilder()
|
val statementRows = HtmlBuilder()
|
||||||
@ -113,7 +107,7 @@ class M68kRegisterFlowDocumentationProvider : AbstractDocumentationProvider() {
|
|||||||
var currStatement = startingStatement
|
var currStatement = startingStatement
|
||||||
val statementLines = ArrayList<HtmlChunk>()
|
val statementLines = ArrayList<HtmlChunk>()
|
||||||
val rn = register.regname
|
val rn = register.regname
|
||||||
var addAbrevDots = false
|
var addAbbrevDots = false
|
||||||
var lines = 0
|
var lines = 0
|
||||||
while (missingBits > 0) {
|
while (missingBits > 0) {
|
||||||
val globalLabel = PsiTreeUtil.findChildOfType(currStatement, M68kGlobalLabel::class.java)
|
val globalLabel = PsiTreeUtil.findChildOfType(currStatement, M68kGlobalLabel::class.java)
|
||||||
@ -127,17 +121,17 @@ class M68kRegisterFlowDocumentationProvider : AbstractDocumentationProvider() {
|
|||||||
currStatement = direction.invoke(currStatement) ?: break
|
currStatement = direction.invoke(currStatement) ?: break
|
||||||
val currAsmInstruction = PsiTreeUtil.getChildOfType(currStatement, M68kAsmInstruction::class.java) ?: continue
|
val currAsmInstruction = PsiTreeUtil.getChildOfType(currStatement, M68kAsmInstruction::class.java) ?: continue
|
||||||
if (checkIfInstructionUsesRegister(currAsmInstruction, register)) {
|
if (checkIfInstructionUsesRegister(currAsmInstruction, register)) {
|
||||||
if (addAbrevDots) {
|
if (addAbbrevDots) {
|
||||||
++lines
|
++lines
|
||||||
statementLines.add(createAbbreviationDots())
|
statementLines.add(createAbbreviationDots())
|
||||||
}
|
}
|
||||||
if (++lines > linesLimit) {
|
if (++lines > linesLimit) {
|
||||||
if (!addAbrevDots) {
|
if (!addAbbrevDots) {
|
||||||
statementLines.add(createAbbreviationDots())
|
statementLines.add(createAbbreviationDots())
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
addAbrevDots = false
|
addAbbrevDots = false
|
||||||
val (_, currAdrMode) = findExactIsaDataAndAllowedAdrModeForInstruction(currAsmInstruction) ?: continue
|
val (_, currAdrMode) = findExactIsaDataAndAllowedAdrModeForInstruction(currAsmInstruction) ?: continue
|
||||||
|
|
||||||
val localLabelName = PsiTreeUtil.findChildOfType(currStatement, M68kLocalLabel::class.java)?.name ?: " "
|
val localLabelName = PsiTreeUtil.findChildOfType(currStatement, M68kLocalLabel::class.java)?.name ?: " "
|
||||||
@ -163,7 +157,7 @@ class M68kRegisterFlowDocumentationProvider : AbstractDocumentationProvider() {
|
|||||||
.children(lineBuilder.wrapWith(DocumentationMarkup.SECTION_CONTENT_CELL))
|
.children(lineBuilder.wrapWith(DocumentationMarkup.SECTION_CONTENT_CELL))
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
addAbrevDots = true
|
addAbbrevDots = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return statementLines
|
return statementLines
|
||||||
|
@ -55,7 +55,7 @@ object LexerUtil {
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun handleMacroMode(lexer: _M68kLexer): IElementType {
|
fun handleMacroMode(lexer: _M68kLexer): IElementType {
|
||||||
if (lexer.lexerPrefs.macroParametersUnparsed) {
|
if (lexer.lexerPrefs.macroParametersUnparsed) {
|
||||||
lexer.yybegin(_M68kLexer.MACROCALL)
|
lexer.yybegin(_M68kLexer.PLAINPARAMS)
|
||||||
} else {
|
} else {
|
||||||
lexer.yybegin(_M68kLexer.ASMOPS)
|
lexer.yybegin(_M68kLexer.ASMOPS)
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package de.platon42.intellij.plugins.m68k.lexer;
|
package de.platon42.intellij.plugins.m68k.lexer;
|
||||||
|
|
||||||
|
import com.intellij.lexer.FlexLexer;
|
||||||
import com.intellij.psi.tree.IElementType;
|
import com.intellij.psi.tree.IElementType;
|
||||||
|
|
||||||
import static com.intellij.psi.TokenType.BAD_CHARACTER;
|
import static com.intellij.psi.TokenType.BAD_CHARACTER;
|
||||||
@ -101,6 +102,7 @@ PLAIN_MACRO_LINE=[^;\r\n]+
|
|||||||
{MACRO_DEF_LEFT} { yybegin(MACRODEF); yypushback(pushbackAfterFirstToken(yytext())); return MACRO_NAME; }
|
{MACRO_DEF_LEFT} { yybegin(MACRODEF); yypushback(pushbackAfterFirstToken(yytext())); return MACRO_NAME; }
|
||||||
{LOCAL_LABEL} { yybegin(INSTRPART); eatOneWhitespace = false; yypushback(pushbackLabelColons(yytext())); return LOCAL_LABEL_DEF; }
|
{LOCAL_LABEL} { yybegin(INSTRPART); eatOneWhitespace = false; yypushback(pushbackLabelColons(yytext())); return LOCAL_LABEL_DEF; }
|
||||||
{GLOBAL_LABEL} { yybegin(INSTRPART); eatOneWhitespace = false; yypushback(pushbackLabelColons(yytext())); return GLOBAL_LABEL_DEF; }
|
{GLOBAL_LABEL} { yybegin(INSTRPART); eatOneWhitespace = false; yypushback(pushbackLabelColons(yytext())); return GLOBAL_LABEL_DEF; }
|
||||||
|
"." { yybegin(INSTRPART); eatOneWhitespace = false; return LOCAL_LABEL_DEF; }
|
||||||
}
|
}
|
||||||
|
|
||||||
<NOSOL> {
|
<NOSOL> {
|
||||||
|
@ -123,9 +123,9 @@ private line ::= !<<eof>> (MacroDefinition | statement) (<<eof>>|EOL)
|
|||||||
statement ::= (Assignment
|
statement ::= (Assignment
|
||||||
| PreprocessorDirective
|
| PreprocessorDirective
|
||||||
| LabelInsts)
|
| LabelInsts)
|
||||||
{pin=1 recoverWhile=statement_recover};
|
{pin = 1 recoverWhile = statement_recover}
|
||||||
|
|
||||||
private statement_recover ::= !(EOL)
|
private statement_recover ::= !(EOL) { consumeTokenMethod = "consumeTokenFast" }
|
||||||
|
|
||||||
SymbolDefinition ::= SYMBOLDEF {
|
SymbolDefinition ::= SYMBOLDEF {
|
||||||
implements = "de.platon42.intellij.plugins.m68k.psi.M68kNamedElement"
|
implements = "de.platon42.intellij.plugins.m68k.psi.M68kNamedElement"
|
||||||
|
@ -62,11 +62,4 @@ object M68kAddressModeUtil {
|
|||||||
else -> throw IllegalArgumentException("Unknown addressing mode $addressingMode")
|
else -> throw IllegalArgumentException("Unknown addressing mode $addressingMode")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun mergeReadWriteModifyRegisters(regset: Set<Pair<Register, Int>>): Set<Pair<Register, Int>> {
|
|
||||||
if (regset.size <= 1) return regset
|
|
||||||
return regset.groupBy({ it.first }) { it.second }
|
|
||||||
.map { it.key to if (it.value.size == 1) it.value.single() else it.value.reduce(Int::or) }
|
|
||||||
.toSet()
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -29,7 +29,7 @@ object M68kPsiImplUtil {
|
|||||||
|
|
||||||
// Local Label
|
// Local Label
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun getName(element: M68kLocalLabel): String? = element.firstChild.text
|
fun getName(element: M68kLocalLabel): String = element.firstChild?.text ?: ""
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun setName(element: M68kLocalLabel, name: String): PsiElement {
|
fun setName(element: M68kLocalLabel, name: String): PsiElement {
|
||||||
|
@ -0,0 +1,68 @@
|
|||||||
|
package de.platon42.intellij.plugins.m68k.refs
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.completion.*
|
||||||
|
import com.intellij.codeInsight.lookup.LookupElementBuilder
|
||||||
|
import com.intellij.patterns.PlatformPatterns
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
|
import com.intellij.util.ProcessingContext
|
||||||
|
import de.platon42.intellij.plugins.m68k.psi.*
|
||||||
|
|
||||||
|
class M68kLocalLabelDefCompletionContributor : CompletionContributor() {
|
||||||
|
|
||||||
|
init {
|
||||||
|
extend(
|
||||||
|
CompletionType.BASIC,
|
||||||
|
PlatformPatterns.or(PlatformPatterns.psiElement(M68kTypes.LOCAL_LABEL_DEF), PlatformPatterns.psiElement(M68kTypes.GLOBAL_LABEL_DEF)),
|
||||||
|
object : CompletionProvider<CompletionParameters>() {
|
||||||
|
override fun addCompletions(parameters: CompletionParameters, context: ProcessingContext, resultSet: CompletionResultSet) {
|
||||||
|
var topLevelElement = parameters.originalFile.findElementAt(parameters.offset)
|
||||||
|
while (topLevelElement?.parent !is M68kFile) {
|
||||||
|
topLevelElement = topLevelElement?.parent ?: return
|
||||||
|
}
|
||||||
|
// TODO find out if we can cache this somehow
|
||||||
|
val affectedStatements = ArrayList<M68kStatement>()
|
||||||
|
val definedLocalLabels = HashSet<String>()
|
||||||
|
val referencedLocalLabels = HashSet<String>()
|
||||||
|
findUndefinedLocalLabels(topLevelElement, affectedStatements, definedLocalLabels, referencedLocalLabels) {
|
||||||
|
PsiTreeUtil.getNextSiblingOfType(it, M68kStatement::class.java)
|
||||||
|
}
|
||||||
|
findUndefinedLocalLabels(topLevelElement, affectedStatements, definedLocalLabels, referencedLocalLabels) {
|
||||||
|
PsiTreeUtil.getPrevSiblingOfType(it, M68kStatement::class.java)
|
||||||
|
}
|
||||||
|
referencedLocalLabels.removeAll(definedLocalLabels)
|
||||||
|
resultSet.addAllElements(
|
||||||
|
if (parameters.originalPosition?.text == ".") {
|
||||||
|
referencedLocalLabels.map { LookupElementBuilder.create(it.removePrefix(".")) }
|
||||||
|
} else {
|
||||||
|
referencedLocalLabels.map(LookupElementBuilder::create)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun findUndefinedLocalLabels(
|
||||||
|
topLevelElement: PsiElement,
|
||||||
|
affectedStatements: MutableList<M68kStatement>,
|
||||||
|
definedLocalLabels: MutableSet<String>,
|
||||||
|
referencedLocalLabels: MutableSet<String>,
|
||||||
|
direction: (topLevelElement: PsiElement) -> M68kStatement?
|
||||||
|
) {
|
||||||
|
var currStatement = topLevelElement
|
||||||
|
while (true) {
|
||||||
|
currStatement = direction.invoke(currStatement) ?: break
|
||||||
|
val globalLabel = PsiTreeUtil.findChildOfType(currStatement, M68kGlobalLabel::class.java)
|
||||||
|
if (globalLabel != null) break
|
||||||
|
affectedStatements.add(currStatement)
|
||||||
|
val localLabel = PsiTreeUtil.findChildOfType(currStatement, M68kLocalLabel::class.java)
|
||||||
|
if (localLabel != null) definedLocalLabels.add(localLabel.name!!)
|
||||||
|
val symbolReferences = PsiTreeUtil.findChildrenOfAnyType(currStatement, M68kSymbolReference::class.java)
|
||||||
|
if (symbolReferences.isNotEmpty()) {
|
||||||
|
referencedLocalLabels.addAll(
|
||||||
|
symbolReferences.filter(M68kSymbolReference::isLocalLabelRef).map(M68kSymbolReference::getSymbolName)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -24,6 +24,7 @@
|
|||||||
<colorSettingsPage implementation="de.platon42.intellij.plugins.m68k.syntax.M68kColorSettingsPage"/>
|
<colorSettingsPage implementation="de.platon42.intellij.plugins.m68k.syntax.M68kColorSettingsPage"/>
|
||||||
<completion.contributor language="MC68000" implementationClass="de.platon42.intellij.plugins.m68k.asm.M68kMnemonicCompletionContributor"/>
|
<completion.contributor language="MC68000" implementationClass="de.platon42.intellij.plugins.m68k.asm.M68kMnemonicCompletionContributor"/>
|
||||||
<completion.contributor language="MC68000" implementationClass="de.platon42.intellij.plugins.m68k.refs.M68kGlobalLabelSymbolCompletionContributor"/>
|
<completion.contributor language="MC68000" implementationClass="de.platon42.intellij.plugins.m68k.refs.M68kGlobalLabelSymbolCompletionContributor"/>
|
||||||
|
<completion.contributor language="MC68000" implementationClass="de.platon42.intellij.plugins.m68k.refs.M68kLocalLabelDefCompletionContributor"/>
|
||||||
<completion.contributor language="MC68000" implementationClass="de.platon42.intellij.plugins.m68k.refs.M68kMacroCallCompletionContributor"/>
|
<completion.contributor language="MC68000" implementationClass="de.platon42.intellij.plugins.m68k.refs.M68kMacroCallCompletionContributor"/>
|
||||||
<lang.braceMatcher language="MC68000" implementationClass="de.platon42.intellij.plugins.m68k.syntax.M68kPairedBraceMatcher"/>
|
<lang.braceMatcher language="MC68000" implementationClass="de.platon42.intellij.plugins.m68k.syntax.M68kPairedBraceMatcher"/>
|
||||||
<lang.quoteHandler language="MC68000" implementationClass="de.platon42.intellij.plugins.m68k.M68kStringQuoteHandler"/>
|
<lang.quoteHandler language="MC68000" implementationClass="de.platon42.intellij.plugins.m68k.M68kStringQuoteHandler"/>
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
package de.platon42.intellij.plugins.m68k.refs
|
||||||
|
|
||||||
|
import com.intellij.testFramework.fixtures.CodeInsightTestFixture
|
||||||
|
import de.platon42.intellij.jupiter.LightCodeInsightExtension
|
||||||
|
import de.platon42.intellij.jupiter.MyFixture
|
||||||
|
import de.platon42.intellij.jupiter.TestDataPath
|
||||||
|
import de.platon42.intellij.jupiter.TestDataSubPath
|
||||||
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith
|
||||||
|
|
||||||
|
@TestDataPath("src/test/resources/references")
|
||||||
|
@TestDataSubPath("completion")
|
||||||
|
@ExtendWith(LightCodeInsightExtension::class)
|
||||||
|
internal class M68kLocalLabelDefCompletionContributorTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
internal fun completion_shows_undefined_local_labels_without_dot_prefix(@MyFixture myFixture: CodeInsightTestFixture) {
|
||||||
|
myFixture.configureByText(
|
||||||
|
"completeme.asm", """
|
||||||
|
main
|
||||||
|
.loop
|
||||||
|
dbra d0,.loop
|
||||||
|
dbra d1,.loop2
|
||||||
|
.<caret>
|
||||||
|
bra.s .foo
|
||||||
|
rts
|
||||||
|
|
||||||
|
coolsubroutine
|
||||||
|
bra.s .narf
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
myFixture.completeBasic()
|
||||||
|
assertThat(myFixture.lookupElementStrings).containsExactlyInAnyOrder("loop2", "foo")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
internal fun completion_shows_undefined_local_labels_even_without_dot(@MyFixture myFixture: CodeInsightTestFixture) {
|
||||||
|
myFixture.configureByText(
|
||||||
|
"completeme.asm", """
|
||||||
|
main
|
||||||
|
.loop
|
||||||
|
dbra d0,.loop
|
||||||
|
dbra d1,.loop2
|
||||||
|
<caret>
|
||||||
|
bra.s .foo
|
||||||
|
bra.s bar$
|
||||||
|
rts
|
||||||
|
|
||||||
|
coolsubroutine
|
||||||
|
bra.s .narf
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
myFixture.completeBasic()
|
||||||
|
assertThat(myFixture.lookupElementStrings).containsExactlyInAnyOrder(".loop2", ".foo", "bar$")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user