//===--- StringExtras.cpp - String Utilities ------------------------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// // // This file implements utilities for working with words and camelCase // names. // //===----------------------------------------------------------------------===// #include "swift/Basic/StringExtras.h" #include "clang/Basic/CharInfo.h" using namespace swift; using namespace camel_case; PrepositionKind swift::getPrepositionKind(StringRef word) { #define DIRECTIONAL_PREPOSITION(Word) \ if (word.equals_lower(#Word)) \ return PK_Directional; #define PREPOSITION(Word) \ if (word.equals_lower(#Word)) \ return PK_Nondirectional; #include "Prepositions.def" return PK_None; } void WordIterator::computeNextPosition() const { assert(Position < String.size() && "Already at end of string"); // Skip over any uppercase letters at the beginning of the word. unsigned i = Position, n = String.size(); while (i < n && clang::isUppercase(String[i])) ++i; // If there was more than one uppercase letter, this is an // acronym. if (i - Position > 1) { // If we hit the end of the string, that's it. Otherwise, this // word ends at the last uppercase letter, so that the next word // starts with the last uppercase letter. NextPosition = i == n? i : i-1; NextPositionValid = true; return; } // Skip non-uppercase letters. while (i < n && !clang::isUppercase(String[i])) ++i; NextPosition = i; NextPositionValid = true; } void WordIterator::computePrevPosition() const { assert(Position > 0 && "Already at beginning of string"); // While we see non-uppercase letters, keep moving back. unsigned i = Position; while (i > 0 && !clang::isUppercase(String[i-1])) --i; // If we found any lowercase letters, this was a normal camel case // word (not an acronym). if (i < Position) { // If we hit the beginning of the string, that's it. Otherwise, // this word starts at the uppercase letter that terminated the // search above. PrevPosition = i == 0 ? 0 : i-1; PrevPositionValid = true; return; } // There were no lowercase letters, so this is an acronym. Keep // skipping uppercase letters. while (i > 0 && clang::isUppercase(String[i-1])) --i; PrevPosition = i; PrevPositionValid = true; } StringRef camel_case::getFirstWord(StringRef string) { if (string.empty()) return ""; return *WordIterator(string, 0); } StringRef camel_case::getLastWord(StringRef string) { if (string.empty()) return ""; return *--WordIterator(string, string.size()); }