/*
* 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.
*/
package com.jpexs.decompiler.flash.abc.types.traits;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.types.ConvertData;
import com.jpexs.decompiler.flash.abc.types.MethodBody;
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
import com.jpexs.decompiler.flash.abc.types.Namespace;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.flash.exporters.script.Dependency;
import com.jpexs.decompiler.flash.exporters.script.DependencyParser;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.flash.helpers.NulWriter;
import com.jpexs.decompiler.flash.helpers.hilight.HighlightSpecialType;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.decompiler.graph.ScopeStack;
import com.jpexs.helpers.Helper;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author JPEXS
*/
public class TraitMethodGetterSetter extends Trait {
public int disp_id; //compiler assigned value that helps overriding
public int method_info;
@Override
public void delete(ABC abc, boolean d) {
abc.constants.getMultiname(name_index).deleted = d;
abc.method_info.get(method_info).delete(abc, d);
}
@Override
public String toString(ABC abc, List<DottedChain> fullyQualifiedNames) {
return "0x" + Helper.formatAddress(fileOffset) + " " + Helper.byteArrToString(bytes) + " MethodGetterSetter " + abc.constants.getMultiname(name_index).toString(abc.constants, fullyQualifiedNames) + " disp_id=" + disp_id + " method_info=" + method_info + " metadata=" + Helper.intArrToString(metadata);
}
@Override
public void convertHeader(Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List<DottedChain> fullyQualifiedNames, boolean parallel) {
}
@Override
public void getDependencies(String customNs, ABC abc, List<Dependency> dependencies, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) {
if (ignorePackage == null) {
ignorePackage = getPackage(abc);
}
super.getDependencies(customNs, abc, dependencies, uses, ignorePackage, fullyQualifiedNames);
if (customNs == null) {
Namespace n = getName(abc).getNamespace(abc.constants);
if (n.kind == Namespace.KIND_NAMESPACE) {
customNs = n.getName(abc.constants).toRawString();
}
}
//if (method_info != 0)
{
DependencyParser.parseDependenciesFromMethodInfo(customNs, abc, method_info, dependencies, uses, ignorePackage, fullyQualifiedNames, new ArrayList<>());
}
}
@Override
public GraphTextWriter toStringHeader(Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List<DottedChain> fullyQualifiedNames, boolean parallel) {
String addKind = "";
if (kindType == TRAIT_GETTER) {
addKind = "get ";
}
if (kindType == TRAIT_SETTER) {
addKind = "set ";
}
MethodBody body = abc.findBody(method_info);
if (((classIndex == -1) || (!abc.instance_info.get(classIndex).isInterface())) && (body == null)) {
writer.appendNoHilight("native ");
}
getModifiers(abc, isStatic, writer);
writer.hilightSpecial("function " + addKind, HighlightSpecialType.TRAIT_TYPE);
writer.hilightSpecial(getName(abc).getName(abc.constants, fullyQualifiedNames, false, true), HighlightSpecialType.TRAIT_NAME);
writer.appendNoHilight("(");
abc.method_info.get(method_info).getParamStr(writer, abc.constants, body, abc, fullyQualifiedNames);
writer.appendNoHilight(") : ");
abc.method_info.get(method_info).getReturnTypeStr(writer, abc.constants, fullyQualifiedNames);
return writer;
}
@Override
public void convert(Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List<DottedChain> fullyQualifiedNames, boolean parallel) throws InterruptedException {
if (classIndex < 0) {
writeImportsUsages(abc, writer, getPackage(abc), fullyQualifiedNames);
}
writer.startMethod(method_info);
path = path + "." + getName(abc).getName(abc.constants, fullyQualifiedNames, false, true);
convertHeader(parent, convertData, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel);
int bodyIndex = abc.findBodyIndex(method_info);
if (exportMode != ScriptExportMode.AS_METHOD_STUBS) {
if (!(classIndex != -1 && abc.instance_info.get(classIndex).isInterface() || bodyIndex == -1)) {
if (bodyIndex != -1) {
abc.bodies.get(bodyIndex).convert(convertData, path, exportMode, isStatic, method_info, scriptIndex, classIndex, abc, this, new ScopeStack(), 0, writer, fullyQualifiedNames, null, true);
}
}
}
writer.endMethod();
}
@Override
public GraphTextWriter toString(Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List<DottedChain> fullyQualifiedNames, boolean parallel) throws InterruptedException {
if (classIndex < 0) {
writeImportsUsages(abc, writer, getPackage(abc), fullyQualifiedNames);
}
getMetaData(parent, convertData, abc, writer);
writer.startMethod(method_info);
path = path + "." + getName(abc).getName(abc.constants, fullyQualifiedNames, false, true);
toStringHeader(parent, convertData, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel);
int bodyIndex = abc.findBodyIndex(method_info);
if (classIndex != -1 && abc.instance_info.get(classIndex).isInterface() || bodyIndex == -1) {
writer.appendNoHilight(";");
} else {
writer.startBlock();
if (exportMode != ScriptExportMode.AS_METHOD_STUBS) {
if (exportMode != ScriptExportMode.AS) {
convertTraitHeader(abc, writer);
}
if (bodyIndex != -1) {
abc.bodies.get(bodyIndex).toString(path, exportMode, abc, this, writer, fullyQualifiedNames);
}
} else {
String retTypeRaw = abc.method_info.get(method_info).getReturnTypeRaw(abc.constants, fullyQualifiedNames);
switch (retTypeRaw) {
case "void":
break;
case "int":
case "uint":
writer.append("return 0; //autogenerated").newLine();
break;
case "double":
case "float":
writer.append("return 0.0; //autogenerated").newLine();
break;
case "String":
writer.append("return \"\"; //autogenerated").newLine();
break;
default:
writer.append("return null; //autogenerated").newLine();
break;
}
}
writer.endBlock();
}
writer.newLine();
writer.endMethod();
return writer;
}
@Override
public int removeTraps(int scriptIndex, int classIndex, boolean isStatic, ABC abc, String path) throws InterruptedException {
int bodyIndex = abc.findBodyIndex(method_info);
if (bodyIndex != -1) {
return abc.bodies.get(bodyIndex).removeTraps(abc, this, scriptIndex, classIndex, isStatic, path);
}
return 0;
}
@Override
public TraitMethodGetterSetter clone() {
TraitMethodGetterSetter ret = (TraitMethodGetterSetter) super.clone();
return ret;
}
@Override
public boolean isVisible(boolean isStatic, ABC abc) {
if (Configuration.handleSkinPartsAutomatically.get()) {
if ("skinParts".equals(getName(abc).getName(abc.constants, new ArrayList<>(), true, true))) {
if (kindType == TRAIT_GETTER) {
MethodInfo mi = abc.method_info.get(method_info);
if (mi.param_types.length == 0 && "Object".equals(abc.constants.getMultiname(mi.ret_type).getNameWithNamespace(abc.constants, true).toRawString())) {
if (abc.constants.getNamespace(abc.constants.getMultiname(name_index).namespace_index).kind == Namespace.KIND_PROTECTED) {
return false;
}
}
}
}
}
return true;
}
@Override
public GraphTextWriter convertTraitHeader(ABC abc, GraphTextWriter writer) {
switch (kindType) {
case Trait.TRAIT_METHOD:
convertCommonHeaderFlags("method", abc, writer);
break;
case Trait.TRAIT_GETTER:
convertCommonHeaderFlags("getter", abc, writer);
break;
case Trait.TRAIT_SETTER:
convertCommonHeaderFlags("setter", abc, writer);
break;
}
writer.newLine();
writer.appendNoHilight("dispid ");
writer.hilightSpecial("" + disp_id, HighlightSpecialType.DISP_ID);
writer.newLine();
return writer;
}
}