| // Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| package com.android.tools.r8.naming; |
| |
| import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage; |
| import static com.android.tools.r8.DiagnosticsMatcher.diagnosticPosition; |
| import static com.android.tools.r8.DiagnosticsMatcher.diagnosticType; |
| import static com.android.tools.r8.PositionMatcher.positionLine; |
| import static junit.framework.TestCase.assertEquals; |
| import static junit.framework.TestCase.assertFalse; |
| import static junit.framework.TestCase.assertNotNull; |
| import static junit.framework.TestCase.assertTrue; |
| import static org.hamcrest.CoreMatchers.allOf; |
| import static org.hamcrest.core.StringContains.containsString; |
| |
| import com.android.tools.r8.TestDiagnosticMessagesImpl; |
| import com.android.tools.r8.naming.MemberNaming.MethodSignature; |
| import com.android.tools.r8.naming.mappinginformation.MappingInformationDiagnostics; |
| import com.android.tools.r8.utils.Reporter; |
| import com.android.tools.r8.utils.StringUtils; |
| import com.google.common.collect.ImmutableList; |
| import java.io.IOException; |
| import java.util.List; |
| import org.junit.Before; |
| import org.junit.Test; |
| |
| public class ProguardMapReaderArgumentsTest { |
| |
| private Reporter reporter; |
| private TestDiagnosticMessagesImpl testDiagnosticMessages; |
| |
| @Before |
| public void setUp() { |
| testDiagnosticMessages = new TestDiagnosticMessagesImpl(); |
| reporter = new Reporter(testDiagnosticMessages); |
| } |
| |
| @Test |
| public void testMethodCanParseMemberComments() throws IOException { |
| String mapWithArgumentRemovalInformation = |
| StringUtils.join( |
| "\n", |
| "android.constraint.Placeholder -> a.b.b.f:", |
| "# Just a comment", // Regular comment |
| " int mContentId -> b", |
| "# {}", // Valid JSON with no information |
| " 147:161:void updatePreLayout(android.constraint.Layout) -> a", |
| "# {foo:bar}}}", // Not valid JSON |
| " 194:204:void updatePostMeasure(android.constraint.Layout) -> b", |
| "# { 'id': 'bar' }", // Valid json but no handler for bar. |
| " 194:204:void updatePostMeasure(android.constraint.Layout) -> c"); |
| ClassNameMapper cnm = |
| ClassNameMapper.mapperFromString(mapWithArgumentRemovalInformation, reporter); |
| ClassNamingForNameMapper classNaming = cnm.getClassNaming("a.b.b.f"); |
| assertNotNull(classNaming); |
| testDiagnosticMessages.assertOnlyInfos(); |
| testDiagnosticMessages |
| .assertInfosMatch( |
| ImmutableList.of( |
| allOf( |
| diagnosticMessage(containsString("Could not locate 'id'")), |
| diagnosticPosition(positionLine(4))), |
| allOf( |
| diagnosticMessage(containsString("Not valid JSON")), |
| diagnosticPosition(positionLine(6))), |
| allOf( |
| diagnosticMessage(containsString("Could not find a handler for bar")), |
| diagnosticPosition(positionLine(8))))) |
| .assertAllInfosMatch(diagnosticType(MappingInformationDiagnostics.class)); |
| } |
| |
| @Test |
| public void testMethodWillReportWhenParsingArgumentsChangedMemberComments() throws IOException { |
| String mapWithArgumentRemovalInformation = |
| StringUtils.join( |
| "\n", |
| "android.constraint.Placeholder -> a.b.b.f:", |
| "# Just a comment", // Regular comment |
| " int mContentId -> b", |
| // Valid JSON but missing signature |
| "# { 'id': 'methodSignatureChanged', " |
| + "'signature': ['void', 'updatePreLayout', 'android.constraint.Layout']," |
| + "'returnType': [], 'receiver': true, 'params': []}", |
| " 147:161:void updatePreLayout(android.constraint.Layout) -> a", |
| // Valid JSON but not an argumentsChanged object |
| "# { 'id': 'methodSignatureChanged', " |
| + "'signature': ['void', 'updatePreLayout', 'android.constraint.Layout']," |
| + "'returnType': [], 'receiver': true, 'params': []}", |
| " 147:161:void updatePreLayout(android.constraint.Layout) -> a", |
| // Valid JSON but not an arguments_changed object. |
| "# { 'id': 'methodSignatureChanged', " |
| + "'signature': ['void','updatePreLayout','android.constraint.Layout']," |
| + "'returnType': 'foo', 'receiver': 1, 'params': 'foo' }", |
| " 194:204:void updatePostMeasure(android.constraint.Layout) -> a") |
| .replace("'", "\""); |
| ClassNameMapper cnm = |
| ClassNameMapper.mapperFromString(mapWithArgumentRemovalInformation, reporter); |
| ClassNamingForNameMapper classNaming = cnm.getClassNaming("a.b.b.f"); |
| assertNotNull(classNaming); |
| testDiagnosticMessages.assertOnlyInfos(); |
| testDiagnosticMessages |
| .assertInfosMatch( |
| ImmutableList.of( |
| allOf( |
| diagnosticMessage(containsString("Could not decode")), |
| diagnosticPosition(positionLine(4))), |
| allOf( |
| diagnosticMessage(containsString("Could not decode")), |
| diagnosticPosition(positionLine(6))), |
| allOf( |
| diagnosticMessage(containsString("Could not decode")), |
| diagnosticPosition(positionLine(8))))) |
| .assertAllInfosMatch(diagnosticType(MappingInformationDiagnostics.class)); |
| } |
| |
| @Test |
| public void testMethodCanParseArgumentRemoval() throws IOException { |
| String mapWithArgumentRemovalInformation = |
| StringUtils.lines( |
| "android.constraint.Placeholder -> a.b.b.f:", |
| " int mContentId -> b", |
| "# { 'id': 'methodSignatureChanged'," |
| + "'signature': [" |
| + "'void','updatePreLayout','android.constraint.Layout','String','int']," |
| + " 'returnType': 'void', 'receiver': true, 'params':[[1],[2]]}", |
| " 147:161:void updatePreLayout(android.constraint.Layout,String,int) -> a", |
| "# {'id':'methodSignatureChanged'," |
| + "'signature': [" |
| + "'void','updatePreMeasure','android.constraint.Layout','String','int']," |
| + "'returnType': 'void', 'receiver': true, 'params':[[3]]}", |
| " 162:173:void updatePreMeasure(android.constraint.Layout,String,int) -> a", |
| " 194:204:void updatePostMeasure(android.constraint.Layout,String,int) -> a"); |
| ClassNameMapper cnm = ClassNameMapper.mapperFromString(mapWithArgumentRemovalInformation); |
| ClassNamingForNameMapper classNaming = cnm.getClassNaming("a.b.b.f"); |
| assertNotNull(classNaming); |
| |
| List<MemberNaming> members = classNaming.lookupByOriginalName("mContentId"); |
| assertFalse(members.isEmpty()); |
| MemberNaming fieldContentId = members.get(0); |
| assertNotNull(fieldContentId); |
| assertTrue(!fieldContentId.isMethodNaming()); |
| |
| members = classNaming.lookupByOriginalName("updatePreLayout"); |
| assertFalse(members.isEmpty()); |
| MemberNaming updatePreLayout = members.get(0); |
| assertNotNull(updatePreLayout); |
| assertTrue(updatePreLayout.isMethodNaming()); |
| MethodSignature renamedPreLayout = (MethodSignature) updatePreLayout.getRenamedSignature(); |
| assertEquals(1, renamedPreLayout.parameters.length); |
| assertEquals("int", renamedPreLayout.parameters[0]); |
| |
| members = classNaming.lookupByOriginalName("updatePreMeasure"); |
| assertFalse(members.isEmpty()); |
| MemberNaming updatePreMeasure = members.get(0); |
| assertNotNull(updatePreMeasure); |
| assertTrue(updatePreMeasure.isMethodNaming()); |
| MethodSignature renamedPreMeasure = (MethodSignature) updatePreMeasure.getRenamedSignature(); |
| assertEquals(2, renamedPreMeasure.parameters.length); |
| assertEquals("android.constraint.Layout", renamedPreMeasure.parameters[0]); |
| assertEquals("String", renamedPreMeasure.parameters[1]); |
| |
| members = classNaming.lookupByOriginalName("updatePostMeasure"); |
| assertFalse(members.isEmpty()); |
| MemberNaming updatePostMeasure = members.get(0); |
| assertNotNull(updatePostMeasure); |
| assertTrue(updatePostMeasure.isMethodNaming()); |
| MethodSignature renamedPostMeasure = (MethodSignature) updatePostMeasure.getRenamedSignature(); |
| assertEquals(3, renamedPostMeasure.parameters.length); |
| } |
| |
| @Test |
| public void testMethodCanParseArgumentChanged() throws IOException { |
| String mapWithArgumentRemovalInformation = |
| StringUtils.join( |
| "\n", |
| "android.constraint.Placeholder -> a.b.b.f:", |
| "# {'id':'methodSignatureChanged'," |
| + "'signature':[" |
| + "'void','updatePreLayout','android.constraint.Layout','String','float']," |
| + "'returnType': 'void'," |
| + "'receiver': true," |
| + "'params':[[1,int],[2,Foo]]}", |
| "# {'id':'methodSignatureChanged'," |
| + "'signature':[" |
| + "'void','updatePreMeasure','android.constraint.Layout','String','int']," |
| + "'returnType': 'void', " |
| + "'receiver': true, " |
| + "'params':[[2,com.baz.Bar],[3]]}", |
| " 147:161:void updatePreLayout(android.constraint.Layout,String,float) -> a", |
| " 162:173:void updatePreMeasure(android.constraint.Layout,String,int) -> a", |
| " 194:204:void updatePostMeasure(android.constraint.Layout,String,int) -> a"); |
| ClassNameMapper cnm = ClassNameMapper.mapperFromString(mapWithArgumentRemovalInformation); |
| ClassNamingForNameMapper classNaming = cnm.getClassNaming("a.b.b.f"); |
| assertNotNull(classNaming); |
| |
| List<MemberNaming> members = classNaming.lookupByOriginalName("updatePreLayout"); |
| assertFalse(members.isEmpty()); |
| MemberNaming updatePreLayout = members.get(0); |
| assertNotNull(updatePreLayout); |
| assertTrue(updatePreLayout.isMethodNaming()); |
| MethodSignature renamedPreLayout = (MethodSignature) updatePreLayout.getRenamedSignature(); |
| assertEquals(3, renamedPreLayout.parameters.length); |
| assertEquals("int", renamedPreLayout.parameters[0]); |
| assertEquals("Foo", renamedPreLayout.parameters[1]); |
| assertEquals("float", renamedPreLayout.parameters[2]); |
| |
| members = classNaming.lookupByOriginalName("updatePreMeasure"); |
| assertFalse(members.isEmpty()); |
| MemberNaming updatePreMeasure = members.get(0); |
| assertNotNull(updatePreMeasure); |
| assertTrue(updatePreMeasure.isMethodNaming()); |
| MethodSignature renamedPreMeasure = (MethodSignature) updatePreMeasure.getRenamedSignature(); |
| assertEquals(2, renamedPreMeasure.parameters.length); |
| assertEquals("android.constraint.Layout", renamedPreMeasure.parameters[0]); |
| assertEquals("com.baz.Bar", renamedPreMeasure.parameters[1]); |
| |
| members = classNaming.lookupByOriginalName("updatePostMeasure"); |
| assertFalse(members.isEmpty()); |
| MemberNaming updatePostMeasure = members.get(0); |
| assertNotNull(updatePostMeasure); |
| assertTrue(updatePostMeasure.isMethodNaming()); |
| MethodSignature renamedPostMeasure = (MethodSignature) updatePostMeasure.getRenamedSignature(); |
| assertEquals(3, renamedPostMeasure.parameters.length); |
| } |
| } |