mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-06 21:18:07 +00:00
Display AS3 p-code docs in GUI, improvements.
This commit is contained in:
@@ -2160,7 +2160,8 @@ public class AVM2Code implements Cloneable {
|
||||
ins.operands[j] = updater.updateOperandOffset(target, ins.operands[j]);
|
||||
}
|
||||
}*/ //Faster, but not so universal
|
||||
if (ins.definition instanceof IfTypeIns) {
|
||||
{
|
||||
if (ins.definition instanceof IfTypeIns) {
|
||||
long target = ins.getTargetAddress();
|
||||
try {
|
||||
ins.operands[0] = updater.updateOperandOffset(ins.getAddress(), target, ins.operands[0]);
|
||||
@@ -2168,6 +2169,7 @@ public class AVM2Code implements Cloneable {
|
||||
throw new ConvertException("Invalid offset (" + ins + ")", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
ins.setAddress(updater.updateInstructionOffset(ins.getAddress()));
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
public class AbsJumpIns extends InstructionDefinition {
|
||||
|
||||
public AbsJumpIns() {
|
||||
super(0xEE, "abs_jump", new int[]{}, false /*?*/, AVM2InstructionFlag.UNDOCUMENTED, AVM2InstructionFlag.UNKNOWN_OPERANDS, AVM2InstructionFlag.NO_FLASH_PLAYER);
|
||||
super(0xEE, "abs_jump", new int[]{}, false /*?*/, AVM2InstructionFlag.UNDOCUMENTED, AVM2InstructionFlag.UNKNOWN_OPERANDS, AVM2InstructionFlag.NO_FLASH_PLAYER, AVM2InstructionFlag.UNKNOWN_STACK);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -598,9 +598,10 @@ public class Configuration {
|
||||
@ConfigurationInternal
|
||||
public static final ConfigurationItem<Boolean> hwAcceleratedGraphics = null;
|
||||
|
||||
@ConfigurationDefaultBoolean(false)
|
||||
@ConfigurationDefaultDouble(0.85)
|
||||
@ConfigurationName("gui.avm2.splitPane.docs.dividerLocationPercent")
|
||||
@ConfigurationInternal
|
||||
public static final ConfigurationItem<Boolean> as3pcodeDocWindow = null;
|
||||
public static final ConfigurationItem<Double> guiAvm2DocsSplitPaneDividerLocationPercent = null;
|
||||
|
||||
private enum OSId {
|
||||
|
||||
|
||||
@@ -0,0 +1,220 @@
|
||||
package com.jpexs.decompiler.flash.docs;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2InstructionFlag;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.helpers.Cache;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* Generator for AVM2 instruction set documentation.
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class As3PCodeDocs {
|
||||
|
||||
private static ResourceBundle prop;
|
||||
private static Map<AVM2InstructionFlag, String> flagDescriptions = new HashMap<>();
|
||||
|
||||
private static Cache<String, String> docsCache = Cache.getInstance(false, true, "as3DocsCache");
|
||||
private static Map<String, InstructionDefinition> nameToDef = new HashMap<>();
|
||||
|
||||
static final String NEWLINE = "\r\n";
|
||||
|
||||
static {
|
||||
prop = ResourceBundle.getBundle("com.jpexs.decompiler.flash.locales.docs.pcode.AS3");
|
||||
for (InstructionDefinition def : AVM2Code.allInstructionSet) {
|
||||
if (def == null) {
|
||||
continue;
|
||||
}
|
||||
nameToDef.put(def.instructionName, def);
|
||||
}
|
||||
|
||||
for (AVM2InstructionFlag flg : AVM2InstructionFlag.values()) {
|
||||
String flagIdent = makeIdent(flg.toString());
|
||||
String flagDescription = getProperty("instructionFlag." + flagIdent);
|
||||
flagDescriptions.put(flg, flagDescription);
|
||||
}
|
||||
}
|
||||
|
||||
private static String makeIdent(String name) {
|
||||
StringBuilder identName = new StringBuilder();
|
||||
boolean cap = false;
|
||||
for (int i = 0; i < name.length(); i++) {
|
||||
char c = name.charAt(i);
|
||||
if (c == '_') {
|
||||
cap = true;
|
||||
continue;
|
||||
}
|
||||
if (cap) {
|
||||
identName.append(c);
|
||||
cap = false;
|
||||
} else {
|
||||
identName.append(Character.toLowerCase(c));
|
||||
}
|
||||
}
|
||||
return identName.toString();
|
||||
}
|
||||
|
||||
public static String getDocsForIns(String insName, boolean showDataSize, boolean ui) {
|
||||
if (!nameToDef.containsKey(insName)) {
|
||||
return null;
|
||||
}
|
||||
return getDocsForIns(nameToDef.get(insName), showDataSize, ui);
|
||||
}
|
||||
|
||||
private static String getProperty(String name) {
|
||||
if (prop.containsKey(name)) {
|
||||
return prop.getString(name);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getDocsForIns(InstructionDefinition def, boolean showDataSize, boolean ui) {
|
||||
final String cacheKey = def.instructionName + "|" + (showDataSize ? 1 : 0) + "|" + (ui ? 1 : 0);
|
||||
String v = docsCache.get(cacheKey);
|
||||
if (v != null) {
|
||||
return v;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String insName = def.instructionName;
|
||||
|
||||
String insShortDescription = getProperty("instruction." + insName + ".shortDescription");
|
||||
String insDescription = getProperty("instruction." + insName + ".description");
|
||||
String stackBefore = def.hasFlag(AVM2InstructionFlag.UNKNOWN_STACK) ? "" : getProperty("instruction." + insName + ".stackBefore");
|
||||
String stackAfter = def.hasFlag(AVM2InstructionFlag.UNKNOWN_STACK) ? "" : getProperty("instruction." + insName + ".stackAfter");
|
||||
if (stackBefore.trim().isEmpty()) {
|
||||
stackBefore = getProperty("ui.stack.before.empty");
|
||||
} else {
|
||||
stackBefore = getProperty("ui.stack.before") + stackBefore;
|
||||
}
|
||||
if (stackAfter.trim().isEmpty()) {
|
||||
stackAfter = getProperty("ui.stack.before.empty");
|
||||
} else {
|
||||
stackAfter = getProperty("ui.stack.before") + stackAfter;
|
||||
}
|
||||
String stack = def.hasFlag(AVM2InstructionFlag.UNKNOWN_STACK) ? getProperty("ui.unknown") : stackBefore + " => " + stackAfter;
|
||||
String operandsDoc = def.hasFlag(AVM2InstructionFlag.UNKNOWN_OPERANDS) ? getProperty("ui.unknown") : getProperty("instruction." + insName + ".operands");
|
||||
|
||||
sb.append(String.format("0x%02X", def.instructionCode)).append(" <font color=\"blue\"><b>").append(insName).append("</b></font>").append(" ");
|
||||
|
||||
if (def.hasFlag(AVM2InstructionFlag.UNKNOWN_OPERANDS)) {
|
||||
sb.append(getProperty("ui.unknown")).append(NEWLINE);
|
||||
} else {
|
||||
String[] operandsDocs = operandsDoc.split(", ?");
|
||||
boolean first = true;
|
||||
for (int i = 0; i < def.operands.length; i++) {
|
||||
int op = def.operands[i];
|
||||
String opDoc = operandsDocs[i];
|
||||
String operandTypeRaw = AVM2Code.operandTypeToString(op, false);
|
||||
String operandTypeCombined = AVM2Code.operandTypeToString(op, true);
|
||||
if (operandTypeCombined.contains(", ")) {
|
||||
String operandTypesCombined[] = operandTypeCombined.split(", ?");
|
||||
String operandTypesRaw[] = operandTypeRaw.split(", ?");
|
||||
|
||||
for (int j = 0; j < operandTypesCombined.length; j++) {
|
||||
if (!first) {
|
||||
sb.append(", ");
|
||||
} else {
|
||||
first = false;
|
||||
}
|
||||
opDoc = operandsDocs[i + j];
|
||||
operandTypeCombined = operandTypesCombined[j];
|
||||
operandTypeRaw = operandTypesRaw[j];
|
||||
operandTypeRaw = getProperty("operandType." + operandTypeRaw + (ui ? ".uiName" : ".name"));
|
||||
if (opDoc.equals("...")) {
|
||||
sb.append("...");
|
||||
} else {
|
||||
sb.append(opDoc);
|
||||
sb.append(":").append(showDataSize ? operandTypeCombined : operandTypeRaw);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!first) {
|
||||
sb.append(", ");
|
||||
} else {
|
||||
first = false;
|
||||
}
|
||||
operandTypeRaw = getProperty("operandType." + operandTypeRaw + (ui ? ".uiName" : ".name"));
|
||||
|
||||
if (opDoc.equals(operandTypeRaw)) {
|
||||
sb.append(showDataSize ? operandTypeCombined : operandTypeRaw);
|
||||
} else {
|
||||
sb.append(opDoc).append(":").append(showDataSize ? operandTypeCombined : operandTypeRaw);
|
||||
}
|
||||
}
|
||||
}
|
||||
sb.append(NEWLINE);
|
||||
}
|
||||
|
||||
sb.append(insShortDescription).append(NEWLINE);
|
||||
|
||||
if (!insDescription.trim().isEmpty()) {
|
||||
sb.append(insDescription).append(NEWLINE);
|
||||
}
|
||||
|
||||
sb.append("<b>").append(getProperty("ui.stack")).append("</b>").append(stack).append(NEWLINE);
|
||||
boolean flagsPrinted = false;
|
||||
|
||||
AVM2InstructionFlag flags[] = def.flags.clone();
|
||||
Arrays.sort(flags, Enum::compareTo);
|
||||
|
||||
for (AVM2InstructionFlag fl : flags) {
|
||||
if (fl != AVM2InstructionFlag.UNKNOWN_OPERANDS && fl != AVM2InstructionFlag.UNKNOWN_STACK) {
|
||||
if (!flagsPrinted) {
|
||||
flagsPrinted = true;
|
||||
sb.append("<b>").append(getProperty("ui.flags")).append("</b>").append(NEWLINE);
|
||||
}
|
||||
sb.append(getProperty("ui.flags.beginning")).append(flagDescriptions.get(fl)).append(NEWLINE);
|
||||
}
|
||||
}
|
||||
String r = sb.toString();
|
||||
docsCache.put(cacheKey, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static String getAllInstructionDocs() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String style = "li {list-style:none; padding:10px;border:1px solid black; border-bottom:none; border-collapse:collapse; } " + NEWLINE
|
||||
+ "ul {padding-left:0; display:table; border-bottom:1px solid black;}" + NEWLINE;
|
||||
|
||||
sb.append("<!DOCTYPE html>").append(NEWLINE).
|
||||
append("<html>").append(NEWLINE).
|
||||
append("<head>").append(NEWLINE).
|
||||
append("<style>").append(style).append("</style>").append(NEWLINE).
|
||||
append("<meta charset=\"UTF-8\">").append(NEWLINE).
|
||||
append("<title>").append(getProperty("ui.list.pageTitle")).append("</title>").append(NEWLINE).
|
||||
append("</head>").append(NEWLINE).
|
||||
append("<body>").append(NEWLINE);
|
||||
sb.append("<h1>").append(getProperty("ui.list.heading")).append("</h1>").append(NEWLINE);
|
||||
sb.append("<ul>").append(NEWLINE);
|
||||
Set<String> s = new TreeSet<>(nameToDef.keySet());
|
||||
for (String name : s) {
|
||||
InstructionDefinition def = nameToDef.get(name);
|
||||
if (def == null) {
|
||||
continue;
|
||||
}
|
||||
sb.append("<li>").append(NEWLINE);
|
||||
sb.append(getDocsForIns(def, true, false).replace(NEWLINE, "<br />" + NEWLINE));
|
||||
sb.append("</li>").append(NEWLINE);
|
||||
}
|
||||
sb.append("</ul>").append(NEWLINE);
|
||||
sb.append("</body>").append(NEWLINE);
|
||||
sb.append("</html>").append(NEWLINE);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(getAllInstructionDocs());
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,20 @@
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library.
|
||||
|
||||
#String for whole list generation
|
||||
ui.list.heading = AVM2 Instruction list
|
||||
ui.list.pageTitle = AVM2 Instruction list
|
||||
|
||||
#various strings in UI:
|
||||
ui.unknown = ???
|
||||
ui.stack = Stack:\u0020
|
||||
ui.stack.before = ...,\u0020
|
||||
ui.stack.before.empty = ...
|
||||
ui.flags = Flags:\u0020
|
||||
ui.flags.beginning = \u0020-\u0020
|
||||
|
||||
|
||||
#----------------------- Flags of the instructions
|
||||
instructionFlag.undocumented = Undocumented
|
||||
instructionFlag.unknownStack = Unknown stack
|
||||
instructionFlag.es4NumericsMinor = ES4 numerics (ABC minor 17)
|
||||
@@ -21,83 +35,133 @@ instructionFlag.unknownOperands = Unknown operands
|
||||
instructionFlag.noFlashPlayer = Not in standard Flash Player
|
||||
instructionFlag.deprecated = Deprecated
|
||||
instructionFlag.domainMemory = Domain memory operation
|
||||
instructionFlag. =
|
||||
instructionFlag. =
|
||||
|
||||
|
||||
|
||||
#----------------------- Operand types
|
||||
operandType.multinameIndex = Multiname index
|
||||
operandType.multinameIndex.description = Index into multiname constant pool
|
||||
operandType.multinameIndex.name = multinameIndex
|
||||
operandType.multinameIndex.uiName = multiname
|
||||
|
||||
operandType.argCount = Number of arguments
|
||||
operandType.argCount.description = Number of following arguments
|
||||
operandType.argCount.name = argCount
|
||||
operandType.argCount.uiName = uint
|
||||
|
||||
|
||||
operandType.methodIndex = Method index
|
||||
operandType.methodIndex.description = Index of method in the ABC
|
||||
operandType.methodIndex.name = methodIndex
|
||||
operandType.methodIndex.uiName = methodIndex
|
||||
|
||||
operandType.stringIndex = String index
|
||||
operandType.stringIndex.description = Index into string values constant pool
|
||||
operandType.stringIndex.name = stringIndex
|
||||
operandType.stringIndex.uiName = string
|
||||
|
||||
|
||||
operandType.debugType = Debug type
|
||||
operandType.debugType.description = Type of debug information. Currently only value of 1 is used.
|
||||
operandType.debugType.name = debugType
|
||||
operandType.debugType.uiName = debugType
|
||||
|
||||
|
||||
operandType.registerIndex = Register index
|
||||
operandType.registerIndex.description = Index of a local register (0-255)
|
||||
operandType.registerIndex.name = registerIndex
|
||||
operandType.registerIndex.uiName = uint
|
||||
|
||||
operandType.linenum = Line number
|
||||
operandType.linenum.description = Line number of file
|
||||
operandType.linenum.name = linenum
|
||||
operandType.linenum.uiName = linenum
|
||||
|
||||
|
||||
#similar as registerIndex, but U30 instead of U8
|
||||
operandType.localRegIndex = Register index
|
||||
operandType.localRegIndex.description = Index of a local register
|
||||
operandType.localRegIndex.name = localRegIndex
|
||||
operandType.localRegIndex.uiName = uint
|
||||
|
||||
|
||||
operandType.slotIndex = Slot index
|
||||
operandType.slotIndex.description = Index of the slot on an object
|
||||
operandType.slotIndex.name = slotIndex
|
||||
operandType.slotIndex.uiName = slotIndex
|
||||
|
||||
operandType.scopeIndex = Scope stack index
|
||||
operandType.scopeIndex.description = Index in the scope stack
|
||||
operandType.scopeIndex.name = scopeIndex
|
||||
operandType.scopeIndex.uiName = scopeIndex
|
||||
|
||||
operandType.offset = Offset
|
||||
operandType.offset.description = Offset to other location
|
||||
operandType.offset.name = offset
|
||||
operandType.offset.uiName = labelName
|
||||
|
||||
operandType.exceptionIndex = Exception index
|
||||
operandType.exceptionIndex.description = Index of exception in current method info
|
||||
operandType.exceptionIndex.name = exceptionIndex
|
||||
operandType.exceptionIndex.uiName = exceptionIndex
|
||||
|
||||
|
||||
operandType.classIndex = Class index
|
||||
operandType.classIndex.description = Index of class in ABC
|
||||
operandType.classIndex.name = classIndex
|
||||
operandType.classIndex.uiName = classIndex
|
||||
|
||||
operandType.intIndex = Int index
|
||||
operandType.intIndex.description = Index into integer values constant pool
|
||||
operandType.intIndex.name = intIndex
|
||||
operandType.intIndex.uiName = int
|
||||
|
||||
operandType.uintIndex = UInt index
|
||||
operandType.uintIndex.description = Index into unsigned integer values constant pool
|
||||
operandType.uintIndex.name = uintIndex
|
||||
operandType.uintIndex.uiName = uint
|
||||
|
||||
|
||||
operandType.doubleIndex = Double index
|
||||
operandType.doubleIndex.description = Index into double precision floating point values constant pool
|
||||
operandType.doubleIndex.name = doubleIndex
|
||||
operandType.doubleIndex.uiName = double
|
||||
|
||||
operandType.decimalIndex = Decimal index
|
||||
operandType.decimalIndex.description = Index into decimal values (128bit floating point) constant pool (EcmaScript 4 numerics - ABC minorVersion 17)
|
||||
operandType.decimalIndex.description = Index into decimal values (128bit floating point) constant pool
|
||||
operandType.decimalIndex.name = decimalIndex
|
||||
operandType.decimalIndex.uiName = decimal
|
||||
|
||||
operandType.caseBaseoffset = Base offset
|
||||
operandType.caseBaseoffset.description = Base offset of lookupswitch triggered when no value matches
|
||||
operandType.caseBaseoffset.name = offset
|
||||
operandType.caseBaseoffset.uiName = labelName
|
||||
|
||||
operandType.numberContext = Number context (ES4)
|
||||
operandType.numberContext.description = Context of calculations when using EcmaScript 4 numerics (ABC minorVersion 17).\nBits 0-2 type,3-5 rounding type, 6-12 precision.\nType: 0=number,1=decimal,2=double,3=int,4=uint\nRounding: 0=ceiling,1=up,2=half_up,3=half_even,4=half_down,5=down,6=floor\nPrecision:0-34
|
||||
|
||||
operandType.multinameIndex = Multiname index
|
||||
operandType.multinameIndex.description = Index into multiname constant pool
|
||||
operandType.numberContext.name = numberContext
|
||||
operandType.numberContext.uiName = uint
|
||||
|
||||
operandType.dispatchId = Dispatch id
|
||||
operandType.dispatchId.description = Id of the method dispatch
|
||||
operandType.dispatchId.name = dispatchId
|
||||
operandType.dispatchId.uiName = uint
|
||||
|
||||
operandType.floatIndex = Float index
|
||||
operandType.floatIndex.description = Index into float values constant pool (Only some ABC versions)
|
||||
operandType.floatIndex.description = Index into float values constant pool
|
||||
operandType.floatIndex.name = floatIndex
|
||||
operandType.floatIndex.uiName = float
|
||||
|
||||
operandType.float4Index = Float4 index
|
||||
operandType.float4Index.description = Index into float4 values constant pool (Only some ABC versions)
|
||||
operandType.float4Index.description = Index into float4 values constant pool
|
||||
operandType.float4Index.name = float4Index
|
||||
operandType.float4Index.uiName = float4
|
||||
|
||||
operandType.namespaceIndex = Namespace index
|
||||
operandType.namespaceIndex = Index into namespace constant pool
|
||||
operandType.namespaceIndex.name = namespaceIndex
|
||||
operandType.namespaceIndex.uiName = namespace
|
||||
|
||||
|
||||
#----------------------- Instructions
|
||||
|
||||
instruction.bkpt.shortDescription = Breakpoint
|
||||
instruction.bkpt.description = Breakpoint when debugging
|
||||
@@ -512,7 +576,7 @@ instruction.callproperty.shortDescription = Call property
|
||||
instruction.callproperty.description =
|
||||
instruction.callproperty.stackBefore = obj, [ns], [name], arg1, ..., argN
|
||||
instruction.callproperty.stackAfter = value
|
||||
instruction.callproperty.operands = propertyName, argCount
|
||||
instruction.callproperty.operands = property, argCount
|
||||
|
||||
instruction.returnvoid.shortDescription = Return from a method
|
||||
instruction.returnvoid.description =
|
||||
@@ -536,7 +600,7 @@ instruction.constructprop.shortDescription = Construct a property of an object
|
||||
instruction.constructprop.description =
|
||||
instruction.constructprop.stackBefore = obj, [ns], [name], arg1, ..., argN
|
||||
instruction.constructprop.stackAfter = value
|
||||
instruction.constructprop.operands = propertyName, argCount
|
||||
instruction.constructprop.operands = property, argCount
|
||||
|
||||
#Undocumented:
|
||||
instruction.callsuperid.shortDescription = Call super id
|
||||
@@ -549,7 +613,7 @@ instruction.callproplex.shortDescription = Call property with null as this
|
||||
instruction.callproplex.description =
|
||||
instruction.callproplex.stackBefore = obj, [ns], [name], arg1, ..., argN
|
||||
instruction.callproplex.stackAfter = value
|
||||
instruction.callproplex.operands = propertyName, argCount
|
||||
instruction.callproplex.operands = property, argCount
|
||||
|
||||
#Undocumented:
|
||||
instruction.callinterface.shortDescription = Call interface
|
||||
@@ -570,7 +634,7 @@ instruction.callpropvoid.shortDescription = Call property, discard return value
|
||||
instruction.callpropvoid.description =
|
||||
instruction.callpropvoid.stackBefore = obj, [ns], [name], arg1, ..., argN
|
||||
instruction.callpropvoid.stackAfter = value
|
||||
instruction.callpropvoid.operands = propertyName, argCount
|
||||
instruction.callpropvoid.operands = property, argCount
|
||||
|
||||
instruction.sxi1.shortDescription = Sign extend 1bit value to 32bits
|
||||
instruction.sxi1.description =
|
||||
@@ -687,13 +751,13 @@ instruction.getlocal.shortDescription = Get local register value
|
||||
instruction.getlocal.description =
|
||||
instruction.getlocal.stackBefore =
|
||||
instruction.getlocal.stackAfter = value
|
||||
instruction.getlocal.operands = localReg
|
||||
instruction.getlocal.operands = localRegIndex
|
||||
|
||||
instruction.setlocal.shortDescription = Set local register value
|
||||
instruction.setlocal.description =
|
||||
instruction.setlocal.stackBefore = value
|
||||
instruction.setlocal.stackAfter =
|
||||
instruction.setlocal.operands = localReg
|
||||
instruction.setlocal.operands = localRegIndex
|
||||
|
||||
instruction.getglobalscope.shortDescription = Get global scope
|
||||
instruction.getglobalscope.description =
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
# Copyright (C) 2010-2016 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.
|
||||
|
||||
#String for whole list generation
|
||||
ui.list.heading = Seznam AVM2 instrukc\u00ed
|
||||
ui.list.pageTitle = Seznam AVM2 instrukc\u00ed
|
||||
|
||||
#various strings in UI:
|
||||
ui.unknown = ???
|
||||
ui.stack = Z\u00e1sobn\u00edk:\u0020
|
||||
ui.stack.before = ...,\u0020
|
||||
ui.stack.before.empty = ...
|
||||
ui.flags = P\u0159\u00edznaky:\u0020
|
||||
ui.flags.beginning = \u0020-\u0020
|
||||
|
||||
|
||||
#----------------------- Flags of the instructions
|
||||
instructionFlag.undocumented = Nedokumentovan\u00e9
|
||||
instructionFlag.unknownStack = Nezn\u00e1m\u00fd z\u00e1sobn\u00edk
|
||||
instructionFlag.es4NumericsMinor = ES4 numerika (ABC minor 17)
|
||||
instructionFlag.floatMajor = Float hodnoty (ABC major 47)
|
||||
instructionFlag.unknownOperands = Nezn\u00e1me operandy
|
||||
instructionFlag.noFlashPlayer = Nen\u00ed v standardn\u00edm Flash Playeru
|
||||
instructionFlag.deprecated = P\u0159ekonan\u00e9
|
||||
instructionFlag.domainMemory = Operace s dom\u00e9novou pam\u011bt\u00ed
|
||||
|
||||
#----------------------- Operand types
|
||||
operandType.multinameIndex = Index multiname
|
||||
operandType.multinameIndex.description = Index do seznamu multiname konstant
|
||||
operandType.multinameIndex.name = multinameIndex
|
||||
operandType.multinameIndex.uiName = multiname
|
||||
|
||||
operandType.argCount = Po\u010det argument\u016f
|
||||
operandType.argCount.description = Po\u010det argument\u016f, kter\u00e9 n\u00e1sleduj\u00ed
|
||||
operandType.argCount.name = argCount
|
||||
operandType.argCount.uiName = uint
|
||||
|
||||
|
||||
operandType.methodIndex = Index metody
|
||||
operandType.methodIndex.description = Index metody v ABC
|
||||
operandType.methodIndex.name = methodIndex
|
||||
operandType.methodIndex.uiName = methodIndex
|
||||
|
||||
operandType.stringIndex = Index \u0159et\u011bzce
|
||||
operandType.stringIndex.description = Index do seznamu \u0159et\u011bzcov\u00fdch konstant
|
||||
operandType.stringIndex.name = stringIndex
|
||||
operandType.stringIndex.uiName = string
|
||||
|
||||
|
||||
operandType.debugType = Typ lad\u011bn\u00ed
|
||||
operandType.debugType.description = Typ lad\u00edc\u00ed informace. Moment\u00e1ln\u011b je pou\u017eita pouze hodnota 1.
|
||||
operandType.debugType.name = debugType
|
||||
operandType.debugType.uiName = debugType
|
||||
|
||||
|
||||
operandType.registerIndex = Index registru
|
||||
operandType.registerIndex.description = Index lok\u00e1ln\u00edho registru (0-255)
|
||||
operandType.registerIndex.name = registerIndex
|
||||
operandType.registerIndex.uiName = uint
|
||||
|
||||
operandType.linenum = \u010c\u00edslo \u0159\u00e1dku
|
||||
operandType.linenum.description = \u010c\u00edslo \u0159\u00e1dku v souboru
|
||||
operandType.linenum.name = linenum
|
||||
operandType.linenum.uiName = linenum
|
||||
|
||||
|
||||
#similar as registerIndex, but U30 instead of U8
|
||||
operandType.localRegIndex = Index registru
|
||||
operandType.localRegIndex.description = Index lok\u00e1ln\u00edho registru
|
||||
operandType.localRegIndex.name = localRegIndex
|
||||
operandType.localRegIndex.uiName = uint
|
||||
|
||||
|
||||
operandType.slotIndex = Index slotu
|
||||
operandType.slotIndex.description = Index slotu v objektu
|
||||
operandType.slotIndex.name = slotIndex
|
||||
operandType.slotIndex.uiName = slotIndex
|
||||
|
||||
operandType.scopeIndex = Index na scope z\u00e1sobn\u00edku
|
||||
operandType.scopeIndex.description = Index na scope z\u00e1sobn\u00edku
|
||||
operandType.scopeIndex.name = scopeIndex
|
||||
operandType.scopeIndex.uiName = scopeIndex
|
||||
|
||||
operandType.offset = Ofset
|
||||
operandType.offset.description = Ofset na jinou pozici
|
||||
operandType.offset.name = ofset
|
||||
operandType.offset.uiName = n\u00e1zevLabelu
|
||||
|
||||
operandType.exceptionIndex = Index v\u00fdjimky
|
||||
operandType.exceptionIndex.description = Index v\u00fdjimky v aktu\u00e1ln\u00edm methodinfo
|
||||
operandType.exceptionIndex.name = exceptionIndex
|
||||
operandType.exceptionIndex.uiName = exceptionIndex
|
||||
|
||||
|
||||
operandType.classIndex = Index t\u0159\u00eddy
|
||||
operandType.classIndex.description = Index t\u0159\u00eddy v ABC
|
||||
operandType.classIndex.name = classIndex
|
||||
operandType.classIndex.uiName = classIndex
|
||||
|
||||
operandType.intIndex = Index int
|
||||
operandType.intIndex.description = Index do seznamu cel\u00fdch int \u010d\u00edsel
|
||||
operandType.intIndex.name = intIndex
|
||||
operandType.intIndex.uiName = int
|
||||
|
||||
operandType.uintIndex = Inde uint
|
||||
operandType.uintIndex.description = Index do seznamu int \u010d\u00edsel bez znam\u00e9nka
|
||||
operandType.uintIndex.name = uintIndex
|
||||
operandType.uintIndex.uiName = uint
|
||||
|
||||
|
||||
operandType.doubleIndex = Index double
|
||||
operandType.doubleIndex.description = Index do seznamu double \u010d\u00edsel
|
||||
operandType.doubleIndex.name = doubleIndex
|
||||
operandType.doubleIndex.uiName = double
|
||||
|
||||
operandType.decimalIndex = Index decimal
|
||||
operandType.decimalIndex.description = Index do seznamu decimal \u010d\u00edsel (128bit \u010d\u00edsla se znam\u00e9nkem)
|
||||
operandType.decimalIndex.name = decimalIndex
|
||||
operandType.decimalIndex.uiName = decimal
|
||||
|
||||
operandType.caseBaseoffset = Z\u00e1kladn\u00ed ofset
|
||||
operandType.caseBaseoffset.description = Z\u00e1kladn\u00ed ofset lookupswitche spu\u0161ten\u00fd kdy\u017e \u017e\u00e1dn\u00e1 hodnota neodpov\u00edd\u00e1
|
||||
operandType.caseBaseoffset.name = ofset
|
||||
operandType.caseBaseoffset.uiName = n\u00e1zevLabelu
|
||||
|
||||
operandType.numberContext = \u010c\u00edseln\u00fd kontext (ES4)
|
||||
operandType.numberContext.description = Kontext v\u00fdpo\u010dt\u016f p\u0159i pou\u017e\u00edv\u00e1n\u00ed EcmaScript 4 numeriky (ABC minorVersion 17).\nBity 0-2 typ,3-5 typ zaokrouhlen\u00ed, 6-12 p\u0159esnost.\nTyp: 0=number,1=decimal,2=double,3=int,4=uint\nZaokrouhlen\u00ed: 0=ceiling,1=up,2=half_up,3=half_even,4=half_down,5=down,6=floor\nP\u0159esnost:0-34
|
||||
operandType.numberContext.name = \u010d\u00edseln\u00fdKontext
|
||||
operandType.numberContext.uiName = uint
|
||||
|
||||
operandType.dispatchId = Dispatch id
|
||||
operandType.dispatchId.description = Dispatch id metody
|
||||
operandType.dispatchId.name = dispatchId
|
||||
operandType.dispatchId.uiName = uint
|
||||
|
||||
operandType.floatIndex = Index float
|
||||
operandType.floatIndex.description = Index do seznamu float hodnot
|
||||
operandType.floatIndex.name = floatIndex
|
||||
operandType.floatIndex.uiName = float
|
||||
|
||||
operandType.float4Index = Index float4
|
||||
operandType.float4Index.description = Index do seznamu float4 hodnot
|
||||
operandType.float4Index.name = float4Index
|
||||
operandType.float4Index.uiName = float4
|
||||
|
||||
operandType.namespaceIndex = Index namespace
|
||||
operandType.namespaceIndex = Index do seznamu namespace
|
||||
operandType.namespaceIndex.name = namespaceIndex
|
||||
operandType.namespaceIndex.uiName = namespace
|
||||
|
||||
|
||||
#----------------------- Instructions
|
||||
#TODO... maybe(?)
|
||||
@@ -1,171 +0,0 @@
|
||||
package com.jpexs.decompiler.flash.locales.docs.pcode;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2InstructionFlag;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.helpers.Cache;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Generator for AVM2 instruction set documentation. TODO: use this somehow in
|
||||
* GUI
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class As3Docs {
|
||||
|
||||
private static Properties prop;
|
||||
private static Map<AVM2InstructionFlag, String> flagDescriptions = new HashMap<>();
|
||||
|
||||
private static Cache<String, String> docsCache = Cache.getInstance(false, true, "as3DocsCache");
|
||||
private static Map<String, InstructionDefinition> nameToDef = new HashMap<>();
|
||||
|
||||
static {
|
||||
prop = new Properties();
|
||||
try {
|
||||
prop.load(As3Docs.class.getClassLoader().getResourceAsStream("com/jpexs/decompiler/flash/locales/docs/pcode/AS3.properties"));
|
||||
} catch (IOException e) {
|
||||
//ignore
|
||||
}
|
||||
|
||||
for (InstructionDefinition def : AVM2Code.allInstructionSet) {
|
||||
if (def == null) {
|
||||
continue;
|
||||
}
|
||||
nameToDef.put(def.instructionName, def);
|
||||
}
|
||||
|
||||
for (AVM2InstructionFlag flg : AVM2InstructionFlag.values()) {
|
||||
String flagIdent = makeIdent(flg.toString());
|
||||
String flagDescription = prop.getProperty("instructionFlag." + flagIdent);
|
||||
flagDescriptions.put(flg, flagDescription);
|
||||
}
|
||||
}
|
||||
|
||||
private static String makeIdent(String name) {
|
||||
StringBuilder identName = new StringBuilder();
|
||||
boolean cap = false;
|
||||
for (int i = 0; i < name.length(); i++) {
|
||||
char c = name.charAt(i);
|
||||
if (c == '_') {
|
||||
cap = true;
|
||||
continue;
|
||||
}
|
||||
if (cap) {
|
||||
identName.append(c);
|
||||
cap = false;
|
||||
} else {
|
||||
identName.append(Character.toLowerCase(c));
|
||||
}
|
||||
}
|
||||
return identName.toString();
|
||||
}
|
||||
|
||||
public static String getDocsForIns(String insName) {
|
||||
if (!nameToDef.containsKey(insName)) {
|
||||
return null;
|
||||
}
|
||||
return getDocsForIns(nameToDef.get(insName));
|
||||
}
|
||||
|
||||
public static String getDocsForIns(InstructionDefinition def) {
|
||||
String v = docsCache.get(def.instructionName);
|
||||
if (v != null) {
|
||||
return v;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String insName = def.instructionName;
|
||||
final String NEWLINE = "\r\n";
|
||||
|
||||
String insShortDescription = prop.getProperty("instruction." + insName + ".shortDescription");
|
||||
String insDescription = prop.getProperty("instruction." + insName + ".description");
|
||||
String stackBefore = def.hasFlag(AVM2InstructionFlag.UNKNOWN_STACK) ? "???" : prop.getProperty("instruction." + insName + ".stackBefore");
|
||||
String stackAfter = def.hasFlag(AVM2InstructionFlag.UNKNOWN_STACK) ? "???" : prop.getProperty("instruction." + insName + ".stackAfter");
|
||||
String operandsDoc = def.hasFlag(AVM2InstructionFlag.UNKNOWN_OPERANDS) ? "???" : prop.getProperty("instruction." + insName + ".operands");
|
||||
|
||||
sb.append(String.format("0x%02X", def.instructionCode)).append(" <font color=\"blue\"><b>").append(insName).append("</b></font>: ").append(insShortDescription).append(NEWLINE);
|
||||
|
||||
if (!insDescription.trim().isEmpty()) {
|
||||
sb.append("<b>Description:</b> ").append(insDescription).append(NEWLINE);
|
||||
}
|
||||
sb.append("<b>Stack before:</b> ").append(stackBefore).append(NEWLINE);
|
||||
sb.append("<b>Stack after:</b> ").append(stackAfter).append(NEWLINE);
|
||||
boolean flagsPrinted = false;
|
||||
|
||||
sb.append("<b>Operands:</b> ");
|
||||
|
||||
if (def.hasFlag(AVM2InstructionFlag.UNKNOWN_OPERANDS)) {
|
||||
sb.append("???").append(NEWLINE);
|
||||
} else {
|
||||
String[] operandsDocs = operandsDoc.split(", ?");
|
||||
boolean first = true;
|
||||
for (int i = 0; i < def.operands.length; i++) {
|
||||
int op = def.operands[i];
|
||||
String opDoc = operandsDocs[i];
|
||||
String operandTypeRaw = AVM2Code.operandTypeToString(op, false);
|
||||
String operandTypeCombined = AVM2Code.operandTypeToString(op, true);
|
||||
if (operandTypeCombined.contains(", ")) {
|
||||
String operandTypesCombined[] = operandTypeCombined.split(", ?");
|
||||
for (int j = 0; j < operandTypesCombined.length; j++) {
|
||||
if (!first) {
|
||||
sb.append(", ");
|
||||
} else {
|
||||
first = false;
|
||||
}
|
||||
opDoc = operandsDocs[i + j];
|
||||
operandTypeCombined = operandTypesCombined[j];
|
||||
if (opDoc.equals("...")) {
|
||||
sb.append("...");
|
||||
} else {
|
||||
sb.append(opDoc).append(":").append(operandTypeCombined);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!first) {
|
||||
sb.append(", ");
|
||||
} else {
|
||||
first = false;
|
||||
}
|
||||
if (opDoc.equals(operandTypeRaw)) {
|
||||
sb.append(operandTypeCombined);
|
||||
} else {
|
||||
sb.append(opDoc).append(":").append(operandTypeCombined);
|
||||
}
|
||||
}
|
||||
}
|
||||
sb.append(NEWLINE);
|
||||
}
|
||||
|
||||
AVM2InstructionFlag flags[] = def.flags.clone();
|
||||
Arrays.sort(flags, Enum::compareTo);
|
||||
|
||||
for (AVM2InstructionFlag fl : flags) {
|
||||
if (fl != AVM2InstructionFlag.UNKNOWN_OPERANDS && fl != AVM2InstructionFlag.UNKNOWN_STACK) {
|
||||
if (!flagsPrinted) {
|
||||
flagsPrinted = true;
|
||||
sb.append("Flags:").append(NEWLINE);
|
||||
}
|
||||
sb.append(" - ").append(flagDescriptions.get(fl)).append(NEWLINE);
|
||||
}
|
||||
}
|
||||
String r = sb.toString();
|
||||
docsCache.put(def.instructionName, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
||||
for (InstructionDefinition def : AVM2Code.allInstructionSet) {
|
||||
if (def == null) {
|
||||
continue;
|
||||
}
|
||||
System.out.println("=========================");
|
||||
System.out.print(getDocsForIns(def));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.JEditorPane;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JRootPane;
|
||||
import javax.swing.JScrollPane;
|
||||
|
||||
@@ -32,47 +33,27 @@ import javax.swing.JScrollPane;
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DocsWindow extends JFrame implements DocsListener {
|
||||
public class DocsPanel extends JPanel implements DocsListener {
|
||||
|
||||
private JEditorPane textDisplay = new JEditorPane();
|
||||
//TODO: Make this use skin somehow (?)
|
||||
public static final Color HINT_COLOR = new Color(245, 245, 181);
|
||||
|
||||
public DocsWindow() {
|
||||
setAlwaysOnTop(true);
|
||||
setSize(500, 250);
|
||||
setTitle("-");
|
||||
getContentPane().setLayout(new BorderLayout());
|
||||
getContentPane().add(new JScrollPane(textDisplay), BorderLayout.CENTER);
|
||||
public DocsPanel() {
|
||||
setLayout(new BorderLayout());
|
||||
add(new JScrollPane(textDisplay), BorderLayout.CENTER);
|
||||
textDisplay.setContentType("text/html");
|
||||
setAutoRequestFocus(false);
|
||||
textDisplay.setFocusable(false);
|
||||
View.setWindowIcon(this);
|
||||
this.getRootPane().setWindowDecorationStyle(JRootPane.PLAIN_DIALOG);
|
||||
textDisplay.setBackground(Color.white);
|
||||
textDisplay.setBackground(HINT_COLOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void docs(String identifier, String docs, Point screenLocation) {
|
||||
setTitle(identifier);
|
||||
textDisplay.setText(docs.replace("\r\n", "<br />"));
|
||||
if (screenLocation != null) {
|
||||
setLocation(screenLocation);
|
||||
}
|
||||
|
||||
setFocusableWindowState(false);
|
||||
setVisible(true);
|
||||
View.execInEventDispatchLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
setFocusableWindowState(true);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void noDocs() {
|
||||
setVisible(false);
|
||||
setTitle("-");
|
||||
textDisplay.setText("");
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ import com.jpexs.decompiler.flash.helpers.HighlightedText;
|
||||
import com.jpexs.decompiler.flash.helpers.HighlightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.hilight.HighlightSpecialType;
|
||||
import com.jpexs.decompiler.flash.helpers.hilight.Highlighting;
|
||||
import com.jpexs.decompiler.flash.locales.docs.pcode.As3Docs;
|
||||
import com.jpexs.decompiler.flash.docs.As3PCodeDocs;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.graph.ScopeStack;
|
||||
@@ -158,7 +158,7 @@ public class ASMSourceEditorPane extends DebuggableEditorPane implements CaretLi
|
||||
public ASMSourceEditorPane(DecompiledEditorPane decompiledEditor) {
|
||||
this.decompiledEditor = decompiledEditor;
|
||||
addCaretListener(this);
|
||||
for (InstructionDefinition def : AVM2Code.instructionSet) {
|
||||
for (InstructionDefinition def : AVM2Code.allInstructionSet) {
|
||||
if (def != null) {
|
||||
insNameToDef.put(def.instructionName, def);
|
||||
}
|
||||
@@ -419,7 +419,7 @@ public class ASMSourceEditorPane extends DebuggableEditorPane implements CaretLi
|
||||
}
|
||||
}
|
||||
|
||||
public void caretUpdateEdit(CaretEvent e) {
|
||||
public void updateDocs() {
|
||||
String curLine = getCurrentLineText();
|
||||
|
||||
if (curLine == null) {
|
||||
@@ -444,7 +444,7 @@ public class ASMSourceEditorPane extends DebuggableEditorPane implements CaretLi
|
||||
if (loc != null) {
|
||||
SwingUtilities.convertPointToScreen(loc, this);
|
||||
}
|
||||
fireDocs(insName, As3Docs.getDocsForIns(insName), loc);
|
||||
fireDocs(insName, As3PCodeDocs.getDocsForIns(insName, false, true), loc);
|
||||
} else {
|
||||
fireNoDocs();
|
||||
}
|
||||
@@ -452,11 +452,12 @@ public class ASMSourceEditorPane extends DebuggableEditorPane implements CaretLi
|
||||
|
||||
@Override
|
||||
public void caretUpdate(CaretEvent e) {
|
||||
if (isEditable()) {
|
||||
caretUpdateEdit(e);
|
||||
updateDocs();
|
||||
|
||||
if (ignoreCarret) {
|
||||
return;
|
||||
}
|
||||
if (ignoreCarret) {
|
||||
if (isEditable()) {
|
||||
return;
|
||||
}
|
||||
getCaret().setVisible(true);
|
||||
|
||||
@@ -21,9 +21,10 @@ import com.jpexs.decompiler.flash.abc.types.traits.Trait;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.gui.AppStrings;
|
||||
import com.jpexs.decompiler.flash.gui.DocsWindow;
|
||||
import com.jpexs.decompiler.flash.gui.DocsPanel;
|
||||
import com.jpexs.decompiler.flash.gui.Main;
|
||||
import com.jpexs.decompiler.flash.gui.View;
|
||||
import com.jpexs.decompiler.flash.gui.controls.JPersistentSplitPane;
|
||||
import com.jpexs.decompiler.flash.gui.controls.NoneSelectedButtonGroup;
|
||||
import com.jpexs.decompiler.flash.helpers.hilight.HighlightSpecialType;
|
||||
import java.awt.BorderLayout;
|
||||
@@ -36,6 +37,7 @@ import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JSplitPane;
|
||||
import javax.swing.JToggleButton;
|
||||
|
||||
/**
|
||||
@@ -51,7 +53,7 @@ public class MethodCodePanel extends JPanel {
|
||||
private final JToggleButton hexButton;
|
||||
|
||||
private final JToggleButton hexOnlyButton;
|
||||
private final DocsWindow docsWindow;
|
||||
private final DocsPanel docsPanel;
|
||||
|
||||
public void refreshMarkers() {
|
||||
sourceTextArea.refreshMarkers();
|
||||
@@ -113,7 +115,10 @@ public class MethodCodePanel extends JPanel {
|
||||
sourceTextArea = new ASMSourceEditorPane(decompiledEditor);
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
add(new JScrollPane(sourceTextArea), BorderLayout.CENTER);
|
||||
|
||||
docsPanel = new DocsPanel();
|
||||
sourceTextArea.addDocsListener(docsPanel);
|
||||
add(new JPersistentSplitPane(JSplitPane.VERTICAL_SPLIT, new JScrollPane(sourceTextArea), new JScrollPane(docsPanel), Configuration.guiAvm2DocsSplitPaneDividerLocationPercent));
|
||||
sourceTextArea.changeContentType("text/flasm3");
|
||||
sourceTextArea.setFont(new Font("Monospaced", Font.PLAIN, sourceTextArea.getFont().getSize()));
|
||||
|
||||
@@ -146,11 +151,7 @@ public class MethodCodePanel extends JPanel {
|
||||
buttonsPanel.add(new JPanel());
|
||||
|
||||
add(buttonsPanel, BorderLayout.NORTH);
|
||||
docsWindow = new DocsWindow();
|
||||
|
||||
if (Configuration.as3pcodeDocWindow.get()) {
|
||||
sourceTextArea.addDocsListener(docsWindow);
|
||||
}
|
||||
}
|
||||
|
||||
private void graphButtonActionPerformed(ActionEvent evt) {
|
||||
|
||||
Reference in New Issue
Block a user