@Override public GenericParameter findTypeVariable(final String name) { for (final GenericParameter genericParameter : getGenericParameters()) { if (StringUtilities.equals(genericParameter.getName(), name)) { return genericParameter; } } final MethodReference declaringMethod = getDeclaringMethod(); if (declaringMethod != null) { return declaringMethod.findTypeVariable(name); } final TypeReference declaringType = getDeclaringType(); if (declaringType != null && !this.isStatic()) { return declaringType.findTypeVariable(name); } return null; }
@Override public Void visitInvocationExpression(final InvocationExpression node, final Void data) { super.visitInvocationExpression(node, data); final AstNodeCollection<Expression> arguments = node.getArguments(); final Expression lastArgument = arguments.lastOrNullObject(); Expression arrayArg = lastArgument; if (arrayArg instanceof CastExpression) arrayArg = ((CastExpression) arrayArg).getExpression(); if (arrayArg == null || arrayArg.isNull() || !(arrayArg instanceof ArrayCreationExpression && node.getTarget() instanceof MemberReferenceExpression)) { return null; } final ArrayCreationExpression newArray = (ArrayCreationExpression) arrayArg; final MemberReferenceExpression target = (MemberReferenceExpression) node.getTarget(); if (!newArray.getAdditionalArraySpecifiers().hasSingleElement()) { return null; } final MethodReference method = (MethodReference) node.getUserData(Keys.MEMBER_REFERENCE); if (method == null) { return null; } final MethodDefinition resolved = method.resolve(); if (resolved == null || !resolved.isVarArgs()) { return null; } final List<MethodReference> candidates; final Expression invocationTarget = target.getTarget(); if (invocationTarget == null || invocationTarget.isNull()) { candidates = MetadataHelper.findMethods( context.getCurrentType(), MetadataFilters.matchName(resolved.getName())); } else { final ResolveResult targetResult = _resolver.apply(invocationTarget); if (targetResult == null || targetResult.getType() == null) { return null; } candidates = MetadataHelper.findMethods( targetResult.getType(), MetadataFilters.matchName(resolved.getName())); } final List<TypeReference> argTypes = new ArrayList<>(); for (final Expression argument : arguments) { final ResolveResult argResult = _resolver.apply(argument); if (argResult == null || argResult.getType() == null) { return null; } argTypes.add(argResult.getType()); } final MethodBinder.BindResult c1 = MethodBinder.selectMethod(candidates, argTypes); if (c1.isFailure() || c1.isAmbiguous()) { return null; } argTypes.remove(argTypes.size() - 1); final ArrayInitializerExpression initializer = newArray.getInitializer(); final boolean hasElements = !initializer.isNull() && !initializer.getElements().isEmpty(); if (hasElements) { for (final Expression argument : initializer.getElements()) { final ResolveResult argResult = _resolver.apply(argument); if (argResult == null || argResult.getType() == null) { return null; } argTypes.add(argResult.getType()); } } final MethodBinder.BindResult c2 = MethodBinder.selectMethod(candidates, argTypes); if (c2.isFailure() || c2.isAmbiguous() || !StringUtilities.equals( c2.getMethod().getErasedSignature(), c1.getMethod().getErasedSignature())) { return null; } lastArgument.remove(); if (!hasElements) { return null; } for (final Expression newArg : initializer.getElements()) { newArg.remove(); arguments.add(newArg); } return null; }
/** @author DeathMarine */ private void doSaveJarDecompiled(File inFile, File outFile) throws Exception { try (JarFile jfile = new JarFile(inFile); FileOutputStream dest = new FileOutputStream(outFile); BufferedOutputStream buffDest = new BufferedOutputStream(dest); ZipOutputStream out = new ZipOutputStream(buffDest); ) { byte data[] = new byte[1024]; DecompilerSettings settings = getDecompilerSettings(); LuytenTypeLoader typeLoader = new LuytenTypeLoader(); MetadataSystem metadataSystem = new MetadataSystem(typeLoader); ITypeLoader jarLoader = new JarTypeLoader(jfile); typeLoader.getTypeLoaders().add(jarLoader); DecompilationOptions decompilationOptions = new DecompilationOptions(); decompilationOptions.setSettings(settings); decompilationOptions.setFullDecompilation(true); Enumeration<JarEntry> ent = jfile.entries(); Set<JarEntry> history = new HashSet<JarEntry>(); while (ent.hasMoreElements()) { JarEntry entry = ent.nextElement(); if (entry.getName().endsWith(".class")) { JarEntry etn = new JarEntry(entry.getName().replace(".class", ".java")); if (history.add(etn)) { out.putNextEntry(etn); try { String internalName = StringUtilities.removeRight(entry.getName(), ".class"); TypeReference type = metadataSystem.lookupType(internalName); TypeDefinition resolvedType = null; if ((type == null) || ((resolvedType = type.resolve()) == null)) { throw new Exception("Unable to resolve type."); } Writer writer = new OutputStreamWriter(out); settings .getLanguage() .decompileType(resolvedType, new PlainTextOutput(writer), decompilationOptions); writer.flush(); } finally { out.closeEntry(); } } } else { try { JarEntry etn = new JarEntry(entry.getName()); if (history.add(etn)) continue; history.add(etn); out.putNextEntry(etn); try { InputStream in = jfile.getInputStream(entry); if (in != null) { try { int count; while ((count = in.read(data, 0, 1024)) != -1) { out.write(data, 0, count); } } finally { in.close(); } } } finally { out.closeEntry(); } } catch (ZipException ze) { // some jar-s contain duplicate pom.xml entries: ignore // it if (!ze.getMessage().contains("duplicate")) { throw ze; } } } } } }