mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-02 20:04:37 +00:00
AS1/2 variable highlighter improvements
This commit is contained in:
@@ -46,7 +46,7 @@ public class ActionScript2VariableParser {
|
||||
* Swf version
|
||||
*/
|
||||
private final int swfVersion;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@@ -57,7 +57,7 @@ public class ActionScript2VariableParser {
|
||||
}
|
||||
|
||||
private final boolean debugMode = false;
|
||||
|
||||
|
||||
private void commands(boolean inFunction, boolean inMethod, int forinlevel, boolean inTellTarget, List<VariableOrScope> variables, Reference<Boolean> hasEval) throws IOException, ActionParseException, InterruptedException {
|
||||
if (debugMode) {
|
||||
System.out.println("commands:");
|
||||
@@ -67,22 +67,29 @@ public class ActionScript2VariableParser {
|
||||
}
|
||||
if (debugMode) {
|
||||
System.out.println("/commands");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean type(List<VariableOrScope> variables) throws IOException, ActionParseException, InterruptedException {
|
||||
private String type(boolean definition, List<VariableOrScope> variables) throws IOException, ActionParseException, InterruptedException {
|
||||
ParsedSymbol s = lex();
|
||||
expectedIdentifier(s, lexer.yyline());
|
||||
ParsedSymbol lastIdent = s;
|
||||
Variable vret = new Variable(false, s.value.toString(), s.position);
|
||||
variables.add(vret);
|
||||
String ret = s.value.toString();
|
||||
s = lex();
|
||||
while (s.type == SymbolType.DOT) {
|
||||
ret += ".";
|
||||
s = lex();
|
||||
expectedIdentifier(s, lexer.yyline());
|
||||
lastIdent = s;
|
||||
ret += s.value.toString();
|
||||
s = lex();
|
||||
}
|
||||
lexer.pushback(s);
|
||||
return true;
|
||||
Type t = new Type(definition, ret, lastIdent.position);
|
||||
variables.add(t);
|
||||
return ret;
|
||||
}
|
||||
|
||||
private void expected(ParsedSymbol symb, int line, Object... expected) throws IOException, ActionParseException {
|
||||
@@ -157,7 +164,7 @@ public class ActionScript2VariableParser {
|
||||
paramPositions.add(s.position);
|
||||
s = lex();
|
||||
if (s.type == SymbolType.COLON) {
|
||||
type(variables);
|
||||
type(false, variables);
|
||||
s = lex();
|
||||
}
|
||||
|
||||
@@ -168,13 +175,16 @@ public class ActionScript2VariableParser {
|
||||
List<VariableOrScope> subvariables = new ArrayList<>();
|
||||
Reference<Boolean> subHasEval = new Reference<>(false);
|
||||
|
||||
if (!functionName.isEmpty()) {
|
||||
variables.add(new Variable(true, functionName, functionNamePosition));
|
||||
}
|
||||
|
||||
for (int i = 0; i < paramNames.size(); i++) {
|
||||
subvariables.add(new Variable(true, paramNames.get(i), paramPositions.get(i)));
|
||||
}
|
||||
|
||||
if (withBody) {
|
||||
expectedType(SymbolType.CURLY_OPEN);
|
||||
//body = ;
|
||||
commands(true, isMethod, 0, inTellTarget, subvariables, subHasEval);
|
||||
expectedType(SymbolType.CURLY_CLOSE);
|
||||
}
|
||||
@@ -184,18 +194,20 @@ public class ActionScript2VariableParser {
|
||||
}
|
||||
|
||||
variables.add(new FunctionScope(subvariables));
|
||||
if (!functionName.isEmpty()) {
|
||||
variables.add(new Variable(true, functionName, functionNamePosition));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean traits(boolean isInterface, List<VariableOrScope> variables, boolean inTellTarget, Reference<Boolean> hasEval) throws IOException, ActionParseException, InterruptedException {
|
||||
private boolean traits(boolean isInterface, String className, List<VariableOrScope> variables, boolean inTellTarget, Reference<Boolean> hasEval) throws IOException, ActionParseException, InterruptedException {
|
||||
|
||||
ParsedSymbol s;
|
||||
|
||||
looptrait:
|
||||
while (true) {
|
||||
boolean isStatic = false;
|
||||
s = lex();
|
||||
while (s.isType(SymbolType.STATIC, SymbolType.PUBLIC, SymbolType.PRIVATE)) {
|
||||
if (s.type == SymbolType.STATIC) {
|
||||
isStatic = true;
|
||||
}
|
||||
s = lex();
|
||||
}
|
||||
switch (s.type) {
|
||||
@@ -209,17 +221,18 @@ public class ActionScript2VariableParser {
|
||||
}
|
||||
|
||||
expectedIdentifier(s, lexer.yyline());
|
||||
|
||||
if (!isInterface) {
|
||||
function(!isInterface, "", -1, true, variables, inTellTarget, hasEval);
|
||||
function(!isInterface, isStatic ? className + "." + s.value.toString() : "this." + s.value.toString(), isStatic ? -1 : s.position, true, variables, inTellTarget, hasEval);
|
||||
}
|
||||
break;
|
||||
case VAR:
|
||||
s = lex();
|
||||
expectedIdentifier(s, lexer.yyline());
|
||||
//String ident = s.value.toString();
|
||||
variables.add(new Variable(true, isStatic ? className + "." + s.value.toString() : "this." + s.value.toString(), s.position));
|
||||
s = lex();
|
||||
if (s.type == SymbolType.COLON) {
|
||||
type(variables);
|
||||
type(false, variables);
|
||||
s = lex();
|
||||
}
|
||||
if (s.type == SymbolType.ASSIGN) {
|
||||
@@ -245,7 +258,7 @@ public class ActionScript2VariableParser {
|
||||
System.out.println("expressionCommands:");
|
||||
}
|
||||
boolean ret;
|
||||
|
||||
|
||||
switch (s.type) {
|
||||
case DUPLICATEMOVIECLIP:
|
||||
case FSCOMMAND:
|
||||
@@ -293,7 +306,7 @@ public class ActionScript2VariableParser {
|
||||
variables.add(new Variable(false, (String) s.value, s.position));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
switch (s.type) {
|
||||
case DUPLICATEMOVIECLIP:
|
||||
expectedType(SymbolType.PARENT_OPEN);
|
||||
@@ -436,7 +449,7 @@ public class ActionScript2VariableParser {
|
||||
expression(inFunction, inMethod, inTellTarget, true, variables, false, hasEval);
|
||||
expectedType(SymbolType.COMMA);
|
||||
expression(inFunction, inMethod, inTellTarget, true, variables, false, hasEval);
|
||||
expectedType(SymbolType.PARENT_CLOSE);
|
||||
expectedType(SymbolType.PARENT_CLOSE);
|
||||
ret = true;
|
||||
break;
|
||||
case LOADVARIABLES:
|
||||
@@ -498,7 +511,7 @@ public class ActionScript2VariableParser {
|
||||
}
|
||||
} else {
|
||||
lexer.pushback(s);
|
||||
|
||||
|
||||
}
|
||||
} else {
|
||||
lexer.pushback(s);
|
||||
@@ -724,35 +737,39 @@ public class ActionScript2VariableParser {
|
||||
ret = true;
|
||||
break;
|
||||
case CLASS:
|
||||
type(variables);
|
||||
String className = type(true, variables);
|
||||
s = lex();
|
||||
if (s.type == SymbolType.EXTENDS) {
|
||||
type(variables);
|
||||
type(false, variables);
|
||||
s = lex();
|
||||
}
|
||||
if (s.type == SymbolType.IMPLEMENTS) {
|
||||
do {
|
||||
type(variables);
|
||||
type(false, variables);
|
||||
s = lex();
|
||||
} while (s.type == SymbolType.COMMA);
|
||||
}
|
||||
expected(s, lexer.yyline(), SymbolType.CURLY_OPEN);
|
||||
traits(false, variables, inTellTarget, hasEval);
|
||||
List<VariableOrScope> subVariables = new ArrayList<>();
|
||||
traits(false, className, subVariables, inTellTarget, hasEval);
|
||||
ClassScope cs = new ClassScope(subVariables);
|
||||
variables.add(cs);
|
||||
|
||||
expectedType(SymbolType.CURLY_CLOSE);
|
||||
ret = true;
|
||||
break;
|
||||
case INTERFACE:
|
||||
type(variables);
|
||||
String interfaceName = type(true, variables);
|
||||
s = lex();
|
||||
|
||||
if (s.type == SymbolType.EXTENDS) {
|
||||
do {
|
||||
type(variables);
|
||||
type(false, variables);
|
||||
s = lex();
|
||||
} while (s.type == SymbolType.COMMA);
|
||||
}
|
||||
expected(s, lexer.yyline(), SymbolType.CURLY_OPEN);
|
||||
traits(true, variables, inTellTarget, hasEval);
|
||||
traits(true, interfaceName, variables, inTellTarget, hasEval);
|
||||
expectedType(SymbolType.CURLY_CLOSE);
|
||||
ret = true;
|
||||
break;
|
||||
@@ -768,7 +785,7 @@ public class ActionScript2VariableParser {
|
||||
int varPosition = s.position;
|
||||
s = lex();
|
||||
if (s.type == SymbolType.COLON) {
|
||||
type(variables);
|
||||
type(false, variables);
|
||||
s = lex();
|
||||
//TODO: handle value type
|
||||
}
|
||||
@@ -928,12 +945,12 @@ public class ActionScript2VariableParser {
|
||||
expectedIdentifier(si, lexer.yyline(), SymbolType.STRING);
|
||||
s = lex();
|
||||
if (s.type == SymbolType.COLON) {
|
||||
type(variables);
|
||||
type(false, variables);
|
||||
} else {
|
||||
lexer.pushback(s);
|
||||
}
|
||||
expectedType(SymbolType.PARENT_CLOSE);
|
||||
|
||||
|
||||
List<VariableOrScope> subvariables = new ArrayList<>();
|
||||
|
||||
command(inFunction, inMethod, forinlevel, inTellTarget, subvariables, hasEval);
|
||||
@@ -1124,7 +1141,7 @@ public class ActionScript2VariableParser {
|
||||
case ASSIGN_SHIFT_LEFT:
|
||||
case ASSIGN_SHIFT_RIGHT:
|
||||
case ASSIGN_USHIFT_RIGHT:
|
||||
case ASSIGN_XOR:
|
||||
case ASSIGN_XOR:
|
||||
lhs = true;
|
||||
break;
|
||||
case IDENTIFIER:
|
||||
@@ -1148,7 +1165,7 @@ public class ActionScript2VariableParser {
|
||||
}
|
||||
return lhs;
|
||||
}
|
||||
|
||||
|
||||
private int brackets(boolean inFunction, boolean inMethod, boolean inTellTarget, List<VariableOrScope> variables, Reference<Boolean> hasEval) throws IOException, ActionParseException, InterruptedException {
|
||||
ParsedSymbol s = lex();
|
||||
int arrCnt = 0;
|
||||
@@ -1183,6 +1200,38 @@ public class ActionScript2VariableParser {
|
||||
Variable vret = new Variable(false, varName, s.position);
|
||||
variables.add(vret);
|
||||
allowMemberOrCall.setVal(true);
|
||||
|
||||
if (varName.equals("this")) {
|
||||
ParsedSymbol s2 = lex();
|
||||
if (s2.type == SymbolType.DOT) {
|
||||
ParsedSymbol s3 = lex();
|
||||
if (s3.group == SymbolGroup.IDENTIFIER) {
|
||||
Variable thisVar = new Variable(false, "this." + s3.value.toString(), s3.position);
|
||||
variables.add(thisVar);
|
||||
} else {
|
||||
lexer.pushback(s3);
|
||||
lexer.pushback(s2);
|
||||
}
|
||||
} else {
|
||||
lexer.pushback(s2);
|
||||
}
|
||||
}
|
||||
ParsedSymbol ss = lex();
|
||||
String fullName = varName;
|
||||
while (ss.type == SymbolType.DOT) {
|
||||
ParsedSymbol si = lex();
|
||||
if (!isIdentifier(si)) {
|
||||
lexer.pushback(si);
|
||||
break;
|
||||
}
|
||||
fullName += ".";
|
||||
fullName += si.value.toString();
|
||||
Variable v = new Variable(false, fullName, si.position);
|
||||
variables.add(v);
|
||||
ss = lex();
|
||||
}
|
||||
lexer.pushback(ss);
|
||||
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
@@ -1231,7 +1280,7 @@ public class ActionScript2VariableParser {
|
||||
case "goto":
|
||||
s = lexer.lex();
|
||||
ret = true;
|
||||
//throw new ActionParseException("Compiling §§" + s.value + " is not available, sorry", lexer.yyline());
|
||||
//throw new ActionParseException("Compiling §§" + s.value + " is not available, sorry", lexer.yyline());
|
||||
default:
|
||||
throw new ActionParseException("Unknown preprocessor instruction: §§" + s.value, lexer.yyline());
|
||||
|
||||
@@ -1367,7 +1416,7 @@ public class ActionScript2VariableParser {
|
||||
expressionPrimary(inFunction, inMethod, inTellTarget, false, variables, false, hasEval);
|
||||
}
|
||||
expectedType(SymbolType.PARENT_OPEN);
|
||||
call(inFunction, inMethod, inTellTarget, variables, hasEval);
|
||||
call(inFunction, inMethod, inTellTarget, variables, hasEval);
|
||||
ret = true;
|
||||
allowMemberOrCall = true;
|
||||
|
||||
@@ -1419,7 +1468,7 @@ public class ActionScript2VariableParser {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
private boolean memberOrCall(boolean ret, boolean inFunction, boolean inMethod, boolean inTellTarget, List<VariableOrScope> variables, boolean allowCall, Reference<Boolean> hasEval) throws IOException, ActionParseException, InterruptedException {
|
||||
ParsedSymbol op = lex();
|
||||
while (op.isType(SymbolType.PARENT_OPEN, SymbolType.BRACKET_OPEN, SymbolType.DOT)) {
|
||||
@@ -1427,7 +1476,7 @@ public class ActionScript2VariableParser {
|
||||
if (!allowCall) {
|
||||
break;
|
||||
}
|
||||
call(inFunction, inMethod, inTellTarget, variables, hasEval);
|
||||
call(inFunction, inMethod, inTellTarget, variables, hasEval);
|
||||
ret = true;
|
||||
}
|
||||
if (op.type == SymbolType.BRACKET_OPEN) {
|
||||
@@ -1551,7 +1600,7 @@ public class ActionScript2VariableParser {
|
||||
Map<String, Integer> varNameToDefinitionPosition = new LinkedHashMap<>();
|
||||
|
||||
parseVariablesList(new ArrayList<>(), vars, definitionPosToReferences, referenceToDefinition, varNameToDefinitionPosition);
|
||||
|
||||
|
||||
if (inOnHandler) {
|
||||
expectedType(SymbolType.CURLY_CLOSE);
|
||||
}
|
||||
@@ -1578,14 +1627,16 @@ public class ActionScript2VariableParser {
|
||||
privateVarNameToDefinitionPosition.put(v.name, v.position);
|
||||
definitionPosToReferences.put(v.position, new ArrayList<>());
|
||||
} else {
|
||||
if (privateVarNameToDefinitionPosition.containsKey(v.name)) {
|
||||
if (!privateVarNameToDefinitionPosition.containsKey(v.name)) {
|
||||
parentVarNameToDefinitionPosition.put(v.name, -v.position - 1);
|
||||
privateVarNameToDefinitionPosition.put(v.name, -v.position - 1);
|
||||
definitionPosToReferences.put(-v.position - 1, new ArrayList<>());
|
||||
definitionPosToReferences.get(-v.position - 1).add(v.position);
|
||||
referenceToDefinition.put(v.position, -v.position - 1);
|
||||
} else {
|
||||
int definitionPos = privateVarNameToDefinitionPosition.get(v.name);
|
||||
definitionPosToReferences.get(definitionPos).add(v.position);
|
||||
referenceToDefinition.put(v.position, definitionPos);
|
||||
} else {
|
||||
//first usage, take as definition (?)
|
||||
privateVarNameToDefinitionPosition.put(v.name, v.position);
|
||||
definitionPosToReferences.put(v.position, new ArrayList<>());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1602,15 +1653,16 @@ public class ActionScript2VariableParser {
|
||||
privateVarNameToDefinitionPosition.put(v.name, v.position);
|
||||
definitionPosToReferences.put(v.position, new ArrayList<>());
|
||||
} else {
|
||||
if (privateVarNameToDefinitionPosition.containsKey(v.name)) {
|
||||
if (!privateVarNameToDefinitionPosition.containsKey(v.name)) {
|
||||
parentVarNameToDefinitionPosition.put(v.name, -v.position - 1);
|
||||
privateVarNameToDefinitionPosition.put(v.name, -v.position - 1);
|
||||
definitionPosToReferences.put(-v.position - 1, new ArrayList<>());
|
||||
definitionPosToReferences.get(-v.position - 1).add(v.position);
|
||||
referenceToDefinition.put(v.position, -v.position - 1);
|
||||
} else {
|
||||
int definitionPos = privateVarNameToDefinitionPosition.get(v.name);
|
||||
definitionPosToReferences.get(definitionPos).add(v.position);
|
||||
referenceToDefinition.put(v.position, definitionPos);
|
||||
} else {
|
||||
//first usage, take as definition (?)
|
||||
parentVarNameToDefinitionPosition.put(v.name, v.position);
|
||||
privateVarNameToDefinitionPosition.put(v.name, v.position);
|
||||
definitionPosToReferences.put(v.position, new ArrayList<>());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1623,7 +1675,7 @@ public class ActionScript2VariableParser {
|
||||
|
||||
private void versionRequired(ParsedSymbol s, int min) throws ActionParseException {
|
||||
versionRequired(s.value.toString(), min, Integer.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
private void versionRequired(String type, int min, int max) throws ActionParseException {
|
||||
if (min == max && swfVersion != min) {
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2025 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.parser.script.variables;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ClassScope implements Scope {
|
||||
|
||||
private final List<VariableOrScope> privateItems;
|
||||
|
||||
public ClassScope(List<VariableOrScope> traits) {
|
||||
this.privateItems = traits;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VariableOrScope> getSharedItems() {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VariableOrScope> getPrivateItems() {
|
||||
return privateItems;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2025 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.parser.script.variables;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class Type extends Variable {
|
||||
|
||||
public Type(boolean definition, String name, int position) {
|
||||
super(definition, name, position);
|
||||
}
|
||||
}
|
||||
@@ -31,4 +31,9 @@ public class Variable implements VariableOrScope {
|
||||
this.name = name;
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return (definition ? "definition of " : "") + name + " at " + position;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -712,7 +712,7 @@ public class ActionPanel extends JPanel implements SearchListener<ScriptSearchRe
|
||||
editor.setEditable(false);
|
||||
decompiledEditor = new DebuggableEditorPane();
|
||||
decompiledEditor.setEditable(false);
|
||||
decompiledEditor.setLinkHandler(new LinkHandler() {
|
||||
/*decompiledEditor.setLinkHandler(new LinkHandler() {
|
||||
@Override
|
||||
public boolean isLink(Token token) {
|
||||
int pos = token.start;
|
||||
@@ -741,7 +741,7 @@ public class ActionPanel extends JPanel implements SearchListener<ScriptSearchRe
|
||||
public Highlighter.HighlightPainter linkPainter() {
|
||||
return decompiledEditor.linkPainter();
|
||||
}
|
||||
});
|
||||
});*/
|
||||
|
||||
searchPanel = new SearchPanel<>(new FlowLayout(), this);
|
||||
|
||||
@@ -1409,7 +1409,7 @@ public class ActionPanel extends JPanel implements SearchListener<ScriptSearchRe
|
||||
searchPanel.setSearchText(searchedText);
|
||||
Runnable onScriptComplete = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
public void run() {
|
||||
Timer tim = new Timer();
|
||||
tim.schedule(new TimerTask() {
|
||||
@Override
|
||||
|
||||
@@ -20,6 +20,8 @@ import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.action.parser.ActionParseException;
|
||||
import com.jpexs.decompiler.flash.action.parser.script.variables.ActionScript2VariableParser;
|
||||
import com.jpexs.decompiler.flash.gui.editor.DebuggableEditorPane;
|
||||
import com.jpexs.decompiler.flash.gui.editor.LineMarkedEditorPane;
|
||||
import com.jpexs.decompiler.flash.gui.editor.LinkHandler;
|
||||
import java.awt.Color;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
@@ -36,6 +38,7 @@ import javax.swing.event.CaretListener;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
import javax.swing.text.BadLocationException;
|
||||
import javax.swing.text.Highlighter;
|
||||
import jsyntaxpane.SyntaxDocument;
|
||||
import jsyntaxpane.Token;
|
||||
import jsyntaxpane.TokenType;
|
||||
@@ -47,9 +50,9 @@ import jsyntaxpane.util.Configuration;
|
||||
/**
|
||||
* This class highlights Variable tokens of ActionScript 1/2
|
||||
*/
|
||||
public class ActionVariableMarker implements SyntaxComponent, CaretListener, PropertyChangeListener, DocumentListener {
|
||||
public class ActionVariableMarker implements SyntaxComponent, CaretListener, PropertyChangeListener, DocumentListener, LinkHandler {
|
||||
|
||||
public static final String DEFAULT_TOKENTYPES = "IDENTIFIER, REGEX";
|
||||
public static final String DEFAULT_TOKENTYPES = "IDENTIFIER, KEYWORD, REGEX";
|
||||
public static final String PROPERTY_COLOR = "ActionVariableMarker.Color";
|
||||
public static final String PROPERTY_TOKENTYPES = "ActionVariableMarker.TokenTypes";
|
||||
private static final Color DEFAULT_COLOR = new Color(0xf8e7d6);
|
||||
@@ -92,17 +95,21 @@ public class ActionVariableMarker implements SyntaxComponent, CaretListener, Pro
|
||||
|
||||
private Token getIdentifierTokenAt(SyntaxDocument sDoc, int pos) {
|
||||
Token thisToken = sDoc.getTokenAt(pos);
|
||||
if (thisToken != null && (thisToken.type == TokenType.IDENTIFIER || thisToken.type == TokenType.REGEX)) {
|
||||
if (thisToken != null && (thisToken.type == TokenType.IDENTIFIER || thisToken.type == TokenType.REGEX || thisToken.type == TokenType.KEYWORD)) {
|
||||
return thisToken;
|
||||
}
|
||||
|
||||
Token token = sDoc.getTokenAt(pos - 1);
|
||||
if (token != null && (token.type == TokenType.IDENTIFIER || token.type == TokenType.REGEX) && (token.start + token.length == pos)) {
|
||||
if (token != null
|
||||
&& (token.type == TokenType.IDENTIFIER || token.type == TokenType.REGEX || token.type == TokenType.KEYWORD)
|
||||
&& (token.start + token.length == pos)) {
|
||||
return token;
|
||||
}
|
||||
|
||||
token = sDoc.getTokenAt(pos + 1);
|
||||
if (token != null && (token.type == TokenType.IDENTIFIER || token.type == TokenType.REGEX)) {
|
||||
if (token != null
|
||||
&& (token.type == TokenType.IDENTIFIER || token.type == TokenType.REGEX || token.type == TokenType.KEYWORD)
|
||||
&& (token.start == pos)) {
|
||||
return token;
|
||||
}
|
||||
return null;
|
||||
@@ -120,7 +127,7 @@ public class ActionVariableMarker implements SyntaxComponent, CaretListener, Pro
|
||||
if (referenceToDefinition.containsKey(tok.start)) {
|
||||
definitionPos = referenceToDefinition.get(tok.start);
|
||||
}
|
||||
Token definitionToken = getIdentifierTokenAt(sDoc, definitionPos);
|
||||
Token definitionToken = getIdentifierTokenAt(sDoc, definitionPos < 0 ? -(definitionPos + 1) : definitionPos);
|
||||
if (definitionToken != null) {
|
||||
if (definitionPosToReferences.containsKey(definitionPos)) {
|
||||
Markers.markToken(pane, definitionToken, marker);
|
||||
@@ -161,6 +168,9 @@ public class ActionVariableMarker implements SyntaxComponent, CaretListener, Pro
|
||||
editor.addCaretListener(this);
|
||||
editor.addPropertyChangeListener(this);
|
||||
editor.getDocument().addDocumentListener(this);
|
||||
if (editor instanceof LineMarkedEditorPane) {
|
||||
((LineMarkedEditorPane) editor).setLinkHandler(this);
|
||||
}
|
||||
documentUpdated();
|
||||
markTokenAt(editor.getCaretPosition());
|
||||
status = Status.INSTALLING;
|
||||
@@ -173,8 +183,11 @@ public class ActionVariableMarker implements SyntaxComponent, CaretListener, Pro
|
||||
pane.removePropertyChangeListener(this);
|
||||
pane.getDocument().removeDocumentListener(this);
|
||||
pane.removeCaretListener(this);
|
||||
if (editor instanceof LineMarkedEditorPane) {
|
||||
((LineMarkedEditorPane) editor).setLinkHandler(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(ActionVariableMarker.class.getName());
|
||||
|
||||
@Override
|
||||
@@ -212,9 +225,11 @@ public class ActionVariableMarker implements SyntaxComponent, CaretListener, Pro
|
||||
varParser.parse(fullText, newDefinitionPosToReferences, newReferenceToDefinition);
|
||||
definitionPosToReferences = newDefinitionPosToReferences;
|
||||
referenceToDefinition = newReferenceToDefinition;
|
||||
markTokenAt(pane.getCaretPosition());
|
||||
} catch (BadLocationException | ActionParseException | IOException | InterruptedException ex) {
|
||||
definitionPosToReferences.clear();
|
||||
referenceToDefinition.clear();
|
||||
//ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,4 +247,22 @@ public class ActionVariableMarker implements SyntaxComponent, CaretListener, Pro
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
documentUpdated();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLink(Token token) {
|
||||
return referenceToDefinition.containsKey(token.start) && referenceToDefinition.get(token.start) >= 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleLink(Token token) {
|
||||
Integer definition = referenceToDefinition.get(token.start);
|
||||
if (definition != null) {
|
||||
pane.setCaretPosition(definition);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Highlighter.HighlightPainter linkPainter() {
|
||||
return ((LineMarkedEditorPane) pane).linkPainter();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user