diff --git a/lib/procyon-compilertools-0.5.29.jar b/lib/procyon-compilertools-0.5.29.jar deleted file mode 100644 index 5c77e99..0000000 Binary files a/lib/procyon-compilertools-0.5.29.jar and /dev/null differ diff --git a/lib/procyon-core-0.5.29.jar b/lib/procyon-core-0.5.29.jar deleted file mode 100644 index 38db5e0..0000000 Binary files a/lib/procyon-core-0.5.29.jar and /dev/null differ diff --git a/lib/procyon-decompiler-0.5.29.jar b/lib/procyon-decompiler-0.5.29.jar deleted file mode 100644 index 6888b80..0000000 Binary files a/lib/procyon-decompiler-0.5.29.jar and /dev/null differ diff --git a/pom.xml b/pom.xml index bca4f44..f3f0cab 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.scalatojava scala-to-java - 1.0.1 + 1.0.2 jar @@ -43,31 +43,10 @@ scala-reflect ${scala.version} - - - - - org.bitbucket.mstrobel procyon-compilertools 0.5.29 - system - ${project.basedir}/lib/procyon-compilertools-0.5.29.jar - - - org.bitbucket.mstrobel - procyon-core - 0.5.29 - system - ${project.basedir}/lib/procyon-core-0.5.29.jar - - - org.bitbucket.mstrobel - procyon-decompiler - 0.5.29 - system - ${project.basedir}/lib/procyon-decompiler-0.5.29.jar org.scalatest @@ -155,9 +134,11 @@ com.github.scalatojava.Main - - jar-with-dependencies - + + + src/assembly/jar-with-dependencies-override.xml + + scala-to-java false diff --git a/src/assembly/jar-with-dependencies-override.xml b/src/assembly/jar-with-dependencies-override.xml new file mode 100644 index 0000000..2207c9a --- /dev/null +++ b/src/assembly/jar-with-dependencies-override.xml @@ -0,0 +1,25 @@ + + jar-with-dependencies-override + + jar + + false + + + / + true + true + runtime + + + + + ${project.build.directory}/classes + / + + + \ No newline at end of file diff --git a/src/main/java/com/strobel/assembler/metadata/CoreMetadataFactory.java b/src/main/java/com/strobel/assembler/metadata/CoreMetadataFactory.java new file mode 100644 index 0000000..a4ef696 --- /dev/null +++ b/src/main/java/com/strobel/assembler/metadata/CoreMetadataFactory.java @@ -0,0 +1,769 @@ +/* + * CoreMetadataFactory.java + * + * Copyright (c) 2013 Mike Strobel + * + * This source code is based on Mono.Cecil from Jb Evain, Copyright (c) Jb + * Evain; + * and ILSpy/ICSharpCode from SharpDevelop, Copyright (c) AlphaSierraPapa. + * + * This source code is subject to terms and conditions of the Apache License, + * Version 2.0. + * A copy of the license can be found in the License.html file at the root of + * this distribution. + * By using this source code in any fashion, you are agreeing to be bound by + * the terms of the + * Apache License, Version 2.0. + * + * You must not remove this notice, or any other, from this software. + */ + +package com.strobel.assembler.metadata; + +import com.strobel.assembler.ir.attributes.AttributeNames; +import com.strobel.assembler.ir.attributes.InnerClassEntry; +import com.strobel.assembler.ir.attributes.InnerClassesAttribute; +import com.strobel.assembler.ir.attributes.SourceAttribute; +import com.strobel.assembler.metadata.signatures.*; +import com.strobel.core.ArrayUtilities; +import com.strobel.core.StringUtilities; +import com.strobel.core.VerifyArgument; + +import java.util.List; +import java.util.Stack; + +/** + * I had to patch this class in order to make it decompile class + * name like '_$$anon$1$A$'. + */ +public class CoreMetadataFactory implements MetadataFactory { + private final TypeDefinition _owner; + private final IMetadataResolver _resolver; + private final IGenericContext _scope; + private final Stack _tempScope; + + private CoreMetadataFactory(final TypeDefinition owner, final + IMetadataResolver resolver, final IGenericContext scope) { + _owner = owner; + _resolver = resolver; + _scope = scope; + _tempScope = new Stack<>(); + } + + public static CoreMetadataFactory make(final TypeDefinition owner, final + IGenericContext scope) { + return new CoreMetadataFactory(VerifyArgument.notNull(owner, "owner") + , owner.getResolver(), scope); + } + + public static CoreMetadataFactory make(final IMetadataResolver resolver, + final IGenericContext scope) { + return new CoreMetadataFactory(null, resolver, scope); + } + + private IGenericContext getScope() { + return _scope; + } + + public GenericParameter makeTypeVariable(final String name, final + FieldTypeSignature[] bounds) { + final GenericParameter genericParameter = new GenericParameter(name); + + if (ArrayUtilities.isNullOrEmpty(bounds)) { + return genericParameter; + } + + _tempScope.push(genericParameter); + + try { + final TypeReference extendsBound = makeTypeBound(bounds); + genericParameter.setExtendsBound(extendsBound); + return genericParameter; + } finally { + _tempScope.pop(); + } + } + + public WildcardType makeWildcard( + final FieldTypeSignature superBound, + final FieldTypeSignature extendsBound) { + + if (superBound == null || superBound == BottomSignature.make()) { + if (extendsBound == null || + (extendsBound instanceof SimpleClassTypeSignature && + StringUtilities.equals("java.lang.Object", ( + (SimpleClassTypeSignature) extendsBound) + .getName()))) { + + return WildcardType.unbounded(); + } + + return WildcardType.makeExtends(makeTypeBound(extendsBound)); + } else { + return WildcardType.makeSuper(makeTypeBound(superBound)); + } + } + + protected TypeReference makeTypeBound(final FieldTypeSignature... bounds) { + final TypeReference baseType; + final List interfaceTypes; + + Reifier reifier = null; + + if (ArrayUtilities.isNullOrEmpty(bounds)) { + return null; + } + + if (bounds[0] != BottomSignature.make()) { + reifier = Reifier.make(this); + bounds[0].accept(reifier); + baseType = reifier.getResult(); + assert baseType != null; + } else { + baseType = null; + } + + if (bounds.length == 1) { + return baseType; + } + + if (reifier == null) { + reifier = Reifier.make(this); + } + + if (bounds.length == 2 && baseType == null) { + bounds[1].accept(reifier); + final TypeReference singleInterface = reifier.getResult(); + assert singleInterface != null; + return singleInterface; + } + + final TypeReference[] it = new TypeReference[bounds.length - 1]; + + for (int i = 0; i < it.length; i++) { + bounds[i + 1].accept(reifier); + it[i] = reifier.getResult(); + assert it[i] != null; + } + + interfaceTypes = ArrayUtilities.asUnmodifiableList(it); + + return new CompoundTypeReference(baseType, interfaceTypes); + } + + public TypeReference makeParameterizedType( + final TypeReference declaration, + final TypeReference owner, + final TypeReference... typeArguments) { + + if (typeArguments.length == 0) { + return declaration; + } + return declaration.makeGenericType(typeArguments); + } + + public GenericParameter findTypeVariable(final String name) { + for (int i = _tempScope.size() - 1; i >= 0; i--) { + final GenericParameter genericParameter = _tempScope.get(i); + + if (genericParameter != null && StringUtilities.equals + (genericParameter.getName(), name)) { + return genericParameter; + } + } + + final IGenericContext scope = getScope(); + + if (scope != null) { + return scope.findTypeVariable(name); + } + + return null; + } + + private InnerClassEntry findInnerClassEntry(final String name) { + if (_owner == null) { + return null; + } + + final String internalName = name.replace('.', '/'); + final SourceAttribute attribute = SourceAttribute.find(AttributeNames + .InnerClasses, _owner.getSourceAttributes()); + + if (attribute instanceof InnerClassesAttribute) { + final List entries = ((InnerClassesAttribute) + attribute).getEntries(); + + for (final InnerClassEntry entry : entries) { + if (StringUtilities.equals(entry.getInnerClassName(), + internalName)) { + return entry; + } + } + } + + return null; + } + + public TypeReference makeNamedType(final String name) { + final int length = name.length(); + + final InnerClassEntry entry = findInnerClassEntry(name); + + if (entry != null) { + final String innerClassName = entry.getInnerClassName(); + final int packageEnd = innerClassName.lastIndexOf('/'); + final String shortName = StringUtilities.isNullOrEmpty(entry + .getShortName()) ? null : entry.getShortName(); + final TypeReference declaringType; + + if (!StringUtilities.isNullOrEmpty(entry.getOuterClassName())) { + declaringType = makeNamedType(entry.getOuterClassName() + .replace('/', '.')); + } else { + int lastDollarIndex = name.lastIndexOf('$'); + + while (lastDollarIndex >= 1 && + lastDollarIndex < length && + name.charAt(lastDollarIndex - 1) == '$') { + + if (lastDollarIndex > 1) { + lastDollarIndex = name.lastIndexOf(lastDollarIndex, + lastDollarIndex - 2); + } else { + lastDollarIndex = -1; + } + } + + if (lastDollarIndex == length - 1) { + lastDollarIndex = -1; + } + + if (lastDollarIndex != -1) { + declaringType = makeNamedType(name.substring(0, + lastDollarIndex).replace('/', '.')); + } else { + return new UnresolvedType( + packageEnd < 0 ? innerClassName : innerClassName + .substring(packageEnd + 1), + name, null); + } + + } + + return new UnresolvedType( + declaringType, + packageEnd < 0 ? innerClassName : innerClassName + .substring(packageEnd + 1), + shortName + ); + } + + final int packageEnd = name.lastIndexOf('.'); + + if (packageEnd < 0) { + return new UnresolvedType(StringUtilities.EMPTY, name, null); + } + + return new UnresolvedType( + packageEnd < 0 ? StringUtilities.EMPTY : name.substring(0, + packageEnd), + packageEnd < 0 ? name : name.substring(packageEnd + 1), + null + ); + } + + public TypeReference makeArrayType(final TypeReference componentType) { + return componentType.makeArrayType(); + } + + public TypeReference makeByte() { + return BuiltinTypes.Byte; + } + + public TypeReference makeBoolean() { + return BuiltinTypes.Boolean; + } + + public TypeReference makeShort() { + return BuiltinTypes.Short; + } + + public TypeReference makeChar() { + return BuiltinTypes.Character; + } + + public TypeReference makeInt() { + return BuiltinTypes.Integer; + } + + public TypeReference makeLong() { + return BuiltinTypes.Long; + } + + public TypeReference makeFloat() { + return BuiltinTypes.Float; + } + + public TypeReference makeDouble() { + return BuiltinTypes.Double; + } + + public TypeReference makeVoid() { + return BuiltinTypes.Void; + } + + @Override + public IMethodSignature makeMethodSignature( + final TypeReference returnType, + final List parameterTypes, + final List genericParameters, + final List thrownTypes) { + + return new MethodSignature( + parameterTypes, + returnType, + genericParameters, + thrownTypes + ); + } + + @Override + public IClassSignature makeClassSignature( + final TypeReference baseType, + final List interfaceTypes, + final List genericParameters) { + + return new ClassSignature(baseType, interfaceTypes, genericParameters); + } + + private final static class ClassSignature implements IClassSignature { + private final TypeReference _baseType; + private final List _interfaceTypes; + private final List _genericParameters; + + private ClassSignature( + final TypeReference baseType, + final List interfaceTypes, + final List genericParameters) { + + _baseType = VerifyArgument.notNull(baseType, "baseType"); + _interfaceTypes = VerifyArgument.noNullElements(interfaceTypes, + "interfaceTypes"); + _genericParameters = VerifyArgument.noNullElements + (genericParameters, "genericParameters"); + } + + @Override + public TypeReference getBaseType() { + return _baseType; + } + + @Override + public List getExplicitInterfaces() { + return _interfaceTypes; + } + + @Override + public boolean hasGenericParameters() { + return !_genericParameters.isEmpty(); + } + + @Override + public boolean isGenericDefinition() { + return false; + } + + @Override + public List getGenericParameters() { + return _genericParameters; + } + } + + private final static class MethodSignature implements IMethodSignature { + private final List _parameters; + private final TypeReference _returnType; + private final List _genericParameters; + private final List _thrownTypes; + + MethodSignature( + final List parameterTypes, + final TypeReference returnType, + final List genericParameters, + final List thrownTypes) { + + VerifyArgument.notNull(parameterTypes, "parameterTypes"); + VerifyArgument.notNull(returnType, "returnType"); + VerifyArgument.notNull(genericParameters, "genericParameters"); + VerifyArgument.notNull(thrownTypes, "thrownTypes"); + + final ParameterDefinition[] parameters = new + ParameterDefinition[parameterTypes.size()]; + + for (int i = 0, slot = 0, n = parameters.length; i < n; i++, + slot++) { + final TypeReference parameterType = parameterTypes.get(i); + + parameters[i] = new ParameterDefinition(slot, parameterType); + + if (parameterType.getSimpleType().isDoubleWord()) { + slot++; + } + } + + _parameters = ArrayUtilities.asUnmodifiableList(parameters); + _returnType = returnType; + _genericParameters = genericParameters; + _thrownTypes = thrownTypes; + } + + @Override + public boolean hasParameters() { + return !_parameters.isEmpty(); + } + + @Override + public List getParameters() { + return _parameters; + } + + @Override + public TypeReference getReturnType() { + return _returnType; + } + + @Override + public List getThrownTypes() { + return _thrownTypes; + } + + @Override + public boolean hasGenericParameters() { + return !_genericParameters.isEmpty(); + } + + @Override + public boolean isGenericDefinition() { + return !_genericParameters.isEmpty(); + } + + @Override + public List getGenericParameters() { + return _genericParameters; + } + + @Override + public GenericParameter findTypeVariable(final String name) { + for (final GenericParameter genericParameter : + getGenericParameters()) { + if (StringUtilities.equals(genericParameter.getName(), name)) { + return genericParameter; + } + } + + return null; + } + } + + private final class UnresolvedType extends TypeReference { + private final String _name; + private final String _shortName; + private final String _packageName; + private final GenericParameterCollection _genericParameters; + + private String _fullName; + private String _internalName; + private String _signature; + private String _erasedSignature; + + UnresolvedType(final TypeReference declaringType, final String name, + final String shortName) { + _name = VerifyArgument.notNull(name, "name"); + _shortName = shortName; + setDeclaringType(VerifyArgument.notNull(declaringType, + "declaringType")); + _packageName = declaringType.getPackageName(); + _genericParameters = new GenericParameterCollection(this); + _genericParameters.freeze(); + } + + UnresolvedType(final String packageName, final String name, final + String shortName) { + _packageName = VerifyArgument.notNull(packageName, "packageName"); + _name = VerifyArgument.notNull(name, "name"); + _shortName = shortName; + _genericParameters = new GenericParameterCollection(this); + _genericParameters.freeze(); + } + + UnresolvedType(final TypeReference declaringType, final String name, + final String shortName, final List + genericParameters) { + _name = VerifyArgument.notNull(name, "name"); + _shortName = shortName; + setDeclaringType(VerifyArgument.notNull(declaringType, + "declaringType")); + _packageName = declaringType.getPackageName(); + + _genericParameters = new GenericParameterCollection(this); + + for (final GenericParameter genericParameter : genericParameters) { + _genericParameters.add(genericParameter); + } + + _genericParameters.freeze(); + } + + UnresolvedType(final String packageName, final String name, final + String shortName, final List genericParameters) { + _packageName = VerifyArgument.notNull(packageName, "packageName"); + _name = VerifyArgument.notNull(name, "name"); + _shortName = shortName; + + _genericParameters = new GenericParameterCollection(this); + + for (final GenericParameter genericParameter : genericParameters) { + _genericParameters.add(genericParameter); + } + } + + @Override + public String getName() { + return _name; + } + + @Override + public String getPackageName() { + return _packageName; + } + + public String getFullName() { + if (_fullName == null) { + _fullName = super.getFullName(); + } + return _fullName; + } + + @Override + public String getErasedSignature() { + if (_erasedSignature == null) { + _erasedSignature = super.getErasedSignature(); + } + return _erasedSignature; + } + + @Override + public String getSignature() { + if (_signature == null) { + _signature = super.getSignature(); + } + return _signature; + } + + public String getInternalName() { + if (_internalName == null) { + _internalName = super.getInternalName(); + } + return _internalName; + } + + @Override + public R accept(final TypeMetadataVisitor visitor, final + P parameter) { + return visitor.visitClassType(this, parameter); + } + + @Override + public String getSimpleName() { + return _shortName != null ? _shortName : _name; + } + + @Override + public boolean isGenericDefinition() { + return hasGenericParameters(); + } + + @Override + public List getGenericParameters() { + return _genericParameters; + } + + @Override + public TypeReference makeGenericType(final List typeArguments) { + VerifyArgument.noNullElementsAndNotEmpty(typeArguments, + "typeArguments"); + + return new UnresolvedGenericType( + this, + ArrayUtilities.asUnmodifiableList(typeArguments.toArray(new + TypeReference[typeArguments.size()])) + ); + } + + @Override + public TypeReference makeGenericType(final TypeReference... + typeArguments) { + VerifyArgument.noNullElementsAndNotEmpty(typeArguments, + "typeArguments"); + + return new UnresolvedGenericType( + this, + ArrayUtilities.asUnmodifiableList(typeArguments.clone()) + ); + } + + @Override + public TypeDefinition resolve() { + return _resolver.resolve(this); + } + + @Override + public FieldDefinition resolve(final FieldReference field) { + return _resolver.resolve(field); + } + + @Override + public MethodDefinition resolve(final MethodReference method) { + return _resolver.resolve(method); + } + + @Override + public TypeDefinition resolve(final TypeReference type) { + return _resolver.resolve(type); + } + } + + private final class UnresolvedGenericType extends TypeReference + implements IGenericInstance { + private final TypeReference _genericDefinition; + private final List _typeParameters; + + private String _signature; + + UnresolvedGenericType(final TypeReference genericDefinition, final + List typeParameters) { + _genericDefinition = genericDefinition; + _typeParameters = typeParameters; + } + + @Override + public TypeReference getElementType() { + return null; + } + + @Override + public R accept(final TypeMetadataVisitor visitor, final + P parameter) { + return visitor.visitParameterizedType(this, parameter); + } + + @Override + public String getName() { + return _genericDefinition.getName(); + } + + @Override + public String getPackageName() { + return _genericDefinition.getPackageName(); + } + + @Override + public TypeReference getDeclaringType() { + return _genericDefinition.getDeclaringType(); + } + + @Override + public String getSimpleName() { + return _genericDefinition.getSimpleName(); + } + + @Override + public String getFullName() { + return _genericDefinition.getFullName(); + } + + @Override + public String getInternalName() { + return _genericDefinition.getInternalName(); + } + + @Override + public String getSignature() { + if (_signature == null) { + _signature = super.getSignature(); + } + return _signature; + } + + @Override + public String getErasedSignature() { + return _genericDefinition.getErasedSignature(); + } + + @Override + public boolean isGenericDefinition() { + return false; + } + + @Override + public boolean isGenericType() { + return true; + } + + @Override + public List getGenericParameters() { + if (!_genericDefinition.isGenericDefinition()) { + final TypeDefinition resolvedDefinition = _genericDefinition + .resolve(); + + if (resolvedDefinition != null) { + return resolvedDefinition.getGenericParameters(); + } + } + + return _genericDefinition.getGenericParameters(); + } + + @Override + public boolean hasTypeArguments() { + return true; + } + + @Override + public List getTypeArguments() { + return _typeParameters; + } + + @Override + public IGenericParameterProvider getGenericDefinition() { + return _genericDefinition; + } + + @Override + public TypeReference getUnderlyingType() { + return _genericDefinition; + } + + @Override + public TypeDefinition resolve() { + return _resolver.resolve(this); + } + + @Override + public FieldDefinition resolve(final FieldReference field) { + return _resolver.resolve(field); + } + + @Override + public MethodDefinition resolve(final MethodReference method) { + return _resolver.resolve(method); + } + + @Override + public TypeDefinition resolve(final TypeReference type) { + return _resolver.resolve(type); + } + } +} +