AS3 Highligter - highlight external properties

This commit is contained in:
Jindra Petřík
2025-06-10 00:23:36 +02:00
parent 05a3b511ab
commit c25cb07eed
11 changed files with 497 additions and 158 deletions
@@ -18,6 +18,8 @@ package com.jpexs.decompiler.flash.gui.editor;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.gui.AppStrings;
import com.jpexs.decompiler.flash.simpleparser.LinkHandler;
import com.jpexs.decompiler.flash.simpleparser.LinkType;
import com.jpexs.decompiler.flash.simpleparser.SimpleParser;
import com.jpexs.helpers.Reference;
import java.awt.Color;
@@ -41,7 +43,6 @@ import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Document;
import javax.swing.text.Element;
import javax.swing.text.Highlighter.HighlightPainter;
import javax.swing.text.JTextComponent;
import javax.swing.text.Position;
import javax.swing.text.Segment;
@@ -49,7 +50,6 @@ import javax.swing.text.View;
import jsyntaxpane.SyntaxDocument;
import jsyntaxpane.SyntaxStyle;
import jsyntaxpane.Token;
import jsyntaxpane.TokenType;
import jsyntaxpane.actions.ActionUtils;
/**
@@ -70,16 +70,44 @@ public class LineMarkedEditorPane extends UndoFixedEditorPane implements LinkHan
private LinkHandler linkHandler = this;
private SimpleParser parser;
private SimpleParser parser;
@Override
public LinkType getExternalTypeLinkType(String className) {
public LinkType getClassLinkType(String className) {
return LinkType.NO_LINK;
}
@Override
public void handleExternalTypeLink(String className) {
public boolean traitExists(String className, String traitName) {
return false;
}
@Override
public void handleClassLink(String className) {
}
@Override
public void handleTraitLink(String className, String traitName) {
}
@Override
public String getTraitType(String className, String traitName) {
return "*";
}
@Override
public String getTraitSubType(String className, String traitName, int level) {
return null;
}
@Override
public String getTraitCallType(String className, String traitName) {
return null;
}
@Override
public String getTraitCallSubType(String className, String traitName, int level) {
return null;
}
public static class LineMarker implements Comparable<LineMarker> {
@@ -384,21 +412,6 @@ public class LineMarkedEditorPane extends UndoFixedEditorPane implements LinkHan
return linkHandler;
}
@Override
public HighlightPainter linkPainter() {
return null;
}
@Override
public LinkType getLinkType(Token token) {
return LinkType.NO_LINK;
}
@Override
public void handleLink(Token token) {
}
@Override
public void setText(String t) {
this.lineMarkers = new HashMap<>();
@@ -1,36 +0,0 @@
/*
* Copyright (C) 2010-2025 JPEXS
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.jpexs.decompiler.flash.gui.editor;
import javax.swing.text.Highlighter;
import jsyntaxpane.Token;
/**
* @author JPEXS
*/
public interface LinkHandler {
public LinkType getLinkType(Token token);
public LinkType getExternalTypeLinkType(String className);
public void handleLink(Token token);
public void handleExternalTypeLink(String className);
public Highlighter.HighlightPainter linkPainter();
}
@@ -1,28 +0,0 @@
/*
* Copyright (C) 2025 JPEXS
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.jpexs.decompiler.flash.gui.editor;
/**
*
* @author JPEXS
*/
public enum LinkType {
NO_LINK,
LINK_THIS_SCRIPT,
LINK_OTHER_SCRIPT,
LINK_OTHER_FILE;
}
@@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.gui.AppStrings;
import com.jpexs.decompiler.flash.gui.Main;
import com.jpexs.decompiler.flash.gui.View;
import com.jpexs.decompiler.flash.gui.ViewMessages;
import com.jpexs.decompiler.flash.simpleparser.LinkType;
import com.jpexs.decompiler.flash.simpleparser.SimpleParseException;
import com.jpexs.decompiler.flash.simpleparser.SimpleParser;
import java.awt.BorderLayout;
@@ -108,6 +109,9 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC
private List<String> externalTypes = new ArrayList<>();
private Map<Integer, Integer> referenceToExternalTypeIndex = new LinkedHashMap<>();
private Map<Integer, List<Integer>> externalTypeIndexToReference = new LinkedHashMap<>();
private Map<String, String> simpleExternalClassNameToFullClassName = new LinkedHashMap<>();
private Map<Integer, String> referenceToExternalTraitKey = new LinkedHashMap<>();
private Map<String, List<Integer>> externalTraitKeyToReference = new LinkedHashMap<>();
private MouseMotionAdapter mouseMotionAdapter;
@@ -283,6 +287,27 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC
}
sDoc.readUnlock();
return;
} else {
if (referenceToExternalTraitKey.containsKey(tok.start)) {
String traitKey = referenceToExternalTraitKey.get(tok.start);
for (int i : externalTraitKeyToReference.get(traitKey)) {
Token referenceToken = getIdentifierTokenAt(sDoc, i);
if (referenceToken != null) {
Markers.SimpleMarker markerKind = marker;
if (lastUnderlined == referenceToken) {
if (lastUnderlinedLinkType == LinkType.LINK_OTHER_SCRIPT) {
markerKind = underLineOtherScriptMarkOccurencesPainter;
} else if (lastUnderlinedLinkType == LinkType.LINK_OTHER_FILE) {
markerKind = underLineOtherFileMarkOccurencesPainter;
} else {
markerKind = underLineMarkOccurencesPainter;
}
}
Markers.markToken(pane, referenceToken, markerKind);
occurencesPositions.add(referenceToken.start);
}
}
}
}
}
Token definitionToken = getIdentifierTokenAt(sDoc, definitionPos < 0 ? -(definitionPos + 1) : definitionPos);
@@ -546,12 +571,32 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC
private void editorMouseMoved(MouseEvent e) {
if (pane instanceof LineMarkedEditorPane) {
Token token = ((LineMarkedEditorPane) pane).tokenAtPos(e.getPoint());
if (token != null) {
String err = errors.get(token.start);
pane.setToolTipText(err);
} else {
if (token == null) {
pane.setToolTipText(null);
return;
}
String err = errors.get(token.start);
if (err != null) {
pane.setToolTipText(err);
return;
}
/*
String traitKey = referenceToExternalTraitKey.get(token.start);
if (traitKey != null) {
pane.setToolTipText(traitKey);
return;
}
if (referenceToExternalTypeIndex.containsKey(token.start)) {
String externalType = externalTypes.get(referenceToExternalTypeIndex.get(token.start));
if (externalType != null) {
pane.setToolTipText(externalType);
return;
}
}
*/
pane.setToolTipText(null);
}
}
@@ -627,12 +672,34 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC
List<String> newExternalTypes = new ArrayList<>();
Map<Integer, Integer> newReferenceToExternalTypeIndex = new LinkedHashMap<>();
Map<Integer, List<Integer>> newExternalTypeIndexToReference = new LinkedHashMap<>();
parser.parse(fullText, newDefinitionPosToReferences, newReferenceToDefinition, newErrors, newExternalTypes, newReferenceToExternalTypeIndex, newExternalTypeIndexToReference);
Map<Integer, String> newReferenceToExternalTraitKey = new LinkedHashMap<>();
Map<String, List<Integer>> newExternalTraitKeyToReference = new LinkedHashMap<>();
parser.parse(
fullText,
newDefinitionPosToReferences,
newReferenceToDefinition,
newErrors,
newExternalTypes,
newReferenceToExternalTypeIndex,
newExternalTypeIndexToReference,
((LineMarkedEditorPane) pane).getLinkHandler(),
newReferenceToExternalTraitKey, newExternalTraitKeyToReference
);
Map<String, String> newSimpleExternalClassNameToFullClassName = new LinkedHashMap<>();
for (int i = 0; i < newExternalTypes.size(); i++) {
String type = newExternalTypes.get(i);
String simpleName = type.contains(".") ? type.substring(type.lastIndexOf(".") + 1) : type;
newSimpleExternalClassNameToFullClassName.put(simpleName, type);
}
definitionPosToReferences = newDefinitionPosToReferences;
referenceToDefinition = newReferenceToDefinition;
externalTypes = newExternalTypes;
referenceToExternalTypeIndex = newReferenceToExternalTypeIndex;
externalTypeIndexToReference = newExternalTypeIndexToReference;
simpleExternalClassNameToFullClassName = newSimpleExternalClassNameToFullClassName;
referenceToExternalTraitKey = newReferenceToExternalTraitKey;
externalTraitKeyToReference = newExternalTraitKeyToReference;
for (SimpleParseException ex : newErrors) {
errors.put((int) ex.position, ex.getMessage());
}
@@ -691,9 +758,19 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC
}
if (referenceToExternalTypeIndex.containsKey(token.start)) {
String externalType = externalTypes.get(referenceToExternalTypeIndex.get(token.start));
return ((LineMarkedEditorPane) pane).getLinkHandler().getExternalTypeLinkType(externalType);
return ((LineMarkedEditorPane) pane).getLinkHandler().getClassLinkType(externalType);
}
return ((LineMarkedEditorPane) pane).getLinkHandler().getLinkType(token);
if (referenceToExternalTraitKey.containsKey(token.start)) {
String traitKey = referenceToExternalTraitKey.get(token.start);
//String traitName = traitKey.substring(traitKey.lastIndexOf("/") + 1);
String className = traitKey.substring(0, traitKey.lastIndexOf("/"));
if (simpleExternalClassNameToFullClassName.containsKey(className)) {
className = simpleExternalClassNameToFullClassName.get(className);
}
return ((LineMarkedEditorPane) pane).getLinkHandler().getClassLinkType(className);
}
return LinkType.NO_LINK;
}
private class UnderlinedLabel extends JLabel {
@@ -732,7 +809,8 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC
&& com.jpexs.decompiler.flash.configuration.Configuration.warningLinkTypes.get()) {
String externalType = externalTypes.get(referenceToExternalTypeIndex.get(token.start));
LinkType lt = ((LineMarkedEditorPane) pane).getLinkHandler().getExternalTypeLinkType(externalType);
LinkType lt = ((LineMarkedEditorPane) pane).getLinkHandler().getClassLinkType(externalType);
if (lt == LinkType.LINK_OTHER_FILE) {
JPanel msgPanel = new JPanel();
@@ -811,11 +889,19 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC
goingOut = true;
pane.setCursor(Cursor.getDefaultCursor());
String externalType = externalTypes.get(referenceToExternalTypeIndex.get(token.start));
((LineMarkedEditorPane) pane).getLinkHandler().handleExternalTypeLink(externalType);
((LineMarkedEditorPane) pane).getLinkHandler().handleClassLink(externalType);
return;
}
if (referenceToExternalTraitKey.containsKey(token.start)) {
String traitKey = referenceToExternalTraitKey.get(token.start);
String traitName = traitKey.substring(traitKey.lastIndexOf("/") + 1);
String className = traitKey.substring(0, traitKey.lastIndexOf("/"));
((LineMarkedEditorPane) pane).getLinkHandler().handleLink(token);
if (simpleExternalClassNameToFullClassName.containsKey(className)) {
className = simpleExternalClassNameToFullClassName.get(className);
}
((LineMarkedEditorPane) pane).getLinkHandler().handleTraitLink(className, traitName);
}
}
}