mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-25 10:30:46 +00:00
247 lines
10 KiB
Java
247 lines
10 KiB
Java
/*
|
|
* Copyright (C) 2011 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 2
|
|
* 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, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
package com.jpexs.asdec.abc.methodinfo_parser;
|
|
|
|
import com.jpexs.asdec.Main;
|
|
import com.jpexs.asdec.abc.ABC;
|
|
import com.jpexs.asdec.abc.types.MethodInfo;
|
|
import com.jpexs.asdec.abc.types.ValueKind;
|
|
import java.io.ByteArrayInputStream;
|
|
import java.io.IOException;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
/**
|
|
*
|
|
* @author JPEXS
|
|
*/
|
|
public class MethodInfoParser {
|
|
|
|
public static boolean parseReturnType(String text, MethodInfo update) throws ParseException {
|
|
MethodInfoLexer lexer = new MethodInfoLexer(new ByteArrayInputStream(text.getBytes()));
|
|
ParsedSymbol symb;
|
|
int type=-1;
|
|
try {
|
|
symb = lexer.yylex();
|
|
if(symb.type==ParsedSymbol.TYPE_STAR)
|
|
{
|
|
type=0;
|
|
}else if(symb.type==ParsedSymbol.TYPE_MULTINAME){
|
|
type=(int)(long)(Long)symb.value;
|
|
}else{
|
|
throw new ParseException("Multiname or * expected", lexer.yyline());
|
|
}
|
|
symb = lexer.yylex();
|
|
if(symb.type!=ParsedSymbol.TYPE_EOF)
|
|
{
|
|
throw new ParseException("Only one return type allowed", lexer.yyline());
|
|
}
|
|
update.ret_type=type;
|
|
return true;
|
|
} catch (IOException ex) {
|
|
|
|
}
|
|
return false;
|
|
}
|
|
public static boolean parseParams(String text, MethodInfo update,ABC abc) throws ParseException {
|
|
MethodInfoLexer lexer = new MethodInfoLexer(new ByteArrayInputStream(text.getBytes()));
|
|
List<String> paramNames=new ArrayList<String>();
|
|
List<Long> paramTypes=new ArrayList<Long>();
|
|
List<ValueKind> optionalValues=new ArrayList<ValueKind>();
|
|
boolean hasOptional=false;
|
|
boolean needsRest=false;
|
|
try {
|
|
ParsedSymbol symb;
|
|
symb = lexer.yylex();
|
|
while (symb.type != ParsedSymbol.TYPE_EOF)
|
|
{
|
|
if(symb.type==ParsedSymbol.TYPE_DOTS)
|
|
{
|
|
needsRest=true;
|
|
symb = lexer.yylex();
|
|
if(symb.type!=ParsedSymbol.TYPE_IDENTIFIER)
|
|
{
|
|
throw new ParseException("Identifier expected", lexer.yyline());
|
|
}
|
|
symb = lexer.yylex();
|
|
if(symb.type!=ParsedSymbol.TYPE_EOF)
|
|
{
|
|
throw new ParseException("End expected after rest params", lexer.yyline());
|
|
}
|
|
break;
|
|
}
|
|
|
|
if(symb.type!=ParsedSymbol.TYPE_IDENTIFIER)
|
|
{
|
|
throw new ParseException("Identifier expected", lexer.yyline());
|
|
}
|
|
paramNames.add((String)symb.value);
|
|
symb = lexer.yylex();
|
|
if(symb.type==ParsedSymbol.TYPE_COLON){
|
|
ParsedSymbol symbType=lexer.yylex();
|
|
if(symbType.type==ParsedSymbol.TYPE_STAR)
|
|
{
|
|
paramTypes.add(new Long(0));
|
|
}else if(symbType.type==ParsedSymbol.TYPE_MULTINAME){
|
|
paramTypes.add((Long)symbType.value);
|
|
}else{
|
|
throw new ParseException("Multiname or * expected", lexer.yyline());
|
|
}
|
|
ParsedSymbol symbEqual=lexer.yylex();
|
|
if(symbEqual.type==ParsedSymbol.TYPE_ASSIGN)
|
|
{
|
|
hasOptional=true;
|
|
ParsedSymbol symbValue;
|
|
String nstype="";
|
|
do{
|
|
symbValue=lexer.yylex();
|
|
if(symbValue.type>=8&&symbValue.type<=13){
|
|
nstype=nstype+symbValue.type+":";
|
|
}
|
|
}while(symbValue.type>=8&&symbValue.type<=13);
|
|
if((!nstype.equals(""))&&(symbValue.type!=ParsedSymbol.TYPE_NAMESPACE))
|
|
{
|
|
throw new ParseException("Namespace expected", lexer.yyline());
|
|
}
|
|
int id=0;
|
|
switch(symbValue.type)
|
|
{
|
|
case ParsedSymbol.TYPE_INTEGER:
|
|
optionalValues.add(new ValueKind(abc.constants.forceGetIntId((Long)symbValue.value),ValueKind.CONSTANT_Int));
|
|
break;
|
|
case ParsedSymbol.TYPE_FLOAT:
|
|
optionalValues.add(new ValueKind(abc.constants.forceGetDoubleId((Double)symbValue.value),ValueKind.CONSTANT_Double));
|
|
break;
|
|
case ParsedSymbol.TYPE_STRING:
|
|
optionalValues.add(new ValueKind(abc.constants.forceGetStringId((String)symbValue.value),ValueKind.CONSTANT_Utf8));
|
|
break;
|
|
case ParsedSymbol.TYPE_TRUE:
|
|
optionalValues.add(new ValueKind(0,ValueKind.CONSTANT_True));
|
|
break;
|
|
case ParsedSymbol.TYPE_FALSE:
|
|
optionalValues.add(new ValueKind(0,ValueKind.CONSTANT_False));
|
|
break;
|
|
case ParsedSymbol.TYPE_NULL:
|
|
optionalValues.add(new ValueKind(0,ValueKind.CONSTANT_Null));
|
|
break;
|
|
case ParsedSymbol.TYPE_UNDEFINED:
|
|
optionalValues.add(new ValueKind(0,ValueKind.CONSTANT_Undefined));
|
|
break;
|
|
case ParsedSymbol.TYPE_NAMESPACE:
|
|
if(nstype.equals("9:")){
|
|
optionalValues.add(new ValueKind((int)(long)(Long)symbValue.value,ValueKind.CONSTANT_PackageNamespace));
|
|
}else
|
|
if(nstype.equals("9:10:")){
|
|
optionalValues.add(new ValueKind((int)(long)(Long)symbValue.value,ValueKind.CONSTANT_PackageInternalNs));
|
|
}else
|
|
if(nstype.equals("13:")){
|
|
optionalValues.add(new ValueKind((int)(long)(Long)symbValue.value,ValueKind.CONSTANT_ProtectedNamespace));
|
|
}else
|
|
if(nstype.equals("12:")){
|
|
optionalValues.add(new ValueKind((int)(long)(Long)symbValue.value,ValueKind.CONSTANT_ExplicitNamespace));
|
|
}else
|
|
if(nstype.equals("11:13:")){
|
|
optionalValues.add(new ValueKind((int)(long)(Long)symbValue.value,ValueKind.CONSTANT_StaticProtectedNs));
|
|
}else
|
|
if(nstype.equals("8:")){
|
|
optionalValues.add(new ValueKind((int)(long)(Long)symbValue.value,ValueKind.CONSTANT_PrivateNs));
|
|
}else if(nstype.equals("")){
|
|
optionalValues.add(new ValueKind((int)(long)(Long)symbValue.value,ValueKind.CONSTANT_Namespace));
|
|
}else{
|
|
throw new ParseException("Invalid type of namespace", lexer.yyline());
|
|
}
|
|
break;
|
|
default:
|
|
throw new ParseException("Unexpected symbol", lexer.yyline());
|
|
}
|
|
symb=lexer.yylex();
|
|
if(symb.type==ParsedSymbol.TYPE_COMMA){
|
|
|
|
}else if(symb.type==ParsedSymbol.TYPE_EOF){
|
|
break;
|
|
}
|
|
}else if(symbEqual.type==ParsedSymbol.TYPE_COMMA){
|
|
if(hasOptional)
|
|
{
|
|
throw new ParseException("Parameter must have default value", lexer.yyline());
|
|
}
|
|
}else if(symbEqual.type==ParsedSymbol.TYPE_EOF){
|
|
if(hasOptional)
|
|
{
|
|
throw new ParseException("Parameter must have default value", lexer.yyline());
|
|
}
|
|
break;
|
|
} else {
|
|
throw new ParseException("Unexpected symbol", lexer.yyline());
|
|
}
|
|
}else if(symb.type==ParsedSymbol.TYPE_COMMA){
|
|
|
|
}else if(symb.type==ParsedSymbol.TYPE_EOF){
|
|
break;
|
|
}else{
|
|
throw new ParseException("Unexpected symbol", lexer.yyline());
|
|
}
|
|
symb = lexer.yylex();
|
|
}
|
|
} catch (IOException iex) {
|
|
return false;
|
|
}
|
|
|
|
if(needsRest&&(!optionalValues.isEmpty())){
|
|
throw new ParseException("Rest parameter canot be combined with default values", lexer.yyline());
|
|
}
|
|
|
|
update.param_types=new int[paramTypes.size()];
|
|
for(int p=0;p<paramTypes.size();p++)
|
|
{
|
|
update.param_types[p]=(int)(long)paramTypes.get(p);
|
|
}
|
|
update.optional=(ValueKind[])optionalValues.toArray(new ValueKind[optionalValues.size()]);
|
|
update.unsetFlagHas_optional();
|
|
if(!optionalValues.isEmpty()){
|
|
update.setFlagHas_optional();
|
|
}
|
|
update.unsetFlagNeed_rest();
|
|
if(needsRest){
|
|
update.setFlagNeed_rest();
|
|
}
|
|
|
|
update.unsetFlagHas_paramnames();
|
|
update.paramNames=new int[]{};
|
|
boolean useParamNames=false;
|
|
for(int p=0;p<paramNames.size();p++){
|
|
if(!paramNames.get(p).equals("param"+(p+1)))
|
|
{
|
|
useParamNames=true;
|
|
}
|
|
}
|
|
if(!Main.PARAM_NAMES_ENABLE){
|
|
useParamNames=false;
|
|
}
|
|
if(useParamNames){
|
|
update.setFlagHas_paramnames();
|
|
update.paramNames=new int[paramNames.size()];
|
|
for(int p=0;p<paramNames.size();p++){
|
|
update.paramNames[p]=abc.constants.forceGetStringId(paramNames.get(p));
|
|
}
|
|
}
|
|
return true;
|
|
|
|
}
|
|
}
|