brintos

brintos / llvm-project-archived public Read only

0
0
Text · 12.1 KiB · 4da35b5 Raw
304 lines · plain
1// RUN: %clang_cc1 -fblocks -x objective-c-header -emit-pch -o %t.pch %S/Inputs/localization-pch.h2 3// RUN: %clang_analyze_cc1 -fblocks \4// RUN:   -analyzer-config optin.osx.cocoa.localizability.NonLocalizedStringChecker:AggressiveReport=true \5// RUN:   -analyzer-checker=optin.osx.cocoa.localizability.NonLocalizedStringChecker \6// RUN:   -analyzer-checker=optin.osx.cocoa.localizability.EmptyLocalizationContextChecker \7// RUN:   -include-pch %t.pch -verify  %s8 9// These declarations were reduced using Delta-Debugging from Foundation.h10// on Mac OS X.11 12#define nil ((id)0)13#define NSLocalizedString(key, comment)                                        \14  [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil]15#define NSLocalizedStringFromTable(key, tbl, comment)                          \16  [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:(tbl)]17#define NSLocalizedStringFromTableInBundle(key, tbl, bundle, comment)          \18  [bundle localizedStringForKey:(key) value:@"" table:(tbl)]19#define NSLocalizedStringWithDefaultValue(key, tbl, bundle, val, comment)      \20  [bundle localizedStringForKey:(key) value:(val) table:(tbl)]21#define CGFLOAT_TYPE double22typedef CGFLOAT_TYPE CGFloat;23struct CGPoint {24  CGFloat x;25  CGFloat y;26};27typedef struct CGPoint CGPoint;28@interface NSObject29+ (id)alloc;30- (id)init;31@end32@class NSDictionary;33@interface NSString : NSObject34- (void)drawAtPoint:(CGPoint)point withAttributes:(NSDictionary *)attrs;35+ (instancetype)localizedStringWithFormat:(NSString *)format, ...;36@end37@interface NSBundle : NSObject38+ (NSBundle *)mainBundle;39- (NSString *)localizedStringForKey:(NSString *)key40                              value:(NSString *)value41                              table:(NSString *)tableName;42@end43@protocol UIAccessibility 44- (void)accessibilitySetIdentification:(NSString *)ident;45- (void)setAccessibilityLabel:(NSString *)label;46@end47@interface UILabel : NSObject <UIAccessibility>48@property(nullable, nonatomic, copy) NSString *text;49@end50@interface TestObject : NSObject51@property(strong) NSString *text;52@end53@interface NSView : NSObject54@property (strong) NSString *toolTip;55@end56@interface NSViewSubclass : NSView57@end58 59@interface LocalizationTestSuite : NSObject60NSString *ForceLocalized(NSString *str)61    __attribute__((annotate("returns_localized_nsstring")));62CGPoint CGPointMake(CGFloat x, CGFloat y);63int random(void);64// This next one is a made up API65NSString *CFNumberFormatterCreateStringWithNumber(float x);66+ (NSString *)forceLocalized:(NSString *)str67    __attribute__((annotate("returns_localized_nsstring")));68+ (NSString *)takesLocalizedString:69    (NSString *)__attribute__((annotate("takes_localized_nsstring")))str;70@end71 72NSString *73takesLocalizedString(NSString *str74                     __attribute__((annotate("takes_localized_nsstring")))) {75  return str;76}77 78// Test cases begin here79@implementation LocalizationTestSuite80 81// A C-Funtion that returns a localized string because it has the82// "returns_localized_nsstring" annotation83NSString *ForceLocalized(NSString *str) { return str; }84// An ObjC method that returns a localized string because it has the85// "returns_localized_nsstring" annotation86+ (NSString *)forceLocalized:(NSString *)str {87  return str;88}89 90+ (NSString *) takesLocalizedString:(NSString *)str { return str; }91 92// An ObjC method that returns a localized string93+ (NSString *)unLocalizedStringMethod {94  return @"UnlocalizedString";95}96 97- (void)testLocalizationErrorDetectedOnPathway {98  UILabel *testLabel = [[UILabel alloc] init];99  NSString *bar = NSLocalizedString(@"Hello", @"Comment");100 101  if (random()) {102    bar = @"Unlocalized string";103  }104 105  [testLabel setText:bar]; // expected-warning {{User-facing text should use localized string macro}}106}107 108- (void)testLocalizationErrorDetectedOnNSString {109  NSString *bar = NSLocalizedString(@"Hello", @"Comment");110 111  if (random()) {112    bar = @"Unlocalized string";113  }114 115  [bar drawAtPoint:CGPointMake(0, 0) withAttributes:nil]; // expected-warning {{User-facing text should use localized string macro}}116}117 118- (void)testNoLocalizationErrorDetectedFromCFunction {119  UILabel *testLabel = [[UILabel alloc] init];120  NSString *bar = CFNumberFormatterCreateStringWithNumber(1);121 122  [testLabel setText:bar]; // no-warning123}124 125- (void)testAnnotationAddsLocalizedStateForCFunction {126  UILabel *testLabel = [[UILabel alloc] init];127  NSString *bar = NSLocalizedString(@"Hello", @"Comment");128 129  if (random()) {130    bar = @"Unlocalized string";131  }132 133  [testLabel setText:ForceLocalized(bar)]; // no-warning134}135 136- (void)testAnnotationAddsLocalizedStateForObjCMethod {137  UILabel *testLabel = [[UILabel alloc] init];138  NSString *bar = NSLocalizedString(@"Hello", @"Comment");139 140  if (random()) {141    bar = @"Unlocalized string";142  }143 144  [testLabel setText:[LocalizationTestSuite forceLocalized:bar]]; // no-warning145}146 147// An empty string literal @"" should not raise an error148- (void)testEmptyStringLiteralHasLocalizedState {149  UILabel *testLabel = [[UILabel alloc] init];150  NSString *bar = @"";151 152  [testLabel setText:bar]; // no-warning153}154 155// An empty string literal @"" inline should not raise an error156- (void)testInlineEmptyStringLiteralHasLocalizedState {157  UILabel *testLabel = [[UILabel alloc] init];158  [testLabel setText:@""]; // no-warning159}160 161// An string literal @"Hello" inline should raise an error162- (void)testInlineStringLiteralHasLocalizedState {163  UILabel *testLabel = [[UILabel alloc] init];164  [testLabel setText:@"Hello"]; // expected-warning {{User-facing text should use localized string macro}}165}166 167// A nil string should not raise an error168- (void)testNilStringIsNotMarkedAsUnlocalized {169  UILabel *testLabel = [[UILabel alloc] init];170  [testLabel setText:nil]; // no-warning171}172 173// A method that takes in a localized string and returns a string174// most likely that string is localized.175- (void)testLocalizedStringArgument {176  UILabel *testLabel = [[UILabel alloc] init];177  NSString *localizedString = NSLocalizedString(@"Hello", @"Comment");178 179  NSString *combinedString =180      [NSString localizedStringWithFormat:@"%@", localizedString];181 182  [testLabel setText:combinedString]; // no-warning183}184 185// A String passed in as a an parameter should not be considered186// unlocalized187- (void)testLocalizedStringAsArgument:(NSString *)argumentString {188  UILabel *testLabel = [[UILabel alloc] init];189 190  [testLabel setText:argumentString]; // no-warning191}192 193// The warning is expected to be seen in localizedStringAsArgument: body194- (void)testLocalizedStringAsArgumentOtherMethod:(NSString *)argumentString {195  [self localizedStringAsArgument:@"UnlocalizedString"];196}197 198// A String passed into another method that calls a method that199// requires a localized string should give an error200- (void)localizedStringAsArgument:(NSString *)argumentString {201  UILabel *testLabel = [[UILabel alloc] init];202 203  [testLabel setText:argumentString]; // expected-warning {{User-facing text should use localized string macro}}204}205 206// [LocalizationTestSuite unLocalizedStringMethod] returns an unlocalized string207// so we expect an error. Unfrtunately, it probably doesn't make a difference208// what [LocalizationTestSuite unLocalizedStringMethod] returns since all209// string values returned are marked as Unlocalized in aggressive reporting.210- (void)testUnLocalizedStringMethod {211  UILabel *testLabel = [[UILabel alloc] init];212  NSString *bar = NSLocalizedString(@"Hello", @"Comment");213 214  [testLabel setText:[LocalizationTestSuite unLocalizedStringMethod]]; // expected-warning {{User-facing text should use localized string macro}}215}216 217// This is the reverse situation: accessibilitySetIdentification: doesn't care218// about localization so we don't expect a warning219- (void)testMethodNotInRequiresLocalizedStringMethods {220  UILabel *testLabel = [[UILabel alloc] init];221 222  [testLabel accessibilitySetIdentification:@"UnlocalizedString"]; // no-warning223}224 225// An NSView subclass should raise a warning for methods in NSView that 226// require localized strings 227- (void)testRequiresLocalizationMethodFromSuperclass {228  NSViewSubclass *s = [[NSViewSubclass alloc] init];229  NSString *bar = @"UnlocalizedString";230 231  [s setToolTip:bar]; // expected-warning {{User-facing text should use localized string macro}}232}233 234- (void)testRequiresLocalizationMethodFromProtocol {235  UILabel *testLabel = [[UILabel alloc] init];236 237  [testLabel setAccessibilityLabel:@"UnlocalizedString"]; // expected-warning {{User-facing text should use localized string macro}}238}239 240// EmptyLocalizationContextChecker tests241#define HOM(s) YOLOC(s)242#define YOLOC(x) NSLocalizedString(x, nil)243 244- (void)testNilLocalizationContext {245  NSString *string = NSLocalizedString(@"LocalizedString", nil); // expected-warning {{Localized string macro should include a non-empty comment for translators}}246  NSString *string2 = NSLocalizedString(@"LocalizedString", nil); // expected-warning {{Localized string macro should include a non-empty comment for translators}}247  NSString *string3 = NSLocalizedString(@"LocalizedString", nil); // expected-warning {{Localized string macro should include a non-empty comment for translators}}248}249 250- (void)testEmptyLocalizationContext {251  NSString *string = NSLocalizedString(@"LocalizedString", @""); // expected-warning {{Localized string macro should include a non-empty comment for translators}}252  NSString *string2 = NSLocalizedString(@"LocalizedString", @" "); // expected-warning {{Localized string macro should include a non-empty comment for translators}}253  NSString *string3 = NSLocalizedString(@"LocalizedString", @"	 "); // expected-warning {{Localized string macro should include a non-empty comment for translators}}254}255 256- (void)testNSLocalizedStringVariants {257  NSString *string = NSLocalizedStringFromTable(@"LocalizedString", nil, @""); // expected-warning {{Localized string macro should include a non-empty comment for translators}}258  NSString *string2 = NSLocalizedStringFromTableInBundle(@"LocalizedString", nil, [[NSBundle alloc] init],@""); // expected-warning {{Localized string macro should include a non-empty comment for translators}}259  NSString *string3 = NSLocalizedStringWithDefaultValue(@"LocalizedString", nil, [[NSBundle alloc] init], nil,@""); // expected-warning {{Localized string macro should include a non-empty comment for translators}}260}261 262- (void)testMacroExpansionNilString {263  NSString *string = YOLOC(@"Hello"); // expected-warning {{Localized string macro should include a non-empty comment for translators}}264  NSString *string2 = HOM(@"Hello");  // expected-warning {{Localized string macro should include a non-empty comment for translators}}265  NSString *string3 = NSLocalizedString((0 ? @"Critical" : @"Current"),nil); // expected-warning {{Localized string macro should include a non-empty comment for translators}}266}267 268- (void)testMacroExpansionDefinedInPCH {269  NSString *string = MyLocalizedStringInPCH(@"Hello"); // expected-warning {{Localized string macro should include a non-empty comment for translators}}270}271 272#define KCLocalizedString(x,comment) NSLocalizedString(x, comment)273#define POSSIBLE_FALSE_POSITIVE(s,other) KCLocalizedString(s,@"Comment")274 275- (void)testNoWarningForNilCommentPassedIntoOtherMacro {276  NSString *string = KCLocalizedString(@"Hello",@""); // no-warning277  NSString *string2 = KCLocalizedString(@"Hello",nil); // no-warning278  NSString *string3 = KCLocalizedString(@"Hello",@"Comment"); // no-warning279}280 281- (void)testPossibleFalsePositiveSituationAbove {282  NSString *string = POSSIBLE_FALSE_POSITIVE(@"Hello", nil); // no-warning283  NSString *string2 = POSSIBLE_FALSE_POSITIVE(@"Hello", @"Hello"); // no-warning284}285 286- (void)testTakesLocalizedString {287  NSString *localized = NSLocalizedString(@"Hello", @"World");288  NSString *alsoLocalized = [LocalizationTestSuite takesLocalizedString:localized]; // no-warning289  NSString *stillLocalized = [LocalizationTestSuite takesLocalizedString:alsoLocalized]; // no-warning290  takesLocalizedString(stillLocalized); // no-warning291 292  [LocalizationTestSuite takesLocalizedString:@"not localized"]; // expected-warning {{User-facing text should use localized string macro}}293  takesLocalizedString(@"not localized"); // expected-warning {{User-facing text should use localized string macro}}294}295@end296 297@interface SynthesizedAccessors : NSObject298@property (assign) NSObject *obj;299@end300 301@implementation SynthesizedAccessors302// no-crash303@end304