summaryrefslogtreecommitdiff
path: root/clang/lib/Format/FormatToken.h
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Format/FormatToken.h')
-rw-r--r--clang/lib/Format/FormatToken.h104
1 files changed, 98 insertions, 6 deletions
diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h
index e9cd327754ef..d4287f53fde3 100644
--- a/clang/lib/Format/FormatToken.h
+++ b/clang/lib/Format/FormatToken.h
@@ -54,6 +54,7 @@ namespace format {
TYPE(InheritanceComma) \
TYPE(InlineASMBrace) \
TYPE(InlineASMColon) \
+ TYPE(InlineASMSymbolicNameLSquare) \
TYPE(JavaAnnotation) \
TYPE(JsComputedPropertyName) \
TYPE(JsExponentiation) \
@@ -101,10 +102,20 @@ namespace format {
TYPE(TrailingUnaryOperator) \
TYPE(TypenameMacro) \
TYPE(UnaryOperator) \
+ TYPE(UntouchableMacroFunc) \
TYPE(CSharpStringLiteral) \
+ TYPE(CSharpNamedArgumentColon) \
+ TYPE(CSharpNullable) \
TYPE(CSharpNullCoalescing) \
+ TYPE(CSharpNullConditional) \
+ TYPE(CSharpNullConditionalLSquare) \
+ TYPE(CSharpGenericTypeConstraint) \
+ TYPE(CSharpGenericTypeConstraintColon) \
+ TYPE(CSharpGenericTypeConstraintComma) \
TYPE(Unknown)
+/// Determines the semantic type of a syntactic token, e.g. whether "<" is a
+/// template opener or binary operator.
enum TokenType {
#define TYPE(X) TT_##X,
LIST_TOKEN_TYPES
@@ -172,6 +183,12 @@ struct FormatToken {
/// before the token.
bool MustBreakBefore = false;
+ /// Whether to not align across this token
+ ///
+ /// This happens for example when a preprocessor directive ended directly
+ /// before the token, but very rarely otherwise.
+ bool MustBreakAlignBefore = false;
+
/// The raw text of the token.
///
/// Contains the raw token text without leading whitespace and without leading
@@ -184,7 +201,10 @@ struct FormatToken {
/// Contains the kind of block if this token is a brace.
BraceBlockKind BlockKind = BK_Unknown;
- TokenType Type = TT_Unknown;
+ /// Returns the token's type, e.g. whether "<" is a template opener or
+ /// binary operator.
+ TokenType getType() const { return Type; }
+ void setType(TokenType T) { Type = T; }
/// The number of spaces that should be inserted before this token.
unsigned SpacesRequiredBefore = 0;
@@ -504,6 +524,9 @@ struct FormatToken {
/// Returns \c true if this tokens starts a block-type list, i.e. a
/// list that should be indented with a block indent.
bool opensBlockOrBlockTypeList(const FormatStyle &Style) const {
+ // C# Does not indent object initialisers as continuations.
+ if (is(tok::l_brace) && BlockKind == BK_BracedInit && Style.isCSharp())
+ return true;
if (is(TT_TemplateString) && opensScope())
return true;
return is(TT_ArrayInitializerLSquare) || is(TT_ProtoExtensionLSquare) ||
@@ -579,6 +602,8 @@ private:
return Previous->endsSequenceInternal(K1, Tokens...);
return is(K1) && Previous && Previous->endsSequenceInternal(Tokens...);
}
+
+ TokenType Type = TT_Unknown;
};
class ContinuationIndenter;
@@ -770,6 +795,8 @@ struct AdditionalKeywords {
kw_unchecked = &IdentTable.get("unchecked");
kw_unsafe = &IdentTable.get("unsafe");
kw_ushort = &IdentTable.get("ushort");
+ kw_when = &IdentTable.get("when");
+ kw_where = &IdentTable.get("where");
// Keep this at the end of the constructor to make sure everything here
// is
@@ -786,7 +813,8 @@ struct AdditionalKeywords {
kw_fixed, kw_foreach, kw_implicit, kw_in, kw_interface, kw_internal,
kw_is, kw_lock, kw_null, kw_object, kw_out, kw_override, kw_params,
kw_readonly, kw_ref, kw_string, kw_stackalloc, kw_sbyte, kw_sealed,
- kw_uint, kw_ulong, kw_unchecked, kw_unsafe, kw_ushort,
+ kw_uint, kw_ulong, kw_unchecked, kw_unsafe, kw_ushort, kw_when,
+ kw_where,
// Keywords from the JavaScript section.
kw_as, kw_async, kw_await, kw_declare, kw_finally, kw_from,
kw_function, kw_get, kw_import, kw_is, kw_let, kw_module, kw_readonly,
@@ -890,13 +918,77 @@ struct AdditionalKeywords {
IdentifierInfo *kw_unchecked;
IdentifierInfo *kw_unsafe;
IdentifierInfo *kw_ushort;
+ IdentifierInfo *kw_when;
+ IdentifierInfo *kw_where;
/// Returns \c true if \p Tok is a true JavaScript identifier, returns
/// \c false if it is a keyword or a pseudo keyword.
- bool IsJavaScriptIdentifier(const FormatToken &Tok) const {
- return Tok.is(tok::identifier) &&
- JsExtraKeywords.find(Tok.Tok.getIdentifierInfo()) ==
- JsExtraKeywords.end();
+ /// If \c AcceptIdentifierName is true, returns true not only for keywords,
+ // but also for IdentifierName tokens (aka pseudo-keywords), such as
+ // ``yield``.
+ bool IsJavaScriptIdentifier(const FormatToken &Tok,
+ bool AcceptIdentifierName = true) const {
+ // Based on the list of JavaScript & TypeScript keywords here:
+ // https://github.com/microsoft/TypeScript/blob/master/src/compiler/scanner.ts#L74
+ switch (Tok.Tok.getKind()) {
+ case tok::kw_break:
+ case tok::kw_case:
+ case tok::kw_catch:
+ case tok::kw_class:
+ case tok::kw_continue:
+ case tok::kw_const:
+ case tok::kw_default:
+ case tok::kw_delete:
+ case tok::kw_do:
+ case tok::kw_else:
+ case tok::kw_enum:
+ case tok::kw_export:
+ case tok::kw_false:
+ case tok::kw_for:
+ case tok::kw_if:
+ case tok::kw_import:
+ case tok::kw_module:
+ case tok::kw_new:
+ case tok::kw_private:
+ case tok::kw_protected:
+ case tok::kw_public:
+ case tok::kw_return:
+ case tok::kw_static:
+ case tok::kw_switch:
+ case tok::kw_this:
+ case tok::kw_throw:
+ case tok::kw_true:
+ case tok::kw_try:
+ case tok::kw_typeof:
+ case tok::kw_void:
+ case tok::kw_while:
+ // These are JS keywords that are lexed by LLVM/clang as keywords.
+ return false;
+ case tok::identifier: {
+ // For identifiers, make sure they are true identifiers, excluding the
+ // JavaScript pseudo-keywords (not lexed by LLVM/clang as keywords).
+ bool IsPseudoKeyword =
+ JsExtraKeywords.find(Tok.Tok.getIdentifierInfo()) !=
+ JsExtraKeywords.end();
+ return AcceptIdentifierName || !IsPseudoKeyword;
+ }
+ default:
+ // Other keywords are handled in the switch below, to avoid problems due
+ // to duplicate case labels when using the #include trick.
+ break;
+ }
+
+ switch (Tok.Tok.getKind()) {
+ // Handle C++ keywords not included above: these are all JS identifiers.
+#define KEYWORD(X, Y) case tok::kw_##X:
+#include "clang/Basic/TokenKinds.def"
+ // #undef KEYWORD is not needed -- it's #undef-ed at the end of
+ // TokenKinds.def
+ return true;
+ default:
+ // All other tokens (punctuation etc) are not JS identifiers.
+ return false;
+ }
}
/// Returns \c true if \p Tok is a C# keyword, returns