mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
This way they can be used from other projects, like LLDB. The downside is we now have to make sure the header is included consistently in all the places we care about, but I think in practice that won't be a problem, especially not with tests. rdar://problem/22240127 Swift SVN r31173
200 lines
4.9 KiB
C++
200 lines
4.9 KiB
C++
//===- SyntaxModel.h - Routines for IDE syntax model ---------------------===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef SWIFT_IDE_SYNTAX_MODEL_H
|
|
#define SWIFT_IDE_SYNTAX_MODEL_H
|
|
|
|
#include "swift/AST/Attr.h"
|
|
#include "swift/Basic/SourceLoc.h"
|
|
#include "swift/Config.h"
|
|
|
|
#include <vector>
|
|
|
|
namespace swift {
|
|
class Decl;
|
|
class ModuleDecl;
|
|
class SourceFile;
|
|
|
|
namespace ide {
|
|
|
|
enum class SyntaxNodeKind : uint8_t {
|
|
Keyword,
|
|
Identifier,
|
|
DollarIdent,
|
|
Integer,
|
|
Floating,
|
|
String,
|
|
/// Marks the parens for a string interpolation.
|
|
StringInterpolationAnchor,
|
|
CommentLine,
|
|
CommentBlock,
|
|
DocCommentLine,
|
|
DocCommentBlock,
|
|
DocCommentField,
|
|
/// A marker like 'FIXME:' or 'TODO:' inside a comment.
|
|
CommentMarker,
|
|
CommentURL,
|
|
TypeId,
|
|
/// #if/#else/#endif occurence.
|
|
BuildConfigKeyword,
|
|
/// An identifier in a #if condition.
|
|
BuildConfigId,
|
|
/// Any occurence of '@<attribute-name>' anywhere.
|
|
AttributeId,
|
|
/// A "resolved/active" attribute. Mis-applied attributes will be AttributeId.
|
|
AttributeBuiltin,
|
|
/// An editor placeholder string <#like this#>.
|
|
EditorPlaceholder,
|
|
#ifdef SWIFT_ENABLE_OBJECT_LITERALS
|
|
/// An editor object literal [#like(this)#]
|
|
ObjectLiteral
|
|
#endif // SWIFT_ENABLE_OBJECT_LITERALS
|
|
};
|
|
|
|
struct SyntaxNode {
|
|
SyntaxNodeKind Kind;
|
|
CharSourceRange Range;
|
|
|
|
SyntaxNode(SyntaxNodeKind Kind, CharSourceRange Range)
|
|
: Kind(Kind), Range(Range) { }
|
|
|
|
bool isComment() const {
|
|
return Kind == SyntaxNodeKind::CommentLine ||
|
|
Kind == SyntaxNodeKind::CommentBlock;
|
|
}
|
|
|
|
bool isInnerCommentNode() const {
|
|
return Kind == SyntaxNodeKind::CommentMarker ||
|
|
Kind == SyntaxNodeKind::CommentURL;
|
|
}
|
|
};
|
|
|
|
enum class SyntaxStructureKind : uint8_t {
|
|
Class,
|
|
Struct,
|
|
Protocol,
|
|
Enum,
|
|
Extension,
|
|
FreeFunction,
|
|
InstanceFunction,
|
|
StaticFunction,
|
|
ClassFunction,
|
|
GlobalVariable,
|
|
InstanceVariable,
|
|
StaticVariable,
|
|
ClassVariable,
|
|
EnumCase,
|
|
EnumElement,
|
|
|
|
ForEachStatement,
|
|
ForStatement,
|
|
WhileStatement,
|
|
RepeatWhileStatement,
|
|
IfStatement,
|
|
GuardStatement,
|
|
SwitchStatement,
|
|
CaseStatement,
|
|
Parameter,
|
|
BraceStatement,
|
|
CallExpression,
|
|
ArrayExpression,
|
|
DictionaryExpression,
|
|
#ifdef SWIFT_ENABLE_OBJECT_LITERALS
|
|
ObjectLiteralExpression,
|
|
#endif // SWIFT_ENABLE_OBJECT_LITERALS
|
|
};
|
|
|
|
enum class SyntaxStructureElementKind : uint8_t {
|
|
Id,
|
|
Expr,
|
|
InitExpr,
|
|
ConditionExpr,
|
|
Pattern,
|
|
TypeRef,
|
|
};
|
|
|
|
struct SyntaxStructureElement {
|
|
SyntaxStructureElementKind Kind;
|
|
CharSourceRange Range;
|
|
|
|
SyntaxStructureElement(SyntaxStructureElementKind Kind, CharSourceRange Range)
|
|
: Kind(Kind), Range(Range) { }
|
|
};
|
|
|
|
struct SyntaxStructureNode {
|
|
const Decl *Dcl = nullptr;
|
|
SyntaxStructureKind Kind;
|
|
DeclAttributes Attrs;
|
|
CharSourceRange Range;
|
|
CharSourceRange BodyRange;
|
|
CharSourceRange NameRange;
|
|
CharSourceRange TypeRange;
|
|
std::vector<CharSourceRange> InheritedTypeRanges;
|
|
std::vector<SyntaxStructureElement> Elements;
|
|
|
|
bool isVariable() const {
|
|
switch (Kind) {
|
|
case SyntaxStructureKind::GlobalVariable:
|
|
case SyntaxStructureKind::InstanceVariable:
|
|
case SyntaxStructureKind::StaticVariable:
|
|
case SyntaxStructureKind::ClassVariable:
|
|
case SyntaxStructureKind::Parameter:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
};
|
|
|
|
class SyntaxModelWalker {
|
|
virtual void anchor();
|
|
|
|
public:
|
|
virtual ~SyntaxModelWalker() {}
|
|
|
|
/// \brief Called when first visiting a syntax node, before walking into its
|
|
/// children. If it returns false, the subtree is skipped.
|
|
///
|
|
virtual bool walkToNodePre(SyntaxNode Node) { return true; }
|
|
|
|
/// \brief Called after visiting the children of a syntax node. If it returns
|
|
/// false, the remaining traversal is terminated and returns failure.
|
|
virtual bool walkToNodePost(SyntaxNode Node) { return true; }
|
|
|
|
/// \brief Called when first visiting a sub-structure node, before walking
|
|
/// into its children. If it returns false, the subtree is skipped.
|
|
///
|
|
virtual bool walkToSubStructurePre(SyntaxStructureNode Node) { return true; }
|
|
|
|
/// \brief Called after visiting the children of a sub-structure node. If it
|
|
/// returns false, the remaining traversal is terminated and returns failure.
|
|
///
|
|
virtual bool walkToSubStructurePost(SyntaxStructureNode Node) { return true; }
|
|
};
|
|
|
|
class SyntaxModelContext {
|
|
struct Implementation;
|
|
Implementation &Impl;
|
|
|
|
public:
|
|
explicit SyntaxModelContext(SourceFile &SrcFile);
|
|
~SyntaxModelContext();
|
|
|
|
bool walk(SyntaxModelWalker &Walker);
|
|
};
|
|
|
|
} // namespace ide
|
|
} // namespace swift
|
|
|
|
#endif // SWIFT_IDE_SYNTAX_MODEL_H
|
|
|