Java tutorial
/* * Copyright 2017-present Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may obtain * a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package com.facebook.buck.jvm.java.abi; import static org.junit.Assert.fail; import com.facebook.buck.jvm.java.testutil.compiler.TestCompiler; import com.facebook.buck.testutil.integration.TestDataHelper; import java.io.IOException; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.function.Function; import javax.lang.model.element.Element; import javax.lang.model.element.Name; import javax.lang.model.element.TypeElement; import javax.lang.model.util.Elements; import org.junit.Before; import org.junit.Rule; import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.FieldNode; import org.objectweb.asm.tree.MethodNode; public class DescriptorAndSignatureFactoryTestBase { @Rule public TestCompiler testCompiler = new TestCompiler(); protected Elements elements; List<String> errors = new ArrayList<>(); @Before public void setUp() throws IOException { Path sourceFile = TestDataHelper.getTestDataScenario(this, "descriptor_and_signature_factories") .resolve("Foo.java"); testCompiler.addSourceFile(sourceFile); elements = testCompiler.getElements(); testCompiler.compile(); } protected List<String> getTestErrors(Function<FieldNode, String> fieldNodeExpectedValueGetter, Function<MethodNode, String> methodNodeExpectedValueGetter, Function<ClassNode, String> classNodeExpectedValueGetter, Function<Element, String> elementActualValueGetter) throws IOException { TypeElement fooElement = elements.getTypeElement("com.facebook.foo.Foo"); findErrors(fooElement, fieldNodeExpectedValueGetter, methodNodeExpectedValueGetter, classNodeExpectedValueGetter, elementActualValueGetter); return errors; } private void findErrors(TypeElement typeElement, Function<FieldNode, String> fieldNodeExpectedValueGetter, Function<MethodNode, String> methodNodeExpectedValueGetter, Function<ClassNode, String> classNodeExpectedValueGetter, Function<Element, String> elementActualValueGetter) throws IOException { ClassNode typeNode = getClassNode(elements.getBinaryName(typeElement).toString()); for (Element enclosedElement : typeElement.getEnclosedElements()) { Name elementName = enclosedElement.getSimpleName(); String actual = elementActualValueGetter.apply(enclosedElement); switch (enclosedElement.getKind()) { case FIELD: checkValue("Field", elementName, fieldNodeExpectedValueGetter.apply(getFieldNode(typeNode, elementName)), actual); break; case CONSTRUCTOR: case METHOD: checkValue("Method", elementName, methodNodeExpectedValueGetter.apply(getMethodNode(typeNode, elementName)), actual); break; case ANNOTATION_TYPE: case CLASS: case ENUM: case INTERFACE: ClassNode innerTypeNode = getClassNode( elements.getBinaryName((TypeElement) enclosedElement).toString()); checkValue("Class", elementName, classNodeExpectedValueGetter.apply(innerTypeNode), actual); findErrors((TypeElement) enclosedElement, fieldNodeExpectedValueGetter, methodNodeExpectedValueGetter, classNodeExpectedValueGetter, elementActualValueGetter); break; // $CASES-OMITTED$ default: fail(String.format("Didn't implement testing for element kind %s", enclosedElement.getKind())); continue; } } } private void checkValue(String type, Name elementName, String expected, String actual) { if (expected != actual && (expected == null || !expected.equals(actual))) { errors.add(String.format("%s %s:\n\tExpected: %s\n\tActual: %s", type, elementName, expected, actual)); } } private FieldNode getFieldNode(ClassNode classNode, Name name) { return classNode.fields.stream().filter(field -> name.contentEquals(field.name)).findFirst().orElse(null); } private MethodNode getMethodNode(ClassNode classNode, Name name) { return classNode.methods.stream().filter(field -> name.contentEquals(field.name)).findFirst().orElse(null); } private ClassNode getClassNode(String classBinaryName) throws IOException { ClassNode classNode = new ClassNode(Opcodes.ASM5); testCompiler.getClasses().acceptClassVisitor(classBinaryName, 0, classNode); return classNode; } }