37
37
#include " swift/IDE/SyntaxModel.h"
38
38
#include " swift/Subsystems.h"
39
39
#include " swift/Syntax/Serialization/SyntaxSerialization.h"
40
+ #include " swift/Syntax/SyntaxClassifier.h"
40
41
#include " swift/Syntax/SyntaxNodes.h"
41
42
42
43
#include " llvm/Support/ErrorHandling.h"
@@ -557,6 +558,122 @@ struct SwiftSyntaxMap {
557
558
}
558
559
};
559
560
561
+ class SyntaxToSyntaxMapConverter : public SyntaxVisitor {
562
+ SwiftSyntaxMap &SyntaxMap;
563
+
564
+ std::map<unsigned , SyntaxClassification> TokenClassifications;
565
+
566
+ public:
567
+ SyntaxToSyntaxMapConverter (
568
+ SwiftSyntaxMap &SyntaxMap,
569
+ std::map<unsigned , SyntaxClassification> TokenClassifications)
570
+ : SyntaxMap(SyntaxMap), TokenClassifications(TokenClassifications) {}
571
+
572
+ private:
573
+ void visitTrivia (Trivia Trivia, unsigned Offset) {
574
+ for (auto TriviaPiece : Trivia) {
575
+ visitTriviaPiece (TriviaPiece, Offset);
576
+ Offset += TriviaPiece.getTextLength ();
577
+ }
578
+ }
579
+
580
+ void visitTriviaPiece (TriviaPiece TriviaPiece, unsigned Offset) {
581
+ llvm::Optional<SyntaxNodeKind> Kind;
582
+ switch (TriviaPiece.getKind ()) {
583
+ case TriviaKind::Space:
584
+ case TriviaKind::Tab:
585
+ case TriviaKind::VerticalTab:
586
+ case TriviaKind::Formfeed:
587
+ case TriviaKind::Newline:
588
+ case TriviaKind::CarriageReturn:
589
+ case TriviaKind::CarriageReturnLineFeed:
590
+ case swift::syntax::TriviaKind::Backtick:
591
+ case TriviaKind::GarbageText:
592
+ Kind = llvm::None;
593
+ break ;
594
+ case swift::syntax::TriviaKind::LineComment:
595
+ Kind = SyntaxNodeKind::CommentLine;
596
+ break ;
597
+ case TriviaKind::BlockComment:
598
+ Kind = SyntaxNodeKind::CommentBlock;
599
+ break ;
600
+ case TriviaKind::DocLineComment:
601
+ Kind = SyntaxNodeKind::DocCommentLine;
602
+ break ;
603
+ case TriviaKind::DocBlockComment:
604
+ Kind = SyntaxNodeKind::DocCommentBlock;
605
+ break ;
606
+ }
607
+ if (Kind.hasValue ()) {
608
+ SwiftSyntaxToken Token (Offset, TriviaPiece.getTextLength (),
609
+ Kind.getValue ());
610
+ SyntaxMap.addToken (Token);
611
+ }
612
+ }
613
+
614
+ llvm::Optional<SyntaxNodeKind>
615
+ getKindForSyntaxClassification (SyntaxClassification Classification) const {
616
+ // FIXME: We should really use the same enum so that the conversion is not
617
+ // necessary
618
+ switch (Classification) {
619
+ case SyntaxClassification::None:
620
+ return llvm::None;
621
+ case SyntaxClassification::Keyword:
622
+ return SyntaxNodeKind::Keyword;
623
+ case SyntaxClassification::Identifier:
624
+ return SyntaxNodeKind::Identifier;
625
+ case SyntaxClassification::DollarIdentifier:
626
+ return SyntaxNodeKind::DollarIdent;
627
+ case SyntaxClassification::IntegerLiteral:
628
+ return SyntaxNodeKind::Integer;
629
+ case SyntaxClassification::FloatingLiteral:
630
+ return SyntaxNodeKind::Floating;
631
+ case SyntaxClassification::StringLiteral:
632
+ return SyntaxNodeKind::String;
633
+ case SyntaxClassification::StringInterpolationAnchor:
634
+ return SyntaxNodeKind::StringInterpolationAnchor;
635
+ case SyntaxClassification::TypeIdentifier:
636
+ return SyntaxNodeKind::TypeId;
637
+ case SyntaxClassification::BuildConfigKeyword:
638
+ return SyntaxNodeKind::BuildConfigKeyword;
639
+ case SyntaxClassification::BuildConfigId:
640
+ return SyntaxNodeKind::BuildConfigId;
641
+ case SyntaxClassification::PoundDirectiveKeyword:
642
+ return SyntaxNodeKind::PoundDirectiveKeyword;
643
+ case SyntaxClassification::Attribute:
644
+ return SyntaxNodeKind::AttributeBuiltin;
645
+ case SyntaxClassification::EditorPlaceholder:
646
+ return SyntaxNodeKind::EditorPlaceholder;
647
+ case SyntaxClassification::ObjectLiteral:
648
+ return SyntaxNodeKind::ObjectLiteral;
649
+ }
650
+ }
651
+
652
+ virtual void visit (TokenSyntax Token) override {
653
+ if (Token.isMissing ())
654
+ return ;
655
+
656
+ auto LeadingTriviaOffset =
657
+ Token.getAbsolutePositionWithLeadingTrivia ().getOffset ();
658
+ visitTrivia (Token.getLeadingTrivia (), LeadingTriviaOffset);
659
+
660
+ SyntaxClassification Classification = TokenClassifications[Token.getId ()];
661
+ auto Kind = getKindForSyntaxClassification (Classification);
662
+ unsigned TokenStart = Token.getAbsolutePosition ().getOffset ();
663
+ unsigned TokenLength = Token.getRaw ()->getTokenText ().size ();
664
+ if (Kind.hasValue () && TokenLength > 0 ) {
665
+ SwiftSyntaxToken Token (TokenStart, TokenLength, Kind.getValue ());
666
+ SyntaxMap.addToken (Token);
667
+ }
668
+
669
+ auto TrailingTriviaOffset = TokenStart + TokenLength;
670
+ visitTrivia (Token.getTrailingTrivia (), TrailingTriviaOffset);
671
+ }
672
+
673
+ public:
674
+ void writeToSyntaxMap (Syntax Node) { Node.accept (*this ); }
675
+ };
676
+
560
677
struct EditorConsumerSyntaxMapEntry {
561
678
unsigned Offset;
562
679
unsigned Length;
@@ -1772,8 +1889,6 @@ void SwiftEditorDocument::readSyntaxInfo(EditorConsumer &Consumer) {
1772
1889
1773
1890
Impl.ParserDiagnostics = Impl.SyntaxInfo ->getDiagnostics ();
1774
1891
1775
- ide::SyntaxModelContext ModelContext (Impl.SyntaxInfo ->getSourceFile ());
1776
-
1777
1892
if (Consumer.syntaxTreeEnabled ()) {
1778
1893
std::string SyntaxContent;
1779
1894
llvm::raw_string_ostream OS (SyntaxContent);
@@ -1785,11 +1900,21 @@ void SwiftEditorDocument::readSyntaxInfo(EditorConsumer &Consumer) {
1785
1900
1786
1901
SwiftSyntaxMap NewMap = SwiftSyntaxMap (Impl.SyntaxMap .Tokens .size () + 16 );
1787
1902
1788
- SwiftEditorSyntaxWalker SyntaxWalker (NewMap,
1789
- Impl.SyntaxInfo ->getSourceManager (),
1790
- Consumer,
1791
- Impl.SyntaxInfo ->getBufferID ());
1792
- ModelContext.walk (SyntaxWalker);
1903
+ if (Consumer.forceLibSyntaxBasedProcessing ()) {
1904
+ auto SyntaxTree = Impl.SyntaxInfo ->getSourceFile ().getSyntaxRoot ();
1905
+
1906
+ SyntaxClassifier Classifier;
1907
+ auto Classification = Classifier.classify (SyntaxTree);
1908
+ SyntaxToSyntaxMapConverter Printer (NewMap, Classification);
1909
+ Printer.writeToSyntaxMap (SyntaxTree);
1910
+ } else {
1911
+ ide::SyntaxModelContext ModelContext (Impl.SyntaxInfo ->getSourceFile ());
1912
+
1913
+ SwiftEditorSyntaxWalker SyntaxWalker (
1914
+ NewMap, Impl.SyntaxInfo ->getSourceManager (), Consumer,
1915
+ Impl.SyntaxInfo ->getBufferID ());
1916
+ ModelContext.walk (SyntaxWalker);
1917
+ }
1793
1918
1794
1919
bool SawChanges = true ;
1795
1920
if (Impl.Edited ) {
@@ -2034,7 +2159,8 @@ void SwiftLangSupport::editorOpen(StringRef Name, llvm::MemoryBuffer *Buf,
2034
2159
ArrayRef<const char *> Args) {
2035
2160
2036
2161
ImmutableTextSnapshotRef Snapshot = nullptr ;
2037
- const bool BuildSyntaxTree = Consumer.syntaxTreeEnabled ();
2162
+ const bool BuildSyntaxTree =
2163
+ Consumer.syntaxTreeEnabled () || Consumer.forceLibSyntaxBasedProcessing ();
2038
2164
auto EditorDoc = EditorDocuments.getByUnresolvedName (Name);
2039
2165
if (!EditorDoc) {
2040
2166
EditorDoc = new SwiftEditorDocument (Name, *this );
@@ -2101,7 +2227,9 @@ void SwiftLangSupport::editorReplaceText(StringRef Name,
2101
2227
Snapshot = EditorDoc->replaceText (Offset, Length, Buf,
2102
2228
Consumer.needsSemanticInfo ());
2103
2229
assert (Snapshot);
2104
- EditorDoc->parse (Snapshot, *this , Consumer.syntaxTreeEnabled ());
2230
+ bool BuildSyntaxTree = Consumer.syntaxTreeEnabled () ||
2231
+ Consumer.forceLibSyntaxBasedProcessing ();
2232
+ EditorDoc->parse (Snapshot, *this , BuildSyntaxTree);
2105
2233
EditorDoc->readSyntaxInfo (Consumer);
2106
2234
} else {
2107
2235
Snapshot = EditorDoc->getLatestSnapshot ();
0 commit comments