1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.tools.metalava.stub 18 19 import com.android.tools.metalava.model.provider.Capability 20 import com.android.tools.metalava.model.testing.RequiresCapabilities 21 import com.android.tools.metalava.model.text.FileFormat 22 import com.android.tools.metalava.testing.java 23 import com.android.tools.metalava.testing.kotlin 24 import org.junit.Test 25 26 @SuppressWarnings("ALL") 27 class StubsConstructorTest : AbstractStubsTest() { 28 29 @Test Generate stubs for class that should not get default constructor (has other constructors)null30 fun `Generate stubs for class that should not get default constructor (has other constructors)`() { 31 // Class without explicit constructors (shouldn't insert default constructor) 32 checkStubs( 33 sourceFiles = 34 arrayOf( 35 java( 36 """ 37 package test.pkg; 38 public class Foo { 39 public Foo(int i) { 40 41 } 42 public Foo(int i, int j) { 43 } 44 } 45 """ 46 ) 47 ), 48 source = 49 """ 50 package test.pkg; 51 @SuppressWarnings({"unchecked", "deprecation", "all"}) 52 public class Foo { 53 public Foo(int i) { throw new RuntimeException("Stub!"); } 54 public Foo(int i, int j) { throw new RuntimeException("Stub!"); } 55 } 56 """ 57 ) 58 } 59 60 @Test Generate stubs for class that already has a private constructornull61 fun `Generate stubs for class that already has a private constructor`() { 62 // Class without private constructor; no default constructor should be inserted 63 checkStubs( 64 sourceFiles = 65 arrayOf( 66 java( 67 """ 68 package test.pkg; 69 public class Foo { 70 private Foo() { 71 } 72 } 73 """ 74 ) 75 ), 76 source = 77 """ 78 package test.pkg; 79 @SuppressWarnings({"unchecked", "deprecation", "all"}) 80 public class Foo { 81 Foo() { throw new RuntimeException("Stub!"); } 82 } 83 """ 84 ) 85 } 86 87 @Test Arguments to super constructorsnull88 fun `Arguments to super constructors`() { 89 // When overriding constructors we have to supply arguments 90 checkStubs( 91 sourceFiles = 92 arrayOf( 93 java( 94 """ 95 package test.pkg; 96 97 @SuppressWarnings("WeakerAccess") 98 public class Constructors { 99 public class Parent { 100 public Parent(String arg1, int arg2, long arg3, boolean arg4, short arg5) { 101 } 102 } 103 104 public class Child extends Parent { 105 public Child(String arg1, int arg2, long arg3, boolean arg4, short arg5) { 106 super(arg1, arg2, arg3, arg4, arg5); 107 } 108 109 private Child(String arg1) { 110 super(arg1, 0, 0, false, 0); 111 } 112 } 113 114 public class Child2 extends Parent { 115 Child2(String arg1) { 116 super(arg1, 0, 0, false, 0); 117 } 118 } 119 120 public class Child3 extends Child2 { 121 private Child3(String arg1) { 122 super("something"); 123 } 124 } 125 126 public class Child4 extends Parent { 127 Child4(String arg1, HiddenClass arg2) { 128 super(arg1, 0, 0, true, 0); 129 } 130 } 131 /** @hide */ 132 public class HiddenClass { 133 } 134 } 135 """ 136 ) 137 ), 138 source = 139 """ 140 package test.pkg; 141 @SuppressWarnings({"unchecked", "deprecation", "all"}) 142 public class Constructors { 143 public Constructors() { throw new RuntimeException("Stub!"); } 144 @SuppressWarnings({"unchecked", "deprecation", "all"}) 145 public class Child extends test.pkg.Constructors.Parent { 146 public Child(java.lang.String arg1, int arg2, long arg3, boolean arg4, short arg5) { super("", 0, 0, false, (short)0); throw new RuntimeException("Stub!"); } 147 } 148 @SuppressWarnings({"unchecked", "deprecation", "all"}) 149 public class Child2 extends test.pkg.Constructors.Parent { 150 Child2() { super("", 0, 0, false, (short)0); throw new RuntimeException("Stub!"); } 151 } 152 @SuppressWarnings({"unchecked", "deprecation", "all"}) 153 public class Child3 extends test.pkg.Constructors.Child2 { 154 Child3() { throw new RuntimeException("Stub!"); } 155 } 156 @SuppressWarnings({"unchecked", "deprecation", "all"}) 157 public class Child4 extends test.pkg.Constructors.Parent { 158 Child4() { super("", 0, 0, false, (short)0); throw new RuntimeException("Stub!"); } 159 } 160 @SuppressWarnings({"unchecked", "deprecation", "all"}) 161 public class Parent { 162 public Parent(java.lang.String arg1, int arg2, long arg3, boolean arg4, short arg5) { throw new RuntimeException("Stub!"); } 163 } 164 } 165 """, 166 checkTextStubEquivalence = true 167 ) 168 } 169 170 @Test Arguments to super constructors with showAnnotationsnull171 fun `Arguments to super constructors with showAnnotations`() { 172 // When overriding constructors we have to supply arguments 173 checkStubs( 174 showAnnotations = arrayOf("android.annotation.SystemApi"), 175 sourceFiles = 176 arrayOf( 177 java( 178 """ 179 package test.pkg; 180 181 @SuppressWarnings("WeakerAccess") 182 public class Constructors { 183 public class Parent { 184 public Parent(String s, int i, long l, boolean b, short sh) { 185 } 186 } 187 188 public class Child extends Parent { 189 public Child(String s, int i, long l, boolean b, short sh) { 190 super(s, i, l, b, sh); 191 } 192 193 private Child(String s) { 194 super(s, 0, 0, false, 0); 195 } 196 } 197 198 public class Child2 extends Parent { 199 Child2(String s) { 200 super(s, 0, 0, false, 0); 201 } 202 } 203 204 public class Child3 extends Child2 { 205 private Child3(String s) { 206 super("something"); 207 } 208 } 209 210 public class Child4 extends Parent { 211 Child4(String s, HiddenClass hidden) { 212 super(s, 0, 0, true, 0); 213 } 214 } 215 /** @hide */ 216 public class HiddenClass { 217 } 218 } 219 """ 220 ) 221 ), 222 source = 223 """ 224 package test.pkg; 225 @SuppressWarnings({"unchecked", "deprecation", "all"}) 226 public class Constructors { 227 public Constructors() { throw new RuntimeException("Stub!"); } 228 @SuppressWarnings({"unchecked", "deprecation", "all"}) 229 public class Child extends test.pkg.Constructors.Parent { 230 public Child(java.lang.String s, int i, long l, boolean b, short sh) { super("", 0, 0, false, (short)0); throw new RuntimeException("Stub!"); } 231 } 232 @SuppressWarnings({"unchecked", "deprecation", "all"}) 233 public class Child2 extends test.pkg.Constructors.Parent { 234 Child2() { super("", 0, 0, false, (short)0); throw new RuntimeException("Stub!"); } 235 } 236 @SuppressWarnings({"unchecked", "deprecation", "all"}) 237 public class Child3 extends test.pkg.Constructors.Child2 { 238 Child3() { throw new RuntimeException("Stub!"); } 239 } 240 @SuppressWarnings({"unchecked", "deprecation", "all"}) 241 public class Child4 extends test.pkg.Constructors.Parent { 242 Child4() { super("", 0, 0, false, (short)0); throw new RuntimeException("Stub!"); } 243 } 244 @SuppressWarnings({"unchecked", "deprecation", "all"}) 245 public class Parent { 246 public Parent(java.lang.String s, int i, long l, boolean b, short sh) { throw new RuntimeException("Stub!"); } 247 } 248 } 249 """ 250 ) 251 } 252 253 // TODO: Add test to see what happens if I have Child4 in a different package which can't access 254 // the package private constructor of child3? 255 256 @Test Test inaccessible constructorsnull257 fun `Test inaccessible constructors`() { 258 // If the constructors of a class are not visible, and the class has subclasses, 259 // those subclass stubs will need to reference these inaccessible constructors. 260 // This generally only happens when the constructors are package private (and 261 // therefore hidden) but the subclass using it is also in the same package. 262 263 check( 264 checkCompilation = true, 265 sourceFiles = 266 arrayOf( 267 java( 268 """ 269 package test.pkg; 270 public class MyClass1 { 271 MyClass1(int myVar) { } 272 } 273 """ 274 ), 275 java( 276 """ 277 package test.pkg; 278 import java.io.IOException; 279 @SuppressWarnings("RedundantThrows") 280 public class MySubClass1 extends MyClass1 { 281 MySubClass1(int myVar) throws IOException { super(myVar); } 282 } 283 """ 284 ), 285 java( 286 """ 287 package test.pkg; 288 public class MyClass2 { 289 /** @hide */ 290 public MyClass2(int myVar) { } 291 } 292 """ 293 ), 294 java( 295 """ 296 package test.pkg; 297 public class MySubClass2 extends MyClass2 { 298 public MySubClass2() { super(5); } 299 } 300 """ 301 ) 302 ), 303 expectedIssues = "", 304 api = 305 """ 306 package test.pkg { 307 public class MyClass1 { 308 } 309 public class MyClass2 { 310 } 311 public class MySubClass1 extends test.pkg.MyClass1 { 312 } 313 public class MySubClass2 extends test.pkg.MyClass2 { 314 ctor public MySubClass2(); 315 } 316 } 317 """, 318 stubFiles = 319 arrayOf( 320 java( 321 """ 322 package test.pkg; 323 @SuppressWarnings({"unchecked", "deprecation", "all"}) 324 public class MyClass1 { 325 MyClass1() { throw new RuntimeException("Stub!"); } 326 } 327 """ 328 ), 329 java( 330 """ 331 package test.pkg; 332 @SuppressWarnings({"unchecked", "deprecation", "all"}) 333 public class MySubClass1 extends test.pkg.MyClass1 { 334 MySubClass1() { throw new RuntimeException("Stub!"); } 335 } 336 """ 337 ), 338 java( 339 """ 340 package test.pkg; 341 @SuppressWarnings({"unchecked", "deprecation", "all"}) 342 public class MyClass2 { 343 MyClass2() { throw new RuntimeException("Stub!"); } 344 } 345 """ 346 ), 347 java( 348 """ 349 package test.pkg; 350 @SuppressWarnings({"unchecked", "deprecation", "all"}) 351 public class MySubClass2 extends test.pkg.MyClass2 { 352 public MySubClass2() { throw new RuntimeException("Stub!"); } 353 } 354 """ 355 ) 356 ), 357 ) 358 } 359 360 // TODO: Add a protected constructor too to make sure my code to make non-public constructors 361 // package private 362 // don't accidentally demote protected constructors to package private! 363 364 @Test Picking Super Constructorsnull365 fun `Picking Super Constructors`() { 366 checkStubs( 367 format = FileFormat.V2, 368 sourceFiles = 369 arrayOf( 370 java( 371 """ 372 package test.pkg; 373 374 @SuppressWarnings({"RedundantThrows", "JavaDoc", "WeakerAccess"}) 375 public class PickConstructors { 376 public abstract static class FileInputStream extends InputStream { 377 378 public FileInputStream(String name) throws FileNotFoundException { 379 } 380 381 public FileInputStream(File file) throws FileNotFoundException { 382 } 383 384 public FileInputStream(FileDescriptor fdObj) { 385 this(fdObj, false /* isFdOwner */); 386 } 387 388 /** 389 * @hide 390 */ 391 public FileInputStream(FileDescriptor fdObj, boolean isFdOwner) { 392 } 393 } 394 395 public abstract static class AutoCloseInputStream extends FileInputStream { 396 public AutoCloseInputStream(ParcelFileDescriptor pfd) { 397 super(pfd.getFileDescriptor()); 398 } 399 } 400 401 abstract static class HiddenParentStream extends FileInputStream { 402 public HiddenParentStream(FileDescriptor pfd) { 403 super(pfd); 404 } 405 } 406 407 public abstract static class AutoCloseInputStream2 extends HiddenParentStream { 408 public AutoCloseInputStream2(ParcelFileDescriptor pfd) { 409 super(pfd.getFileDescriptor()); 410 } 411 } 412 413 public abstract class ParcelFileDescriptor implements Closeable { 414 public abstract FileDescriptor getFileDescriptor(); 415 } 416 417 @SuppressWarnings("UnnecessaryInterfaceModifier") 418 public static interface Closeable extends AutoCloseable { 419 } 420 421 @SuppressWarnings("UnnecessaryInterfaceModifier") 422 public static interface AutoCloseable { 423 } 424 425 public static abstract class InputStream implements Closeable { 426 } 427 428 public static class File { 429 } 430 431 public static final class FileDescriptor { 432 } 433 434 public static class FileNotFoundException extends IOException { 435 } 436 437 public static class IOException extends Exception { 438 } 439 } 440 """ 441 ) 442 ), 443 warnings = "", 444 api = 445 """ 446 package test.pkg { 447 public class PickConstructors { 448 ctor public PickConstructors(); 449 } 450 public abstract static class PickConstructors.AutoCloseInputStream extends test.pkg.PickConstructors.FileInputStream { 451 ctor public PickConstructors.AutoCloseInputStream(test.pkg.PickConstructors.ParcelFileDescriptor); 452 } 453 public abstract static class PickConstructors.AutoCloseInputStream2 extends test.pkg.PickConstructors.FileInputStream { 454 ctor public PickConstructors.AutoCloseInputStream2(test.pkg.PickConstructors.ParcelFileDescriptor); 455 } 456 public static interface PickConstructors.AutoCloseable { 457 } 458 public static interface PickConstructors.Closeable extends test.pkg.PickConstructors.AutoCloseable { 459 } 460 public static class PickConstructors.File { 461 ctor public PickConstructors.File(); 462 } 463 public static final class PickConstructors.FileDescriptor { 464 ctor public PickConstructors.FileDescriptor(); 465 } 466 public abstract static class PickConstructors.FileInputStream extends test.pkg.PickConstructors.InputStream { 467 ctor public PickConstructors.FileInputStream(String) throws test.pkg.PickConstructors.FileNotFoundException; 468 ctor public PickConstructors.FileInputStream(test.pkg.PickConstructors.File) throws test.pkg.PickConstructors.FileNotFoundException; 469 ctor public PickConstructors.FileInputStream(test.pkg.PickConstructors.FileDescriptor); 470 } 471 public static class PickConstructors.FileNotFoundException extends test.pkg.PickConstructors.IOException { 472 ctor public PickConstructors.FileNotFoundException(); 473 } 474 public static class PickConstructors.IOException extends java.lang.Exception { 475 ctor public PickConstructors.IOException(); 476 } 477 public abstract static class PickConstructors.InputStream implements test.pkg.PickConstructors.Closeable { 478 ctor public PickConstructors.InputStream(); 479 } 480 public abstract class PickConstructors.ParcelFileDescriptor implements test.pkg.PickConstructors.Closeable { 481 ctor public PickConstructors.ParcelFileDescriptor(); 482 method public abstract test.pkg.PickConstructors.FileDescriptor getFileDescriptor(); 483 } 484 } 485 """, 486 source = 487 """ 488 package test.pkg; 489 @SuppressWarnings({"unchecked", "deprecation", "all"}) 490 public class PickConstructors { 491 public PickConstructors() { throw new RuntimeException("Stub!"); } 492 @SuppressWarnings({"unchecked", "deprecation", "all"}) 493 public abstract static class AutoCloseInputStream extends test.pkg.PickConstructors.FileInputStream { 494 public AutoCloseInputStream(test.pkg.PickConstructors.ParcelFileDescriptor pfd) { super((test.pkg.PickConstructors.FileDescriptor)null); throw new RuntimeException("Stub!"); } 495 } 496 @SuppressWarnings({"unchecked", "deprecation", "all"}) 497 public abstract static class AutoCloseInputStream2 extends test.pkg.PickConstructors.FileInputStream { 498 public AutoCloseInputStream2(test.pkg.PickConstructors.ParcelFileDescriptor pfd) { super((test.pkg.PickConstructors.FileDescriptor)null); throw new RuntimeException("Stub!"); } 499 } 500 @SuppressWarnings({"unchecked", "deprecation", "all"}) 501 public static interface AutoCloseable { 502 } 503 @SuppressWarnings({"unchecked", "deprecation", "all"}) 504 public static interface Closeable extends test.pkg.PickConstructors.AutoCloseable { 505 } 506 @SuppressWarnings({"unchecked", "deprecation", "all"}) 507 public static class File { 508 public File() { throw new RuntimeException("Stub!"); } 509 } 510 @SuppressWarnings({"unchecked", "deprecation", "all"}) 511 public static final class FileDescriptor { 512 public FileDescriptor() { throw new RuntimeException("Stub!"); } 513 } 514 @SuppressWarnings({"unchecked", "deprecation", "all"}) 515 public abstract static class FileInputStream extends test.pkg.PickConstructors.InputStream { 516 public FileInputStream(java.lang.String name) throws test.pkg.PickConstructors.FileNotFoundException { throw new RuntimeException("Stub!"); } 517 public FileInputStream(test.pkg.PickConstructors.File file) throws test.pkg.PickConstructors.FileNotFoundException { throw new RuntimeException("Stub!"); } 518 public FileInputStream(test.pkg.PickConstructors.FileDescriptor fdObj) { throw new RuntimeException("Stub!"); } 519 } 520 @SuppressWarnings({"unchecked", "deprecation", "all"}) 521 public static class FileNotFoundException extends test.pkg.PickConstructors.IOException { 522 public FileNotFoundException() { throw new RuntimeException("Stub!"); } 523 } 524 @SuppressWarnings({"unchecked", "deprecation", "all"}) 525 public static class IOException extends java.lang.Exception { 526 public IOException() { throw new RuntimeException("Stub!"); } 527 } 528 @SuppressWarnings({"unchecked", "deprecation", "all"}) 529 public abstract static class InputStream implements test.pkg.PickConstructors.Closeable { 530 public InputStream() { throw new RuntimeException("Stub!"); } 531 } 532 @SuppressWarnings({"unchecked", "deprecation", "all"}) 533 public abstract class ParcelFileDescriptor implements test.pkg.PickConstructors.Closeable { 534 public ParcelFileDescriptor() { throw new RuntimeException("Stub!"); } 535 public abstract test.pkg.PickConstructors.FileDescriptor getFileDescriptor(); 536 } 537 } 538 """ 539 ) 540 } 541 542 @Test Picking Constructorsnull543 fun `Picking Constructors`() { 544 checkStubs( 545 sourceFiles = 546 arrayOf( 547 java( 548 """ 549 package test.pkg; 550 551 @SuppressWarnings({"WeakerAccess", "unused"}) 552 public class Constructors2 { 553 public class TestSuite implements Test { 554 555 public TestSuite() { 556 } 557 558 public TestSuite(final Class<?> theClass) { 559 } 560 561 public TestSuite(Class<? extends TestCase> theClass, String name) { 562 this(theClass); 563 } 564 565 public TestSuite(String name) { 566 } 567 public TestSuite(Class<?>... classes) { 568 } 569 570 public TestSuite(Class<? extends TestCase>[] classes, String name) { 571 this(classes); 572 } 573 } 574 575 public class TestCase { 576 } 577 578 public interface Test { 579 } 580 581 public class Parent { 582 public Parent(int x) throws IOException { 583 } 584 } 585 586 class Intermediate extends Parent { 587 Intermediate(int x) throws IOException { super(x); } 588 } 589 590 public class Child extends Intermediate { 591 public Child() throws IOException { super(5); } 592 public Child(float x) throws IOException { this(); } 593 } 594 595 // ---------------------------------------------------- 596 597 public abstract class DrawableWrapper { 598 public DrawableWrapper(Drawable dr) { 599 } 600 601 DrawableWrapper(Clipstate state, Object resources) { 602 } 603 } 604 605 606 public class ClipDrawable extends DrawableWrapper { 607 ClipDrawable() { 608 this(null); 609 } 610 611 public ClipDrawable(Drawable drawable, int gravity, int orientation) { this(null); } 612 613 private ClipDrawable(Clipstate clipstate) { 614 super(clipstate, null); 615 } 616 } 617 618 public class Drawable { 619 } 620 621 class Clipstate { 622 } 623 } 624 """ 625 ) 626 ), 627 warnings = "", 628 source = 629 """ 630 package test.pkg; 631 @SuppressWarnings({"unchecked", "deprecation", "all"}) 632 public class Constructors2 { 633 public Constructors2() { throw new RuntimeException("Stub!"); } 634 @SuppressWarnings({"unchecked", "deprecation", "all"}) 635 public class Child extends test.pkg.Constructors2.Parent { 636 public Child() { super(0); throw new RuntimeException("Stub!"); } 637 public Child(float x) { super(0); throw new RuntimeException("Stub!"); } 638 } 639 @SuppressWarnings({"unchecked", "deprecation", "all"}) 640 public class ClipDrawable extends test.pkg.Constructors2.DrawableWrapper { 641 public ClipDrawable(test.pkg.Constructors2.Drawable drawable, int gravity, int orientation) { super((test.pkg.Constructors2.Drawable)null); throw new RuntimeException("Stub!"); } 642 } 643 @SuppressWarnings({"unchecked", "deprecation", "all"}) 644 public class Drawable { 645 public Drawable() { throw new RuntimeException("Stub!"); } 646 } 647 @SuppressWarnings({"unchecked", "deprecation", "all"}) 648 public abstract class DrawableWrapper { 649 public DrawableWrapper(test.pkg.Constructors2.Drawable dr) { throw new RuntimeException("Stub!"); } 650 } 651 @SuppressWarnings({"unchecked", "deprecation", "all"}) 652 public class Parent { 653 public Parent(int x) { throw new RuntimeException("Stub!"); } 654 } 655 @SuppressWarnings({"unchecked", "deprecation", "all"}) 656 public static interface Test { 657 } 658 @SuppressWarnings({"unchecked", "deprecation", "all"}) 659 public class TestCase { 660 public TestCase() { throw new RuntimeException("Stub!"); } 661 } 662 @SuppressWarnings({"unchecked", "deprecation", "all"}) 663 public class TestSuite implements test.pkg.Constructors2.Test { 664 public TestSuite() { throw new RuntimeException("Stub!"); } 665 public TestSuite(java.lang.Class<? extends test.pkg.Constructors2.TestCase> theClass, java.lang.String name) { throw new RuntimeException("Stub!"); } 666 public TestSuite(java.lang.Class<? extends test.pkg.Constructors2.TestCase>[] classes, java.lang.String name) { throw new RuntimeException("Stub!"); } 667 public TestSuite(java.lang.Class<?> theClass) { throw new RuntimeException("Stub!"); } 668 public TestSuite(java.lang.Class<?>... classes) { throw new RuntimeException("Stub!"); } 669 public TestSuite(java.lang.String name) { throw new RuntimeException("Stub!"); } 670 } 671 } 672 """ 673 ) 674 } 675 676 @Test Another Constructor Testnull677 fun `Another Constructor Test`() { 678 // A specific scenario triggered in the API where the right super class detector was not 679 // chosen 680 checkStubs( 681 sourceFiles = 682 arrayOf( 683 java( 684 """ 685 package test.pkg; 686 687 @SuppressWarnings({"RedundantThrows", "JavaDoc", "WeakerAccess"}) 688 public class PickConstructors2 { 689 public interface EventListener { 690 } 691 692 public interface PropertyChangeListener extends EventListener { 693 } 694 695 public static abstract class EventListenerProxy<T extends EventListener> 696 implements EventListener { 697 public EventListenerProxy(T listener) { 698 } 699 } 700 701 public static class PropertyChangeListenerProxy 702 extends EventListenerProxy<PropertyChangeListener> 703 implements PropertyChangeListener { 704 public PropertyChangeListenerProxy(String propertyName, PropertyChangeListener listener) { 705 super(listener); 706 } 707 } 708 } 709 """ 710 ) 711 ), 712 warnings = "", 713 source = 714 """ 715 package test.pkg; 716 @SuppressWarnings({"unchecked", "deprecation", "all"}) 717 public class PickConstructors2 { 718 public PickConstructors2() { throw new RuntimeException("Stub!"); } 719 @SuppressWarnings({"unchecked", "deprecation", "all"}) 720 public static interface EventListener { 721 } 722 @SuppressWarnings({"unchecked", "deprecation", "all"}) 723 public abstract static class EventListenerProxy<T extends test.pkg.PickConstructors2.EventListener> implements test.pkg.PickConstructors2.EventListener { 724 public EventListenerProxy(T listener) { throw new RuntimeException("Stub!"); } 725 } 726 @SuppressWarnings({"unchecked", "deprecation", "all"}) 727 public static interface PropertyChangeListener extends test.pkg.PickConstructors2.EventListener { 728 } 729 @SuppressWarnings({"unchecked", "deprecation", "all"}) 730 public static class PropertyChangeListenerProxy extends test.pkg.PickConstructors2.EventListenerProxy<test.pkg.PickConstructors2.PropertyChangeListener> implements test.pkg.PickConstructors2.PropertyChangeListener { 731 public PropertyChangeListenerProxy(java.lang.String propertyName, test.pkg.PickConstructors2.PropertyChangeListener listener) { super((test.pkg.PickConstructors2.PropertyChangeListener)null); throw new RuntimeException("Stub!"); } 732 } 733 } 734 """ 735 ) 736 } 737 738 @Test Use type argument in constructor castnull739 fun `Use type argument in constructor cast`() { 740 check( 741 format = FileFormat.V2, 742 sourceFiles = 743 arrayOf( 744 java( 745 """ 746 package test.pkg; 747 /** @deprecated */ 748 @Deprecated 749 public class BasicPoolEntryRef extends WeakRef<BasicPoolEntry> { 750 public BasicPoolEntryRef(BasicPoolEntry entry) { 751 super(entry); 752 } 753 } 754 """ 755 ), 756 java( 757 """ 758 package test.pkg; 759 760 public class WeakRef<T> { 761 public WeakRef(T foo) { 762 } 763 // need to have more than one constructor to trigger casts in stubs 764 public WeakRef(T foo, int size) { 765 } 766 } 767 """ 768 ), 769 java( 770 """ 771 package test.pkg; 772 773 public class BasicPoolEntry { 774 } 775 """ 776 ) 777 ), 778 api = 779 """ 780 package test.pkg { 781 public class BasicPoolEntry { 782 ctor public BasicPoolEntry(); 783 } 784 @Deprecated public class BasicPoolEntryRef extends test.pkg.WeakRef<test.pkg.BasicPoolEntry> { 785 ctor @Deprecated public BasicPoolEntryRef(test.pkg.BasicPoolEntry); 786 } 787 public class WeakRef<T> { 788 ctor public WeakRef(T); 789 ctor public WeakRef(T, int); 790 } 791 } 792 """, 793 stubFiles = 794 arrayOf( 795 java( 796 """ 797 package test.pkg; 798 /** @deprecated */ 799 @SuppressWarnings({"unchecked", "deprecation", "all"}) 800 @Deprecated 801 public class BasicPoolEntryRef extends test.pkg.WeakRef<test.pkg.BasicPoolEntry> { 802 @Deprecated 803 public BasicPoolEntryRef(test.pkg.BasicPoolEntry entry) { super((test.pkg.BasicPoolEntry)null); throw new RuntimeException("Stub!"); } 804 } 805 """ 806 ) 807 ) 808 ) 809 } 810 811 @Test Use unspecified type argument in constructor castnull812 fun `Use unspecified type argument in constructor cast`() { 813 check( 814 format = FileFormat.V2, 815 sourceFiles = 816 arrayOf( 817 java( 818 """ 819 package test.pkg; 820 public class Foo extends Bar { 821 public Foo(Integer i) { 822 super(i); 823 } 824 } 825 """ 826 ), 827 java( 828 """ 829 package test.pkg; 830 831 public class Bar<T extends Number> { 832 public Bar(T foo) { 833 } 834 // need to have more than one constructor to trigger casts in stubs 835 public Bar(T foo, int size) { 836 } 837 } 838 """ 839 ), 840 ), 841 api = 842 """ 843 package test.pkg { 844 public class Bar<T extends java.lang.Number> { 845 ctor public Bar(T); 846 ctor public Bar(T, int); 847 } 848 public class Foo extends test.pkg.Bar { 849 ctor public Foo(Integer); 850 } 851 } 852 """, 853 stubFiles = 854 arrayOf( 855 java( 856 """ 857 package test.pkg; 858 @SuppressWarnings({"unchecked", "deprecation", "all"}) 859 public class Foo extends test.pkg.Bar { 860 public Foo(java.lang.Integer i) { super((java.lang.Number)null); throw new RuntimeException("Stub!"); } 861 } 862 """ 863 ) 864 ) 865 ) 866 } 867 868 @Test Varargs constructor parameter requiring castnull869 fun `Varargs constructor parameter requiring cast`() { 870 check( 871 format = FileFormat.V2, 872 sourceFiles = 873 arrayOf( 874 java( 875 """ 876 package test.pkg; 877 878 public class Child extends Parent { 879 public Child(int... ints) { 880 super(ints); 881 } 882 public Child(String... strings) { 883 super(strings); 884 } 885 } 886 """ 887 ), 888 java( 889 """ 890 package test.pkg; 891 892 public class Parent { 893 public Parent(int... ints) { 894 } 895 public Parent(String... strings) { 896 } 897 } 898 """ 899 ), 900 ), 901 api = 902 """ 903 package test.pkg { 904 public class Child extends test.pkg.Parent { 905 ctor public Child(int...); 906 ctor public Child(java.lang.String...); 907 } 908 public class Parent { 909 ctor public Parent(int...); 910 ctor public Parent(java.lang.String...); 911 } 912 } 913 """, 914 stubFiles = 915 arrayOf( 916 java( 917 """ 918 package test.pkg; 919 @SuppressWarnings({"unchecked", "deprecation", "all"}) 920 public class Child extends test.pkg.Parent { 921 public Child(int... ints) { super((int[])null); throw new RuntimeException("Stub!"); } 922 public Child(java.lang.String... strings) { super((int[])null); throw new RuntimeException("Stub!"); } 923 } 924 """ 925 ) 926 ) 927 ) 928 } 929 930 @RequiresCapabilities(Capability.KOTLIN) 931 @Test File facade constructornull932 fun `File facade constructor`() { 933 check( 934 format = FileFormat.V2, 935 sourceFiles = 936 arrayOf( 937 kotlin( 938 "test/pkg/Constants.kt", 939 """ 940 package test.pkg 941 942 const val CONSTANT = "CONSTANT" 943 """ 944 ), 945 ), 946 api = 947 """ 948 // Signature format: 2.0 949 package test.pkg { 950 public final class ConstantsKt { 951 property public static final String CONSTANT; 952 field @NonNull public static final String CONSTANT = "CONSTANT"; 953 } 954 } 955 """, 956 stubPaths = arrayOf("test/pkg/ConstantsKt.java"), 957 stubFiles = 958 arrayOf( 959 java( 960 """ 961 package test.pkg; 962 @SuppressWarnings({"unchecked", "deprecation", "all"}) 963 public final class ConstantsKt { 964 ConstantsKt() { throw new RuntimeException("Stub!"); } 965 @android.annotation.NonNull public static final java.lang.String CONSTANT = "CONSTANT"; 966 } 967 """ 968 ) 969 ) 970 ) 971 } 972 } 973