[PATCH] D39571: [clangd] DidChangeConfiguration Notification

2018-01-23 Thread William Enright via Phabricator via cfe-commits
Nebiroth added inline comments.



Comment at: clangd/ClangdLSPServer.cpp:78
 {"documentHighlightProvider", true},
+{"configurationChangeProvider", true},
 {"renameProvider", true},

simark wrote:
> I find `configurationChangeProvider` a bit weird.  It makes it sound like 
> clangd can provide configuration changes.  In reality, it can accept 
> configuration changes.  So I think this should be named something else.
Agreed, perhaps configurationChangeManager would be more appropriate then?


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D39571



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38639: [clangd] #include statements support for Open definition

2017-12-21 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 127900.
Nebiroth marked 11 inline comments as done.
Nebiroth added a comment.

  Minor code cleanup


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D38639

Files:
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.h
  clangd/XRefs.cpp
  unittests/clangd/ClangdTests.cpp

Index: unittests/clangd/ClangdTests.cpp
===
--- unittests/clangd/ClangdTests.cpp
+++ unittests/clangd/ClangdTests.cpp
@@ -7,7 +7,6 @@
 //
 //===--===//
 
-#include "ClangdLSPServer.h"
 #include "ClangdServer.h"
 #include "Context.h"
 #include "TestFS.h"
@@ -751,6 +750,75 @@
   EXPECT_FALSE(PathResult.hasValue());
 }
 
+TEST_F(ClangdVFSTest, CheckDefinitionIncludes) {
+  MockFSProvider FS;
+  ErrorCheckingDiagConsumer DiagConsumer;
+  MockCompilationDatabase CDB;
+
+  ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(),
+  /*StorePreamblesInMemory=*/true,
+  EmptyLogger::getInstance());
+
+  auto FooCpp = getVirtualTestFilePath("foo.cpp");
+  const auto SourceContents = R"cpp(
+  #include "foo.h"
+  #include "invalid.h"
+  int b = a;
+  // test
+  int foo;
+  #include "foo.h"
+  )cpp";
+  FS.Files[FooCpp] = SourceContents;
+  auto FooH = getVirtualTestFilePath("foo.h");
+  const auto HeaderContents = "int a;";
+
+  FS.Files[FooCpp] = SourceContents;
+  FS.Files[FooH] = HeaderContents;
+
+  Server.addDocument(FooH, HeaderContents);
+  Server.addDocument(FooCpp, SourceContents);
+
+  Position P = Position{1, 11};
+
+  auto ExpectedLocations = Server.findDefinitions(FooCpp, P);
+  ASSERT_TRUE(!!ExpectedLocations);
+  std::vector Locations = ExpectedLocations->Value;
+  EXPECT_TRUE(!Locations.empty());
+  std::string s("file:///");
+  std::string check = Locations[0].uri.uri;
+  check = check.erase(0, s.size() - 1);
+  check = check.substr(0, check.size());
+  ASSERT_EQ(check, FooH);
+  ASSERT_EQ(Locations[0].range.start.line, 0);
+  ASSERT_EQ(Locations[0].range.start.character, 0);
+  ASSERT_EQ(Locations[0].range.end.line, 0);
+  ASSERT_EQ(Locations[0].range.end.character, 0);
+
+  // Test ctrl-clicking on the #include part on the statement
+  Position P2 = Position{1, 3};
+
+  ExpectedLocations = Server.findDefinitions(FooCpp, P2);
+  ASSERT_TRUE(!!ExpectedLocations);
+  Locations = ExpectedLocations->Value;
+  EXPECT_TRUE(!Locations.empty());
+
+  // Test invalid include
+  Position P3 = Position{2, 11};
+
+  ExpectedLocations = Server.findDefinitions(FooCpp, P3);
+  ASSERT_TRUE(!!ExpectedLocations);
+  Locations = ExpectedLocations->Value;
+  EXPECT_TRUE(Locations.empty());
+
+  // Test include outside of Preamble
+  Position P4  = Position{6, 5};
+
+  ExpectedLocations = Server.findDefinitions(FooCpp, P4);
+  ASSERT_TRUE(!!ExpectedLocations);
+  Locations = ExpectedLocations->Value;
+  EXPECT_TRUE(!Locations.empty());
+}
+
 TEST_F(ClangdThreadingTest, NoConcurrentDiagnostics) {
   class NoConcurrentAccessDiagConsumer : public DiagnosticsConsumer {
   public:
Index: clangd/XRefs.cpp
===
--- clangd/XRefs.cpp
+++ clangd/XRefs.cpp
@@ -18,6 +18,7 @@
 class DeclarationAndMacrosFinder : public index::IndexDataConsumer {
   std::vector Decls;
   std::vector MacroInfos;
+  std::vector DeclarationLocations;
   const SourceLocation 
   const ASTContext 
   Preprocessor 
@@ -37,14 +38,26 @@
 return std::move(Decls);
   }
 
+  std::vector takeLocations() {
+// Don't keep the same location multiple times.
+// This can happen when nodes in the AST are visited twice.
+std::sort(DeclarationLocations.begin(), DeclarationLocations.end());
+auto Last =
+std::unique(DeclarationLocations.begin(), DeclarationLocations.end());
+DeclarationLocations.erase(Last, DeclarationLocations.end());
+return std::move(DeclarationLocations);
+  }
+
   std::vector takeMacroInfos() {
 // Don't keep the same Macro info multiple times.
 std::sort(MacroInfos.begin(), MacroInfos.end());
 auto Last = std::unique(MacroInfos.begin(), MacroInfos.end());
 MacroInfos.erase(Last, MacroInfos.end());
 return std::move(MacroInfos);
   }
 
+  const SourceLocation () { return SearchedLocation; };
+
   bool
   handleDeclOccurence(const Decl *D, index::SymbolRoleSet Roles,
   ArrayRef Relations, FileID FID,
@@ -62,6 +75,25 @@
SourceMgr.getFileID(SearchedLocation) == FID;
   }
 
+  void addDeclarationLocation(const SourceRange ) {
+const SourceManager  = AST.getSourceManager();
+const LangOptions  = AST.getLangOpts();
+SourceLocation LocStart = ValSourceRange.getBegin();
+SourceLocation LocEnd = Lexer::getLocForEndOfToken(ValSourceRange.getEnd(),
+   0, SourceMgr, LangOpts);
+Position Begin;
+Begin.line = SourceMgr.getSpellingLineNumber(LocStart) 

[PATCH] D41365: [clang] Add BeforeExecute method to PrecompiledPreamble

2017-12-20 Thread William Enright via Phabricator via cfe-commits
Nebiroth added a comment.

Yes please land this.


Repository:
  rC Clang

https://reviews.llvm.org/D41365



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41365: [clang] Add BeforeExecute method to PrecompiledPreamble

2017-12-20 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 127715.
Nebiroth added a comment.

Updated BeforeExecute comment


Repository:
  rC Clang

https://reviews.llvm.org/D41365

Files:
  include/clang/Frontend/PrecompiledPreamble.h
  lib/Frontend/PrecompiledPreamble.cpp


Index: lib/Frontend/PrecompiledPreamble.cpp
===
--- lib/Frontend/PrecompiledPreamble.cpp
+++ lib/Frontend/PrecompiledPreamble.cpp
@@ -348,6 +348,7 @@
   std::unique_ptr Act;
   Act.reset(new PrecompilePreambleAction(
   StoreInMemory ? ().Data : nullptr, Callbacks));
+  Callbacks.BeforeExecute(*Clang);
   if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0]))
 return BuildPreambleError::BeginSourceFileFailed;
 
@@ -704,6 +705,7 @@
   }
 }
 
+void PreambleCallbacks::BeforeExecute(CompilerInstance ) {}
 void PreambleCallbacks::AfterExecute(CompilerInstance ) {}
 void PreambleCallbacks::AfterPCHEmitted(ASTWriter ) {}
 void PreambleCallbacks::HandleTopLevelDecl(DeclGroupRef DG) {}
Index: include/clang/Frontend/PrecompiledPreamble.h
===
--- include/clang/Frontend/PrecompiledPreamble.h
+++ include/clang/Frontend/PrecompiledPreamble.h
@@ -244,6 +244,10 @@
 public:
   virtual ~PreambleCallbacks() = default;
 
+  /// Called before FrontendAction::BeginSourceFile.
+  /// Can be used to store references to various CompilerInstance fields
+  /// (e.g. SourceManager) that may be interesting to the consumers of other 
callbacks.
+  virtual void BeforeExecute(CompilerInstance );
   /// Called after FrontendAction::Execute(), but before
   /// FrontendAction::EndSourceFile(). Can be used to transfer ownership of
   /// various CompilerInstance fields before they are destroyed.


Index: lib/Frontend/PrecompiledPreamble.cpp
===
--- lib/Frontend/PrecompiledPreamble.cpp
+++ lib/Frontend/PrecompiledPreamble.cpp
@@ -348,6 +348,7 @@
   std::unique_ptr Act;
   Act.reset(new PrecompilePreambleAction(
   StoreInMemory ? ().Data : nullptr, Callbacks));
+  Callbacks.BeforeExecute(*Clang);
   if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0]))
 return BuildPreambleError::BeginSourceFileFailed;
 
@@ -704,6 +705,7 @@
   }
 }
 
+void PreambleCallbacks::BeforeExecute(CompilerInstance ) {}
 void PreambleCallbacks::AfterExecute(CompilerInstance ) {}
 void PreambleCallbacks::AfterPCHEmitted(ASTWriter ) {}
 void PreambleCallbacks::HandleTopLevelDecl(DeclGroupRef DG) {}
Index: include/clang/Frontend/PrecompiledPreamble.h
===
--- include/clang/Frontend/PrecompiledPreamble.h
+++ include/clang/Frontend/PrecompiledPreamble.h
@@ -244,6 +244,10 @@
 public:
   virtual ~PreambleCallbacks() = default;
 
+  /// Called before FrontendAction::BeginSourceFile.
+  /// Can be used to store references to various CompilerInstance fields
+  /// (e.g. SourceManager) that may be interesting to the consumers of other callbacks.
+  virtual void BeforeExecute(CompilerInstance );
   /// Called after FrontendAction::Execute(), but before
   /// FrontendAction::EndSourceFile(). Can be used to transfer ownership of
   /// various CompilerInstance fields before they are destroyed.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41365: [clang] Add BeforeExecute method to PrecompiledPreamble

2017-12-19 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 127619.
Nebiroth marked 2 inline comments as done.
Nebiroth added a comment.

Modified comment
Changed where BeforeExecute is called


Repository:
  rC Clang

https://reviews.llvm.org/D41365

Files:
  include/clang/Frontend/PrecompiledPreamble.h
  lib/Frontend/PrecompiledPreamble.cpp


Index: lib/Frontend/PrecompiledPreamble.cpp
===
--- lib/Frontend/PrecompiledPreamble.cpp
+++ lib/Frontend/PrecompiledPreamble.cpp
@@ -348,6 +348,7 @@
   std::unique_ptr Act;
   Act.reset(new PrecompilePreambleAction(
   StoreInMemory ? ().Data : nullptr, Callbacks));
+  Callbacks.BeforeExecute(*Clang);
   if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0]))
 return BuildPreambleError::BeginSourceFileFailed;
 
@@ -704,6 +705,7 @@
   }
 }
 
+void PreambleCallbacks::BeforeExecute(CompilerInstance ) {}
 void PreambleCallbacks::AfterExecute(CompilerInstance ) {}
 void PreambleCallbacks::AfterPCHEmitted(ASTWriter ) {}
 void PreambleCallbacks::HandleTopLevelDecl(DeclGroupRef DG) {}
Index: include/clang/Frontend/PrecompiledPreamble.h
===
--- include/clang/Frontend/PrecompiledPreamble.h
+++ include/clang/Frontend/PrecompiledPreamble.h
@@ -244,6 +244,9 @@
 public:
   virtual ~PreambleCallbacks() = default;
 
+  /// Can be used to store references to various CompilerInstance fields
+  /// (e.g. SourceManager) that may be interesting to the consumers of other 
callbacks.
+  virtual void BeforeExecute(CompilerInstance );
   /// Called after FrontendAction::Execute(), but before
   /// FrontendAction::EndSourceFile(). Can be used to transfer ownership of
   /// various CompilerInstance fields before they are destroyed.


Index: lib/Frontend/PrecompiledPreamble.cpp
===
--- lib/Frontend/PrecompiledPreamble.cpp
+++ lib/Frontend/PrecompiledPreamble.cpp
@@ -348,6 +348,7 @@
   std::unique_ptr Act;
   Act.reset(new PrecompilePreambleAction(
   StoreInMemory ? ().Data : nullptr, Callbacks));
+  Callbacks.BeforeExecute(*Clang);
   if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0]))
 return BuildPreambleError::BeginSourceFileFailed;
 
@@ -704,6 +705,7 @@
   }
 }
 
+void PreambleCallbacks::BeforeExecute(CompilerInstance ) {}
 void PreambleCallbacks::AfterExecute(CompilerInstance ) {}
 void PreambleCallbacks::AfterPCHEmitted(ASTWriter ) {}
 void PreambleCallbacks::HandleTopLevelDecl(DeclGroupRef DG) {}
Index: include/clang/Frontend/PrecompiledPreamble.h
===
--- include/clang/Frontend/PrecompiledPreamble.h
+++ include/clang/Frontend/PrecompiledPreamble.h
@@ -244,6 +244,9 @@
 public:
   virtual ~PreambleCallbacks() = default;
 
+  /// Can be used to store references to various CompilerInstance fields
+  /// (e.g. SourceManager) that may be interesting to the consumers of other callbacks.
+  virtual void BeforeExecute(CompilerInstance );
   /// Called after FrontendAction::Execute(), but before
   /// FrontendAction::EndSourceFile(). Can be used to transfer ownership of
   /// various CompilerInstance fields before they are destroyed.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38639: [clangd] #include statements support for Open definition

2017-12-19 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 127617.
Nebiroth added a comment.

  Removed some useless inclusions
  Removed superfluous check when inserting data in map
  Moved addition to DeclarationLocations in finish() outside of DeclMacrosFinder
  Merged with revision 321087 (moved findDefinitions and findDocumentHighlights 


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D38639

Files:
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/CodeComplete.cpp
  clangd/Protocol.h
  clangd/XRefs.cpp
  unittests/clangd/ClangdTests.cpp

Index: unittests/clangd/ClangdTests.cpp
===
--- unittests/clangd/ClangdTests.cpp
+++ unittests/clangd/ClangdTests.cpp
@@ -7,7 +7,6 @@
 //
 //===--===//
 
-#include "ClangdLSPServer.h"
 #include "ClangdServer.h"
 #include "Context.h"
 #include "TestFS.h"
@@ -751,6 +750,75 @@
   EXPECT_FALSE(PathResult.hasValue());
 }
 
+TEST_F(ClangdVFSTest, CheckDefinitionIncludes) {
+  MockFSProvider FS;
+  ErrorCheckingDiagConsumer DiagConsumer;
+  MockCompilationDatabase CDB;
+
+  ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(),
+  /*StorePreamblesInMemory=*/true,
+  EmptyLogger::getInstance());
+
+  auto FooCpp = getVirtualTestFilePath("foo.cpp");
+  const auto SourceContents = R"cpp(
+  #include "foo.h"
+  #include "invalid.h"
+  int b = a;
+  // test
+  int foo;
+  #include "foo.h"
+  )cpp";
+  FS.Files[FooCpp] = SourceContents;
+  auto FooH = getVirtualTestFilePath("foo.h");
+  const auto HeaderContents = "int a;";
+
+  FS.Files[FooCpp] = SourceContents;
+  FS.Files[FooH] = HeaderContents;
+
+  Server.addDocument(FooH, HeaderContents);
+  Server.addDocument(FooCpp, SourceContents);
+
+  Position P = Position{1, 11};
+
+  auto ExpectedLocations = Server.findDefinitions(FooCpp, P);
+  ASSERT_TRUE(!!ExpectedLocations);
+  std::vector Locations = ExpectedLocations->Value;
+  EXPECT_TRUE(!Locations.empty());
+  std::string s("file:///");
+  std::string check = Locations[0].uri.uri;
+  check = check.erase(0, s.size() - 1);
+  check = check.substr(0, check.size());
+  ASSERT_EQ(check, FooH);
+  ASSERT_EQ(Locations[0].range.start.line, 0);
+  ASSERT_EQ(Locations[0].range.start.character, 0);
+  ASSERT_EQ(Locations[0].range.end.line, 0);
+  ASSERT_EQ(Locations[0].range.end.character, 0);
+
+  // Test ctrl-clicking on the #include part on the statement
+  Position P2 = Position{1, 3};
+
+  ExpectedLocations = Server.findDefinitions(FooCpp, P2);
+  ASSERT_TRUE(!!ExpectedLocations);
+  Locations = ExpectedLocations->Value;
+  EXPECT_TRUE(!Locations.empty());
+
+  // Test invalid include
+  Position P3 = Position{2, 11};
+
+  ExpectedLocations = Server.findDefinitions(FooCpp, P3);
+  ASSERT_TRUE(!!ExpectedLocations);
+  Locations = ExpectedLocations->Value;
+  EXPECT_TRUE(Locations.empty());
+
+  // Test include outside of Preamble
+  Position P4  = Position{6, 5};
+
+  ExpectedLocations = Server.findDefinitions(FooCpp, P4);
+  ASSERT_TRUE(!!ExpectedLocations);
+  Locations = ExpectedLocations->Value;
+  EXPECT_TRUE(!Locations.empty());
+}
+
 TEST_F(ClangdThreadingTest, NoConcurrentDiagnostics) {
   class NoConcurrentAccessDiagConsumer : public DiagnosticsConsumer {
   public:
Index: clangd/XRefs.cpp
===
--- clangd/XRefs.cpp
+++ clangd/XRefs.cpp
@@ -18,6 +18,7 @@
 class DeclarationAndMacrosFinder : public index::IndexDataConsumer {
   std::vector Decls;
   std::vector MacroInfos;
+  std::vector DeclarationLocations;
   const SourceLocation 
   const ASTContext 
   Preprocessor 
@@ -37,14 +38,26 @@
 return std::move(Decls);
   }
 
+  std::vector takeLocations() {
+// Don't keep the same location multiple times.
+// This can happen when nodes in the AST are visited twice.
+std::sort(DeclarationLocations.begin(), DeclarationLocations.end());
+auto Last =
+std::unique(DeclarationLocations.begin(), DeclarationLocations.end());
+DeclarationLocations.erase(Last, DeclarationLocations.end());
+return std::move(DeclarationLocations);
+  }
+
   std::vector takeMacroInfos() {
 // Don't keep the same Macro info multiple times.
 std::sort(MacroInfos.begin(), MacroInfos.end());
 auto Last = std::unique(MacroInfos.begin(), MacroInfos.end());
 MacroInfos.erase(Last, MacroInfos.end());
 return std::move(MacroInfos);
   }
 
+  const SourceLocation () { return SearchedLocation; };
+
   bool
   handleDeclOccurence(const Decl *D, index::SymbolRoleSet Roles,
   ArrayRef Relations, FileID FID,
@@ -62,6 +75,25 @@
SourceMgr.getFileID(SearchedLocation) == FID;
   }
 
+  void addDeclarationLocation(const SourceRange ) {
+const SourceManager  = AST.getSourceManager();
+const LangOptions  = AST.getLangOpts();
+SourceLocation LocStart = ValSourceRange.getBegin();
+SourceLocation LocEnd = 

[PATCH] D38639: [clangd] #include statements support for Open definition

2017-12-19 Thread William Enright via Phabricator via cfe-commits
Nebiroth marked 8 inline comments as done.
Nebiroth added inline comments.



Comment at: clangd/ClangdUnit.cpp:85
+
+if (SourceMgr.getMainFileID() == 
SourceMgr.getFileID(FilenameRange.getAsRange().getBegin()) && 
SourceMgr.isInMainFile(FilenameRange.getAsRange().getBegin())) {
+  // Only inclusion directives in the main file make sense. The user cannot

ilya-biryukov wrote:
> ilya-biryukov wrote:
> > `clang-format` please
> Do we need both checks? Doesn't `SourceMgr.isInMainFile` handles all the 
> cases?
This check was here to prevent an issue that appeared previously. I don't think 
this check is needed anymore.



Comment at: clangd/ClangdUnit.cpp:147
+  IncludeReferenceMap 
+  std::vector> 
TempPreambleIncludeLocations;
 };

ilya-biryukov wrote:
> We should have `SourceMgr` at all the proper places now, let's store 
> `IncludeReferenceMap` directly
The idea was to pass a single map around to fill with every reference instead 
of having separate maps being merged together.



Comment at: clangd/ClangdUnit.cpp:281
+ IntrusiveRefCntPtr VFS,
+ IncludeReferenceMap IRM) {
 

ilya-biryukov wrote:
> What reference does this `IncludeReferenceMap` contain? Includes from the 
> preamble? 
This should contain every reference available for one file.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D38639



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D35894: [clangd] Code hover for Clangd

2017-12-18 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 127413.
Nebiroth marked 3 inline comments as done.
Nebiroth added a comment.

  findHover properly returns an error
  Removed many cases of bad merging
  Separated getHover in two functions
  Minor indenting and NIT fixes


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D35894

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/hover.test
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -31,6 +31,7 @@
 # CHECK-NEXT:  "clangd.applyFix"
 # CHECK-NEXT:]
 # CHECK-NEXT:  },
+# CHECK-NEXT:  "hoverProvider": true,
 # CHECK-NEXT:  "renameProvider": true,
 # CHECK-NEXT:  "signatureHelpProvider": {
 # CHECK-NEXT:"triggerCharacters": [
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -31,6 +31,7 @@
 # CHECK-NEXT:  "clangd.applyFix"
 # CHECK-NEXT:]
 # CHECK-NEXT:  },
+# CHECK-NEXT:  "hoverProvider": true,
 # CHECK-NEXT:  "renameProvider": true,
 # CHECK-NEXT:  "signatureHelpProvider": {
 # CHECK-NEXT:"triggerCharacters": [
Index: test/clangd/hover.test
===
--- /dev/null
+++ test/clangd/hover.test
@@ -0,0 +1,56 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 611
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#define MACRO 1\nnamespace ns1 {\nint test = 5;\nstruct MyClass {\nint xasd;\nvoid anotherOperation() {\n}\nstatic int foo(MyClass*) {\nreturn 0;\n}\n\n};}\n//comments test\ntemplate\nT templateTest(T foo) {\nreturn foo;}\ntemplate\nclass classTemplateTest {\npublic: T test;};\nint main() {\nint a;\na;\nint b = ns1::test;\nns1::MyClass* Params;\nParams->anotherOperation();\nMACRO;\nint temp = 5;\ntemplateTest(temp);classTemplateTest test;}\n"}}}
+
+Content-Length: 144
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":0,"character":12}}}
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"#define MACRO 1"}],"range":{"end":{"character":15,"line":0},"start":{"character":8,"line":0
+
+Content-Length: 144
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":21,"character":1}}}
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"int a"}],"range":{"end":{"character":5,"line":20},"start":{"character":0,"line":20
+
+Content-Length: 145
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":22,"character":15}}}
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"In ns1"},{"language":"C++","value":"int test = 5"}],"range":{"end":{"character":12,"line":2},"start":{"character":0,"line":2
+
+Content-Length: 145
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":23,"character":10}}}
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"In ns1"},{"language":"C++","value":"struct MyClass {"}],"range":{"end":{"character":16,"line":3},"start":{"character":0,"line":3
+
+Content-Length: 145
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":24,"character":13}}}
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"In ns1::MyClass"},{"language":"C++","value":"void anotherOperation() {"}],"range":{"end":{"character":25,"line":5},"start":{"character":0,"line":5
+
+Content-Length: 144
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":25,"character":1}}}
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"#define MACRO 1"}],"range":{"end":{"character":15,"line":0},"start":{"character":8,"line":0
+
+Content-Length: 144
+

[PATCH] D35894: [clangd] Code hover for Clangd

2017-12-18 Thread William Enright via Phabricator via cfe-commits
Nebiroth marked 21 inline comments as done.
Nebiroth added inline comments.



Comment at: clangd/ClangdServer.h:306
+  /// Run formatting for \p Rng inside \p File.
+  std::vector formatRange(PathRef File, Range Rng);
+  /// Run formatting for the whole \p File.

ilya-biryukov wrote:
> These functions are duplicates of existing ones, they should not be here.
> Bad merge?
Yes, this is a bad merge.



Comment at: clangd/ClangdUnit.cpp:438
+  // trimming the extra "::"
+  std::string Res;
+  PrintingPolicy WithScopePP(LangOpts);

ilya-biryukov wrote:
> We should avoid doing the string-matching when we have the AST.
> Use something like this instead (haven't tested, but you should get the idea):
> 
> ```
> /// Returns a NamedDecl that could be used to print the qualifier.
> Decl* getScopeOfDecl(Decl* D) {
>   // Code from NamedDecl::printQualifiedName, we should probably move it into 
>   const DeclContext *Ctx = D->getDeclContext();
> 
>   // For ObjC methods, look through categories and use the interface as 
> context.
>   if (auto *MD = dyn_cast(D))
> if (auto *ID = MD->getClassInterface())
>   Ctx = ID;
> 
>   if (Ctx->isFunctionOrMethod()) {
> /// This is a function-local entity.
> return nullptr;
>   }
> 
>   return Ctx;
> }
> 
> 
> std::string printScopeOfDecl(Decl* Scope) {
>   if (isa(Scope))
> return "global namespace";
> 
>   if (isa(Scope))
> return cast(Scope)->printQualifiedName();
> 
>   return "";
> }
> 
> 
> // Later use like this:
> auto ScopeText = printScopeOfDecl(getScopeOfDecl(D));
> ```
> 
I'm not sure I understand. The intention was to have a separate MarkedString 
display the scope for whatever we are hovering on. The way I understand the 
above code, this would display a scope that isn't as precise as I would like 
which defeats the purpose of having this feature in the first place.



Comment at: clangd/ClangdUnit.cpp:498
   Position Begin;
-  Begin.line = SourceMgr.getSpellingLineNumber(LocStart) - 1;
-  Begin.character = SourceMgr.getSpellingColumnNumber(LocStart) - 1;
+  Begin.line = SourceMgr.getExpansionLineNumber(LocStart) - 1;
+  Begin.character = SourceMgr.getExpansionColumnNumber(LocStart) - 1;

ilya-biryukov wrote:
> Why are we changing the semantics here? Why should we use expansion locations 
> instead of spelling locations here?
Bad merge.



Comment at: clangd/ClangdUnit.cpp:591
+// one line at a time to determine what will be included.
+SourceLocation getFunctionComments(ParsedAST , const Decl *D) {
+

ilya-biryukov wrote:
> This code seems pretty involved. Don't `RawComment`s handle this case?
Bad merge.



Comment at: clangd/ClangdUnit.cpp:968
   // createInvocationFromCommandLine sets DisableFree.
+  CI->LangOpts->CommentOpts.ParseAllComments = true;
   CI->getFrontendOpts().DisableFree = false;

ilya-biryukov wrote:
> This should clearly go before the comment!
> Also, we're currently setting this flag when building the preamble, but not 
> when parsing the AST. We should definitely do that in both cases.
Do you mean also adding this line somewhere in ASTUnit.cpp?


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D35894



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41365: [clang] Add BeforeExecute method to PrecompiledPreamble

2017-12-18 Thread William Enright via Phabricator via cfe-commits
Nebiroth created this revision.
Nebiroth added reviewers: malaperle, ilya-biryukov.

Adds BeforeExecute method to PrecompiledPreamble to be called before Execute(). 
This method can be overriden.


Repository:
  rC Clang

https://reviews.llvm.org/D41365

Files:
  include/clang/Frontend/PrecompiledPreamble.h
  lib/Frontend/PrecompiledPreamble.cpp


Index: lib/Frontend/PrecompiledPreamble.cpp
===
--- lib/Frontend/PrecompiledPreamble.cpp
+++ lib/Frontend/PrecompiledPreamble.cpp
@@ -328,6 +328,7 @@
   Clang->setSourceManager(
   new SourceManager(Diagnostics, Clang->getFileManager()));
 
+  Callbacks.BeforeExecute(*Clang);
   auto PreambleDepCollector = std::make_shared();
   Clang->addDependencyCollector(PreambleDepCollector);
 
@@ -704,6 +705,7 @@
   }
 }
 
+void PreambleCallbacks::BeforeExecute(CompilerInstance ) {}
 void PreambleCallbacks::AfterExecute(CompilerInstance ) {}
 void PreambleCallbacks::AfterPCHEmitted(ASTWriter ) {}
 void PreambleCallbacks::HandleTopLevelDecl(DeclGroupRef DG) {}
Index: include/clang/Frontend/PrecompiledPreamble.h
===
--- include/clang/Frontend/PrecompiledPreamble.h
+++ include/clang/Frontend/PrecompiledPreamble.h
@@ -244,6 +244,9 @@
 public:
   virtual ~PreambleCallbacks() = default;
 
+  /// Called before FrontendAction::Execute(). Can be used to assign a 
SourceManager
+  /// from a CompilerInstance.
+  virtual void BeforeExecute(CompilerInstance );
   /// Called after FrontendAction::Execute(), but before
   /// FrontendAction::EndSourceFile(). Can be used to transfer ownership of
   /// various CompilerInstance fields before they are destroyed.


Index: lib/Frontend/PrecompiledPreamble.cpp
===
--- lib/Frontend/PrecompiledPreamble.cpp
+++ lib/Frontend/PrecompiledPreamble.cpp
@@ -328,6 +328,7 @@
   Clang->setSourceManager(
   new SourceManager(Diagnostics, Clang->getFileManager()));
 
+  Callbacks.BeforeExecute(*Clang);
   auto PreambleDepCollector = std::make_shared();
   Clang->addDependencyCollector(PreambleDepCollector);
 
@@ -704,6 +705,7 @@
   }
 }
 
+void PreambleCallbacks::BeforeExecute(CompilerInstance ) {}
 void PreambleCallbacks::AfterExecute(CompilerInstance ) {}
 void PreambleCallbacks::AfterPCHEmitted(ASTWriter ) {}
 void PreambleCallbacks::HandleTopLevelDecl(DeclGroupRef DG) {}
Index: include/clang/Frontend/PrecompiledPreamble.h
===
--- include/clang/Frontend/PrecompiledPreamble.h
+++ include/clang/Frontend/PrecompiledPreamble.h
@@ -244,6 +244,9 @@
 public:
   virtual ~PreambleCallbacks() = default;
 
+  /// Called before FrontendAction::Execute(). Can be used to assign a SourceManager
+  /// from a CompilerInstance.
+  virtual void BeforeExecute(CompilerInstance );
   /// Called after FrontendAction::Execute(), but before
   /// FrontendAction::EndSourceFile(). Can be used to transfer ownership of
   /// various CompilerInstance fields before they are destroyed.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38639: [clangd] #include statements support for Open definition

2017-12-18 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 127386.
Nebiroth marked 14 inline comments as done.
Nebiroth added a comment.
Herald added a subscriber: mgrang.

  CppFilePreambleCallbacks no longer extends PPCallbacks
  CppFilePreambleCallbacks no longer needs SourceManager parameter
  Removed temporary vector TempPreambleIncludeLocations
  IncludeReferenceMap in ParsedAST no longer passed by reference
  Code handling includes outside of preambles is now separated in 
IncludeRefsCollector class
  Removed addLocation
  Changed isSameLine function name and now checks if searched location is in 
range instead of verifying the line
  Removed changes to findDefinitions interface


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D38639

Files:
  clangd/ClangdServer.cpp
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.h
  unittests/clangd/ClangdTests.cpp

Index: unittests/clangd/ClangdTests.cpp
===
--- unittests/clangd/ClangdTests.cpp
+++ unittests/clangd/ClangdTests.cpp
@@ -7,7 +7,6 @@
 //
 //===--===//
 
-#include "ClangdLSPServer.h"
 #include "ClangdServer.h"
 #include "Context.h"
 #include "TestFS.h"
@@ -751,6 +750,75 @@
   EXPECT_FALSE(PathResult.hasValue());
 }
 
+TEST_F(ClangdVFSTest, CheckDefinitionIncludes) {
+  MockFSProvider FS;
+  ErrorCheckingDiagConsumer DiagConsumer;
+  MockCompilationDatabase CDB;
+
+  ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(),
+  /*StorePreamblesInMemory=*/true,
+  EmptyLogger::getInstance());
+
+  auto FooCpp = getVirtualTestFilePath("foo.cpp");
+  const auto SourceContents = R"cpp(
+  #include "foo.h"
+  #include "invalid.h"
+  int b = a;
+  // test
+  int foo;
+  #include "foo.h"
+  )cpp";
+  FS.Files[FooCpp] = SourceContents;
+  auto FooH = getVirtualTestFilePath("foo.h");
+  const auto HeaderContents = "int a;";
+
+  FS.Files[FooCpp] = SourceContents;
+  FS.Files[FooH] = HeaderContents;
+
+  Server.addDocument(FooH, HeaderContents);
+  Server.addDocument(FooCpp, SourceContents);
+
+  Position P = Position{1, 11};
+
+  auto ExpectedLocations = Server.findDefinitions(FooCpp, P);
+  ASSERT_TRUE(!!ExpectedLocations);
+  std::vector Locations = ExpectedLocations->Value;
+  EXPECT_TRUE(!Locations.empty());
+  std::string s("file:///");
+  std::string check = Locations[0].uri.uri;
+  check = check.erase(0, s.size() - 1);
+  check = check.substr(0, check.size());
+  ASSERT_EQ(check, FooH);
+  ASSERT_EQ(Locations[0].range.start.line, 0);
+  ASSERT_EQ(Locations[0].range.start.character, 0);
+  ASSERT_EQ(Locations[0].range.end.line, 0);
+  ASSERT_EQ(Locations[0].range.end.character, 0);
+
+  // Test ctrl-clicking on the #include part on the statement
+  Position P2 = Position{1, 3};
+
+  ExpectedLocations = Server.findDefinitions(FooCpp, P2);
+  ASSERT_TRUE(!!ExpectedLocations);
+  Locations = ExpectedLocations->Value;
+  EXPECT_TRUE(!Locations.empty());
+
+  // Test invalid include
+  Position P3 = Position{2, 11};
+
+  ExpectedLocations = Server.findDefinitions(FooCpp, P3);
+  ASSERT_TRUE(!!ExpectedLocations);
+  Locations = ExpectedLocations->Value;
+  EXPECT_TRUE(Locations.empty());
+
+  // Test include outside of Preamble
+  Position P4  = Position{6, 5};
+
+  ExpectedLocations = Server.findDefinitions(FooCpp, P4);
+  ASSERT_TRUE(!!ExpectedLocations);
+  Locations = ExpectedLocations->Value;
+  EXPECT_TRUE(!Locations.empty());
+}
+
 TEST_F(ClangdThreadingTest, NoConcurrentDiagnostics) {
   class NoConcurrentAccessDiagConsumer : public DiagnosticsConsumer {
   public:
Index: clangd/Protocol.h
===
--- clangd/Protocol.h
+++ clangd/Protocol.h
@@ -108,6 +108,14 @@
 bool fromJSON(const json::Expr &, Range &);
 json::Expr toJSON(const Range &);
 
+class RangeHash {
+public:
+  std::size_t operator()(const Range ) const {
+return ((R.start.line & 0x18) << 3) | ((R.start.character & 0x18) << 1) |
+   ((R.end.line & 0x18) >> 1) | ((R.end.character & 0x18) >> 3);
+  }
+};
+
 struct Location {
   /// The text document's URI.
   URI uri;
Index: clangd/ClangdUnit.h
===
--- clangd/ClangdUnit.h
+++ clangd/ClangdUnit.h
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 
 namespace llvm {
 class raw_ostream;
@@ -58,17 +59,22 @@
   std::vector Diags;
 };
 
+using IncludeReferenceMap = std::unordered_map;
+
 /// Stores and provides access to parsed AST.
 class ParsedAST {
 public:
   /// Attempts to run Clang and store parsed AST. If \p Preamble is non-null
   /// it is reused during parsing.
   static llvm::Optional
-  Build(const Context , std::unique_ptr CI,
-std::shared_ptr Preamble,
-std::unique_ptr Buffer,
-std::shared_ptr PCHs,
-IntrusiveRefCntPtr VFS);
+  Build(const Context ,
+   

[PATCH] D38639: [clangd] #include statements support for Open definition

2017-12-15 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 127161.
Nebiroth marked 27 inline comments as done.
Nebiroth added a comment.

inner class IncludeReferenceMap replaced by one map
fillRangeVector() and findPreambleIncludes() code moved into wrapper class
Open definition now returns an empty Range struct (line, character = 0)
Fixed unit tests
Minor code improvements


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D38639

Files:
  clangd/ClangdServer.cpp
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.h
  unittests/clangd/ClangdTests.cpp

Index: unittests/clangd/ClangdTests.cpp
===
--- unittests/clangd/ClangdTests.cpp
+++ unittests/clangd/ClangdTests.cpp
@@ -7,7 +7,6 @@
 //
 //===--===//
 
-#include "ClangdLSPServer.h"
 #include "ClangdServer.h"
 #include "Logger.h"
 #include "TestFS.h"
@@ -749,6 +748,75 @@
   EXPECT_FALSE(PathResult.hasValue());
 }
 
+TEST_F(ClangdVFSTest, CheckDefinitionIncludes) {
+  MockFSProvider FS;
+  ErrorCheckingDiagConsumer DiagConsumer;
+  MockCompilationDatabase CDB;
+
+  ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(),
+  /*StorePreamblesInMemory=*/true,
+  EmptyLogger::getInstance());
+
+  auto FooCpp = getVirtualTestFilePath("foo.cpp");
+  const auto SourceContents = R"cpp(
+  #include "foo.h"
+  #include "invalid.h"
+  int b = a;
+  // test
+  int foo;
+  #include "foo.h"
+  )cpp";
+  FS.Files[FooCpp] = SourceContents;
+  auto FooH = getVirtualTestFilePath("foo.h");
+  const auto HeaderContents = "int a;";
+
+  FS.Files[FooCpp] = SourceContents;
+  FS.Files[FooH] = HeaderContents;
+
+  Server.addDocument(FooH, HeaderContents);
+  Server.addDocument(FooCpp, SourceContents);
+
+  Position P = Position{1, 11};
+
+  auto ExpectedLocations = Server.findDefinitions(FooCpp, P);
+  ASSERT_TRUE(!!ExpectedLocations);
+  std::vector Locations = ExpectedLocations->Value;
+  EXPECT_TRUE(!Locations.empty());
+  std::string s("file:///");
+  std::string check = Locations[0].uri.uri;
+  check = check.erase(0, s.size() - 1);
+  check = check.substr(0, check.size());
+  ASSERT_EQ(check, FooH);
+  ASSERT_EQ(Locations[0].range.start.line, 0);
+  ASSERT_EQ(Locations[0].range.start.character, 0);
+  ASSERT_EQ(Locations[0].range.end.line, 0);
+  ASSERT_EQ(Locations[0].range.end.character, 0);
+
+  // Test ctrl-clicking on the #include part on the statement
+  Position P2 = Position{1, 3};
+
+  ExpectedLocations = Server.findDefinitions(FooCpp, P2);
+  ASSERT_TRUE(!!ExpectedLocations);
+  Locations = ExpectedLocations->Value;
+  EXPECT_TRUE(!Locations.empty());
+
+  // Test invalid include
+  Position P3 = Position{2, 11};
+
+  ExpectedLocations = Server.findDefinitions(FooCpp, P3);
+  ASSERT_TRUE(!!ExpectedLocations);
+  Locations = ExpectedLocations->Value;
+  EXPECT_TRUE(Locations.empty());
+
+  // Test include outside of Preamble
+  Position P4  = Position{6, 5};
+
+  ExpectedLocations = Server.findDefinitions(FooCpp, P4);
+  ASSERT_TRUE(!!ExpectedLocations);
+  Locations = ExpectedLocations->Value;
+  EXPECT_TRUE(!Locations.empty());
+}
+
 TEST_F(ClangdThreadingTest, NoConcurrentDiagnostics) {
   class NoConcurrentAccessDiagConsumer : public DiagnosticsConsumer {
   public:
Index: clangd/Protocol.h
===
--- clangd/Protocol.h
+++ clangd/Protocol.h
@@ -108,6 +108,14 @@
 bool fromJSON(const json::Expr &, Range &);
 json::Expr toJSON(const Range &);
 
+class RangeHash {
+public:
+  std::size_t operator()(const Range ) const {
+return ((R.start.line & 0x18) << 3) | ((R.start.character & 0x18) << 1) |
+   ((R.end.line & 0x18) >> 1) | ((R.end.character & 0x18) >> 3);
+  }
+};
+
 struct Location {
   /// The text document's URI.
   URI uri;
Index: clangd/ClangdUnit.h
===
--- clangd/ClangdUnit.h
+++ clangd/ClangdUnit.h
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 namespace llvm {
 class raw_ostream;
@@ -59,6 +60,8 @@
   std::vector Diags;
 };
 
+using IncludeReferenceMap = std::unordered_map;
+
 /// Stores and provides access to parsed AST.
 class ParsedAST {
 public:
@@ -69,7 +72,8 @@
 std::shared_ptr Preamble,
 std::unique_ptr Buffer,
 std::shared_ptr PCHs,
-IntrusiveRefCntPtr VFS, clangd::Logger );
+IntrusiveRefCntPtr VFS, clangd::Logger ,
+IncludeReferenceMap );
 
   ParsedAST(ParsedAST &);
   ParsedAST =(ParsedAST &);
@@ -89,12 +93,14 @@
 
   const std::vector () const;
 
+  IncludeReferenceMap () { return IRM; };
+
 private:
   ParsedAST(std::shared_ptr Preamble,
 std::unique_ptr Clang,
 std::unique_ptr Action,
 std::vector TopLevelDecls,
-std::vector Diags);
+std::vector Diags, IncludeReferenceMap IRM);
 
 private:
   void 

[PATCH] D35894: [clangd] Code hover for Clangd

2017-12-15 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 127131.
Nebiroth added a comment.

Rebase on master


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D35894

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/hover.test
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -31,6 +31,7 @@
 # CHECK-NEXT:  "clangd.applyFix"
 # CHECK-NEXT:]
 # CHECK-NEXT:  },
+# CHECK-NEXT:	   "hoverProvider": true,
 # CHECK-NEXT:  "renameProvider": true,
 # CHECK-NEXT:  "signatureHelpProvider": {
 # CHECK-NEXT:"triggerCharacters": [
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -31,6 +31,7 @@
 # CHECK-NEXT:  "clangd.applyFix"
 # CHECK-NEXT:]
 # CHECK-NEXT:  },
+# CHECK-NEXT:	   "hoverProvider": true,
 # CHECK-NEXT:  "renameProvider": true,
 # CHECK-NEXT:  "signatureHelpProvider": {
 # CHECK-NEXT:"triggerCharacters": [
Index: test/clangd/hover.test
===
--- /dev/null
+++ test/clangd/hover.test
@@ -0,0 +1,56 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 611
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#define MACRO 1\nnamespace ns1 {\nint test = 5;\nstruct MyClass {\nint xasd;\nvoid anotherOperation() {\n}\nstatic int foo(MyClass*) {\nreturn 0;\n}\n\n};}\n//comments test\ntemplate\nT templateTest(T foo) {\nreturn foo;}\ntemplate\nclass classTemplateTest {\npublic: T test;};\nint main() {\nint a;\na;\nint b = ns1::test;\nns1::MyClass* Params;\nParams->anotherOperation();\nMACRO;\nint temp = 5;\ntemplateTest(temp);classTemplateTest test;}\n"}}}
+
+Content-Length: 144
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":0,"character":12}}}
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"#define MACRO 1"}],"range":{"end":{"character":15,"line":0},"start":{"character":8,"line":0
+
+Content-Length: 144
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":21,"character":1}}}
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"int a"}],"range":{"end":{"character":5,"line":20},"start":{"character":0,"line":20
+
+Content-Length: 145
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":22,"character":15}}}
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"In ns1"},{"language":"C++","value":"int test = 5"}],"range":{"end":{"character":12,"line":2},"start":{"character":0,"line":2
+
+Content-Length: 145
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":23,"character":10}}}
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"In ns1"},{"language":"C++","value":"struct MyClass {"}],"range":{"end":{"character":16,"line":3},"start":{"character":0,"line":3
+
+Content-Length: 145
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":24,"character":13}}}
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"In ns1::MyClass"},{"language":"C++","value":"void anotherOperation() {"}],"range":{"end":{"character":25,"line":5},"start":{"character":0,"line":5
+
+Content-Length: 144
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":25,"character":1}}}
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"#define MACRO 1"}],"range":{"end":{"character":15,"line":0},"start":{"character":8,"line":0
+
+Content-Length: 144
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":26,"character":8}}}
+# CHECK: 

[PATCH] D39375: [clang] Add PPCallbacks list to preprocessor when building a preacompiled preamble.

2017-12-14 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 126984.
Nebiroth marked an inline comment as done.
Nebiroth added a comment.

Minor code cleanup


Repository:
  rC Clang

https://reviews.llvm.org/D39375

Files:
  include/clang/Frontend/PrecompiledPreamble.h
  lib/Frontend/PrecompiledPreamble.cpp


Index: lib/Frontend/PrecompiledPreamble.cpp
===
--- lib/Frontend/PrecompiledPreamble.cpp
+++ lib/Frontend/PrecompiledPreamble.cpp
@@ -351,6 +351,10 @@
   if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0]))
 return BuildPreambleError::BeginSourceFileFailed;
 
+  std::unique_ptr DelegatedPPCallbacks = 
Callbacks.createPPCallbacks();
+
+  if (DelegatedPPCallbacks)
+Clang->getPreprocessor().addPPCallbacks(std::move(DelegatedPPCallbacks));
   Act->Execute();
 
   // Run the callbacks.
@@ -709,6 +713,7 @@
 void PreambleCallbacks::HandleTopLevelDecl(DeclGroupRef DG) {}
 void PreambleCallbacks::HandleMacroDefined(const Token ,
const MacroDirective *MD) {}
+std::unique_ptr PreambleCallbacks::createPPCallbacks() {return 
nullptr;}
 
 std::error_code clang::make_error_code(BuildPreambleError Error) {
   return std::error_code(static_cast(Error), 
BuildPreambleErrorCategory());
Index: include/clang/Frontend/PrecompiledPreamble.h
===
--- include/clang/Frontend/PrecompiledPreamble.h
+++ include/clang/Frontend/PrecompiledPreamble.h
@@ -260,6 +260,9 @@
   /// used instead, but having only this method allows a simpler API.
   virtual void HandleMacroDefined(const Token ,
   const MacroDirective *MD);
+  /// Creates wrapper class for PPCallbacks so we can also process information
+  /// about includes that are inside of a preamble
+  virtual std::unique_ptr createPPCallbacks();
 };
 
 enum class BuildPreambleError {


Index: lib/Frontend/PrecompiledPreamble.cpp
===
--- lib/Frontend/PrecompiledPreamble.cpp
+++ lib/Frontend/PrecompiledPreamble.cpp
@@ -351,6 +351,10 @@
   if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0]))
 return BuildPreambleError::BeginSourceFileFailed;
 
+  std::unique_ptr DelegatedPPCallbacks = Callbacks.createPPCallbacks();
+
+  if (DelegatedPPCallbacks)
+Clang->getPreprocessor().addPPCallbacks(std::move(DelegatedPPCallbacks));
   Act->Execute();
 
   // Run the callbacks.
@@ -709,6 +713,7 @@
 void PreambleCallbacks::HandleTopLevelDecl(DeclGroupRef DG) {}
 void PreambleCallbacks::HandleMacroDefined(const Token ,
const MacroDirective *MD) {}
+std::unique_ptr PreambleCallbacks::createPPCallbacks() {return nullptr;}
 
 std::error_code clang::make_error_code(BuildPreambleError Error) {
   return std::error_code(static_cast(Error), BuildPreambleErrorCategory());
Index: include/clang/Frontend/PrecompiledPreamble.h
===
--- include/clang/Frontend/PrecompiledPreamble.h
+++ include/clang/Frontend/PrecompiledPreamble.h
@@ -260,6 +260,9 @@
   /// used instead, but having only this method allows a simpler API.
   virtual void HandleMacroDefined(const Token ,
   const MacroDirective *MD);
+  /// Creates wrapper class for PPCallbacks so we can also process information
+  /// about includes that are inside of a preamble
+  virtual std::unique_ptr createPPCallbacks();
 };
 
 enum class BuildPreambleError {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39571: [clangd] DidChangeConfiguration Notification

2017-12-14 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 126980.
Nebiroth marked 5 inline comments as done.
Nebiroth added a comment.

Removed test file
Added mutex lock when changing CDB
Minor code cleanup


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D39571

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/DraftStore.cpp
  clangd/DraftStore.h
  clangd/GlobalCompilationDatabase.cpp
  clangd/GlobalCompilationDatabase.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -18,9 +18,10 @@
 # CHECK-NEXT:  ":"
 # CHECK-NEXT:]
 # CHECK-NEXT:  },
+# CHECK-NEXT:  "configurationChangeProvider": true,
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
-# CHECK-NEXT:  "documentHighlightProvider": true,
+# CHECK-NEXT:	   "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
@@ -49,4 +50,4 @@
 # CHECK-NEXT:  "result": null
 Content-Length: 33
 
-{"jsonrpc":"2.0":"method":"exit"}
+{"jsonrpc":"2.0":"method":"exit"}
\ No newline at end of file
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -18,9 +18,10 @@
 # CHECK-NEXT:  ":"
 # CHECK-NEXT:]
 # CHECK-NEXT:  },
+# CHECK-NEXT:  "configurationChangeProvider": true,
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
-# CHECK-NEXT:  "documentHighlightProvider": true,
+# CHECK-NEXT:	   "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: clangd/ProtocolHandlers.h
===
--- clangd/ProtocolHandlers.h
+++ clangd/ProtocolHandlers.h
@@ -57,6 +57,8 @@
   virtual void onRename(Ctx C, RenameParams ) = 0;
   virtual void onDocumentHighlight(Ctx C,
TextDocumentPositionParams ) = 0;
+  virtual void onChangeConfiguration(Ctx C,
+ DidChangeConfigurationParams ) = 0;
 };
 
 void registerCallbackHandlers(JSONRPCDispatcher , JSONOutput ,
Index: clangd/ProtocolHandlers.cpp
===
--- clangd/ProtocolHandlers.cpp
+++ clangd/ProtocolHandlers.cpp
@@ -73,4 +73,6 @@
   Register("workspace/executeCommand", ::onCommand);
   Register("textDocument/documentHighlight",
::onDocumentHighlight);
+  Register("workspace/didChangeConfiguration",
+   ::onChangeConfiguration);
 }
Index: clangd/Protocol.h
===
--- clangd/Protocol.h
+++ clangd/Protocol.h
@@ -257,6 +257,24 @@
 };
 bool fromJSON(const json::Expr &, DidChangeWatchedFilesParams &);
 
+/// Clangd extension to manage a workspace/didChangeConfiguration notification
+/// since the data received is described as 'any' type in LSP.
+struct ClangdConfigurationParamsChange {
+  llvm::Optional compilationDatabasePath;
+};
+bool fromJSON(const json::Expr &, ClangdConfigurationParamsChange &);
+
+struct DidChangeConfigurationParams {
+  DidChangeConfigurationParams() = default;
+  DidChangeConfigurationParams(ClangdConfigurationParamsChange settings): settings(settings) {}
+
+  // We use this predefined struct because it is easier to use
+  // than the protocol specified type of 'any'.
+  ClangdConfigurationParamsChange settings;
+};
+bool fromJSON(const json::Expr &, DidChangeConfigurationParams &);
+json::Expr toJSON(const DidChangeConfigurationParams &);
+
 struct FormattingOptions {
   /// Size of a tab in spaces.
   int tabSize;
Index: clangd/Protocol.cpp
===
--- clangd/Protocol.cpp
+++ clangd/Protocol.cpp
@@ -366,5 +366,21 @@
   };
 }
 
+bool fromJSON(const json::Expr , DidChangeConfigurationParams ) {
+  json::ObjectMapper O(Params);
+  return O && O.map("settings", CCP.settings);
+}
+
+json::Expr toJSON(const DidChangeConfigurationParams ) {
+  return json::obj{
+{"settings", CCP.settings},
+  };
+}
+
+bool fromJSON(const json::Expr , ClangdConfigurationParamsChange ) {
+  json::ObjectMapper O(Params);
+  return O && O.map("compilationDatabasePath", CCPC.compilationDatabasePath);
+}
+
 } // namespace clangd
 } // namespace 

[PATCH] D39571: [clangd] DidChangeConfiguration Notification

2017-12-11 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 126449.
Nebiroth added a comment.

Removed some more empty lines


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D39571

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/DraftStore.cpp
  clangd/DraftStore.h
  clangd/GlobalCompilationDatabase.cpp
  clangd/GlobalCompilationDatabase.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/did-change-configuration.test
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -18,6 +18,7 @@
 # CHECK-NEXT:  ":"
 # CHECK-NEXT:]
 # CHECK-NEXT:  },
+# CHECK-NEXT:  "configurationChangeProvider": true,
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -18,6 +18,7 @@
 # CHECK-NEXT:  ":"
 # CHECK-NEXT:]
 # CHECK-NEXT:  },
+# CHECK-NEXT:  "configurationChangeProvider": true,
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
Index: test/clangd/did-change-configuration.test
===
--- /dev/null
+++ test/clangd/did-change-configuration.test
@@ -0,0 +1,46 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 150
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///foo.c","languageId":"c","version":1,"text":"voidmain(){}"}}}
+
+Content-Length: 86
+
+{"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":""}}
+#Failed to decode workspace/didChangeConfiguration request.
+#Incorrect mapping node
+
+Content-Length: 114
+
+{"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{"compilationDatabasePath":{
+#Failed to decode workspace/didChangeConfiguration request.
+#compilationDatabasePath is not a scalar node
+
+Content-Length: 140
+
+{"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{"compilationDatabasePath":"/","testBadValue":"foo1234"}}}
+#Ignored unknown field "testBadValue"
+#Failed to find compilation database for / in overriden directory /
+#Bad field, bad compilation database
+
+Content-Length: 722
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///compile_commands.json","languageId":"json","version":1,"text":"[\n{\n"directory":"/",\n"command":"/usr/bin/c++-DGTEST_HAS_RTTI=0-D_GNU_SOURCE-D__STDC_CONSTANT_MACROS-D__STDC_FORMAT_MACROS-D__STDC_LIMIT_MACROS-Ilib/Demangle-I../lib/Demangle-I/usr/include/libxml2-Iinclude-I../include-fPIC-fvisibility-inlines-hidden-Werror=date-time-std=c++11-Wall-W-Wno-unused-parameter-Wwrite-strings-Wcast-qual-Wno-missing-field-initializers-pedantic-Wno-long-long-Wno-maybe-uninitialized-Wdelete-non-virtual-dtor-Wno-comment-O0-g-fno-exceptions-fno-rtti-o/foo.c.o-c/foo.c",\n"file":"/foo.c"\n},"}}}
+
+Content-Length: 115
+
+{"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{"compilationDatabasePath":"/"}}}
+#CHECK:{"jsonrpc":"2.0","method":"textDocument/publishDiagnostics","params":{"diagnostics":[{"message":"type specifier missing, defaults to 'int'","range":{"end":{"character":1,"line":0},"start":{"character":1,"line":0}},"severity":2},{"message":"control reaches end of non-void function","range":{"end":{"character":12,"line":0},"start":{"character":12,"line":0}},"severity":2}],"uri":"file:///foo.c"}}
+
+Content-Length: 48
+
+{"jsonrpc":"2.0","id":1,"method":"shutdown"}
+
+Content-Length: 33
+
+{"jsonrpc":"2.0":"method":"exit"}
Index: clangd/ProtocolHandlers.h
===
--- clangd/ProtocolHandlers.h
+++ clangd/ProtocolHandlers.h
@@ -54,6 +54,8 @@
   virtual void onFileEvent(Ctx C, DidChangeWatchedFilesParams ) = 0;
   virtual void onCommand(Ctx C, ExecuteCommandParams ) = 0;
   virtual void onRename(Ctx C, RenameParams ) = 0;
+  virtual void onChangeConfiguration(Ctx C,
+ DidChangeConfigurationParams ) = 0;
 };
 
 void registerCallbackHandlers(JSONRPCDispatcher , JSONOutput ,

[PATCH] D39571: [clangd] DidChangeConfiguration Notification

2017-12-11 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 126447.
Nebiroth added a comment.
Herald added a subscriber: klimek.

Merged with latest llvm + clang
Minor code cleanup


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D39571

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/DraftStore.cpp
  clangd/DraftStore.h
  clangd/GlobalCompilationDatabase.cpp
  clangd/GlobalCompilationDatabase.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/did-change-configuration.test
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -18,6 +18,7 @@
 # CHECK-NEXT:  ":"
 # CHECK-NEXT:]
 # CHECK-NEXT:  },
+# CHECK-NEXT:  "configurationChangeProvider": true,
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -18,6 +18,7 @@
 # CHECK-NEXT:  ":"
 # CHECK-NEXT:]
 # CHECK-NEXT:  },
+# CHECK-NEXT:  "configurationChangeProvider": true,
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
Index: test/clangd/did-change-configuration.test
===
--- /dev/null
+++ test/clangd/did-change-configuration.test
@@ -0,0 +1,46 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 150
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///foo.c","languageId":"c","version":1,"text":"voidmain(){}"}}}
+
+Content-Length: 86
+
+{"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":""}}
+#Failed to decode workspace/didChangeConfiguration request.
+#Incorrect mapping node
+
+Content-Length: 114
+
+{"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{"compilationDatabasePath":{
+#Failed to decode workspace/didChangeConfiguration request.
+#compilationDatabasePath is not a scalar node
+
+Content-Length: 140
+
+{"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{"compilationDatabasePath":"/","testBadValue":"foo1234"}}}
+#Ignored unknown field "testBadValue"
+#Failed to find compilation database for / in overriden directory /
+#Bad field, bad compilation database
+
+Content-Length: 722
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///compile_commands.json","languageId":"json","version":1,"text":"[\n{\n"directory":"/",\n"command":"/usr/bin/c++-DGTEST_HAS_RTTI=0-D_GNU_SOURCE-D__STDC_CONSTANT_MACROS-D__STDC_FORMAT_MACROS-D__STDC_LIMIT_MACROS-Ilib/Demangle-I../lib/Demangle-I/usr/include/libxml2-Iinclude-I../include-fPIC-fvisibility-inlines-hidden-Werror=date-time-std=c++11-Wall-W-Wno-unused-parameter-Wwrite-strings-Wcast-qual-Wno-missing-field-initializers-pedantic-Wno-long-long-Wno-maybe-uninitialized-Wdelete-non-virtual-dtor-Wno-comment-O0-g-fno-exceptions-fno-rtti-o/foo.c.o-c/foo.c",\n"file":"/foo.c"\n},"}}}
+
+Content-Length: 115
+
+{"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{"compilationDatabasePath":"/"}}}
+#CHECK:{"jsonrpc":"2.0","method":"textDocument/publishDiagnostics","params":{"diagnostics":[{"message":"type specifier missing, defaults to 'int'","range":{"end":{"character":1,"line":0},"start":{"character":1,"line":0}},"severity":2},{"message":"control reaches end of non-void function","range":{"end":{"character":12,"line":0},"start":{"character":12,"line":0}},"severity":2}],"uri":"file:///foo.c"}}
+
+Content-Length: 48
+
+{"jsonrpc":"2.0","id":1,"method":"shutdown"}
+
+Content-Length: 33
+
+{"jsonrpc":"2.0":"method":"exit"}
Index: clangd/ProtocolHandlers.h
===
--- clangd/ProtocolHandlers.h
+++ clangd/ProtocolHandlers.h
@@ -54,6 +54,8 @@
   virtual void onFileEvent(Ctx C, DidChangeWatchedFilesParams ) = 0;
   virtual void onCommand(Ctx C, ExecuteCommandParams ) = 0;
   virtual void onRename(Ctx C, RenameParams ) = 0;
+  virtual void onChangeConfiguration(Ctx C,
+ DidChangeConfigurationParams ) = 0;
 };
 
 void 

[PATCH] D39375: [clang] Add PPCallbacks list to preprocessor when building a preacompiled preamble.

2017-12-11 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 126430.
Nebiroth added a comment.

Removed unique_ptr parameter in PrecompiledPreamble::Build
Added method createPPCallbacks() in PreambleCallback to be overriden


Repository:
  rC Clang

https://reviews.llvm.org/D39375

Files:
  include/clang/Frontend/PrecompiledPreamble.h
  lib/Frontend/PrecompiledPreamble.cpp


Index: lib/Frontend/PrecompiledPreamble.cpp
===
--- lib/Frontend/PrecompiledPreamble.cpp
+++ lib/Frontend/PrecompiledPreamble.cpp
@@ -351,6 +351,8 @@
   if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0]))
 return BuildPreambleError::BeginSourceFileFailed;
 
+  if (Callbacks.createPPCallbacks())
+
Clang->getPreprocessor().addPPCallbacks(std::move(Callbacks.createPPCallbacks()));
   Act->Execute();
 
   // Run the callbacks.
@@ -709,6 +711,7 @@
 void PreambleCallbacks::HandleTopLevelDecl(DeclGroupRef DG) {}
 void PreambleCallbacks::HandleMacroDefined(const Token ,
const MacroDirective *MD) {}
+std::unique_ptr PreambleCallbacks::createPPCallbacks() {return 
nullptr;}
 
 std::error_code clang::make_error_code(BuildPreambleError Error) {
   return std::error_code(static_cast(Error), 
BuildPreambleErrorCategory());
Index: include/clang/Frontend/PrecompiledPreamble.h
===
--- include/clang/Frontend/PrecompiledPreamble.h
+++ include/clang/Frontend/PrecompiledPreamble.h
@@ -260,6 +260,9 @@
   /// used instead, but having only this method allows a simpler API.
   virtual void HandleMacroDefined(const Token ,
   const MacroDirective *MD);
+  /// Adds list of Preprocessor callbacks so we can also process information
+  /// about includes that are outside of a preamble i.e in the middle of a file
+  virtual std::unique_ptr createPPCallbacks();
 };
 
 enum class BuildPreambleError {


Index: lib/Frontend/PrecompiledPreamble.cpp
===
--- lib/Frontend/PrecompiledPreamble.cpp
+++ lib/Frontend/PrecompiledPreamble.cpp
@@ -351,6 +351,8 @@
   if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0]))
 return BuildPreambleError::BeginSourceFileFailed;
 
+  if (Callbacks.createPPCallbacks())
+Clang->getPreprocessor().addPPCallbacks(std::move(Callbacks.createPPCallbacks()));
   Act->Execute();
 
   // Run the callbacks.
@@ -709,6 +711,7 @@
 void PreambleCallbacks::HandleTopLevelDecl(DeclGroupRef DG) {}
 void PreambleCallbacks::HandleMacroDefined(const Token ,
const MacroDirective *MD) {}
+std::unique_ptr PreambleCallbacks::createPPCallbacks() {return nullptr;}
 
 std::error_code clang::make_error_code(BuildPreambleError Error) {
   return std::error_code(static_cast(Error), BuildPreambleErrorCategory());
Index: include/clang/Frontend/PrecompiledPreamble.h
===
--- include/clang/Frontend/PrecompiledPreamble.h
+++ include/clang/Frontend/PrecompiledPreamble.h
@@ -260,6 +260,9 @@
   /// used instead, but having only this method allows a simpler API.
   virtual void HandleMacroDefined(const Token ,
   const MacroDirective *MD);
+  /// Adds list of Preprocessor callbacks so we can also process information
+  /// about includes that are outside of a preamble i.e in the middle of a file
+  virtual std::unique_ptr createPPCallbacks();
 };
 
 enum class BuildPreambleError {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38639: [clangd] #include statements support for Open definition

2017-12-11 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 126429.
Nebiroth added a comment.

  Creating unique_ptr for wrapper class now uses overriden method 
createPPCallbacks() from PrecompiledPreamble class
  Moved wrapper class to inline inside createPPCallbacks()
  Wrapper class now uses CppFilePreambleCallbacks as field


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D38639

Files:
  clangd/ClangdServer.cpp
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.h
  unittests/clangd/ClangdTests.cpp

Index: unittests/clangd/ClangdTests.cpp
===
--- unittests/clangd/ClangdTests.cpp
+++ unittests/clangd/ClangdTests.cpp
@@ -7,7 +7,6 @@
 //
 //===--===//
 
-#include "ClangdLSPServer.h"
 #include "ClangdServer.h"
 #include "Logger.h"
 #include "TestFS.h"
@@ -620,7 +619,7 @@
 AddDocument(FileIndex);
 
   Position Pos{LineDist(RandGen), ColumnDist(RandGen)};
-  ASSERT_TRUE(!!Server.findDefinitions(FilePaths[FileIndex], Pos));
+  Server.findDefinitions(FilePaths[FileIndex], Pos);
 };
 
 std::vector> AsyncRequests = {
@@ -749,6 +748,58 @@
   EXPECT_FALSE(PathResult.hasValue());
 }
 
+TEST_F(ClangdVFSTest, CheckDefinitionIncludes) {
+  MockFSProvider FS;
+  ErrorCheckingDiagConsumer DiagConsumer;
+  MockCompilationDatabase CDB;
+
+  ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(),
+  /*StorePreamblesInMemory=*/true,
+  EmptyLogger::getInstance());
+
+  auto FooCpp = getVirtualTestFilePath("foo.cpp");
+  const auto SourceContents = R"cpp(
+  #include "foo.h"
+  #include "invalid.h"
+  int b = a;
+  )cpp";
+  FS.Files[FooCpp] = SourceContents;
+  auto FooH = getVirtualTestFilePath("foo.h");
+  const auto HeaderContents = "int a;";
+
+  FS.Files[FooCpp] = SourceContents;
+  FS.Files[FooH] = HeaderContents;
+
+  Server.addDocument(FooH, HeaderContents);
+  Server.addDocument(FooCpp, SourceContents);
+
+  Position P = Position{1, 11};
+
+  std::vector Locations = Server.findDefinitions(FooCpp, P).get().Value;
+  EXPECT_TRUE(!Locations.empty());
+  std::string s("file:///");
+  std::string check = Locations[0].uri.uri;
+  check = check.erase(0, s.size());
+  check = check.substr(0, check.size() - 1);
+  ASSERT_EQ(check, FooH);
+  ASSERT_EQ(Locations[0].range.start.line, 0);
+  ASSERT_EQ(Locations[0].range.start.character, 0);
+  ASSERT_EQ(Locations[0].range.end.line, 0);
+  ASSERT_EQ(Locations[0].range.end.character, 0);
+
+  // Test ctrl-clicking on the #include part on the statement
+  Position P3 = Position{1, 3};
+
+  Locations = Server.findDefinitions(FooCpp, P3).get().Value;
+  EXPECT_TRUE(!Locations.empty());
+
+  // Test invalid include
+  Position P2 = Position{2, 11};
+
+  Locations = Server.findDefinitions(FooCpp, P2).get().Value;
+  EXPECT_TRUE(Locations.empty());
+}
+
 TEST_F(ClangdThreadingTest, NoConcurrentDiagnostics) {
   class NoConcurrentAccessDiagConsumer : public DiagnosticsConsumer {
   public:
Index: clangd/Protocol.h
===
--- clangd/Protocol.h
+++ clangd/Protocol.h
@@ -108,6 +108,14 @@
 bool fromJSON(const json::Expr &, Range &);
 json::Expr toJSON(const Range &);
 
+class RangeHash {
+public:
+  std::size_t operator()(const Range ) const {
+return ((R.start.line & 0x18) << 3) | ((R.start.character & 0x18) << 1) |
+   ((R.end.line & 0x18) >> 1) | ((R.end.character & 0x18) >> 3);
+  }
+};
+
 struct Location {
   /// The text document's URI.
   URI uri;
Index: clangd/ClangdUnit.h
===
--- clangd/ClangdUnit.h
+++ clangd/ClangdUnit.h
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 namespace llvm {
 class raw_ostream;
@@ -59,6 +60,15 @@
   std::vector Diags;
 };
 
+class IncludeReferenceMap {
+  llvm::Optional findIncludeTargetAtLoc(Location Loc);
+
+public:
+  std::unordered_map IncludeLocationMap;
+  std::vector> DataVector;
+  std::vector RangeVector;
+};
+
 /// Stores and provides access to parsed AST.
 class ParsedAST {
 public:
@@ -69,7 +79,8 @@
 std::shared_ptr Preamble,
 std::unique_ptr Buffer,
 std::shared_ptr PCHs,
-IntrusiveRefCntPtr VFS, clangd::Logger );
+IntrusiveRefCntPtr VFS, clangd::Logger ,
+IncludeReferenceMap IRM);
 
   ParsedAST(ParsedAST &);
   ParsedAST =(ParsedAST &);
@@ -89,12 +100,14 @@
 
   const std::vector () const;
 
+  IncludeReferenceMap takeIRM() { return IRM; };
+
 private:
   ParsedAST(std::shared_ptr Preamble,
 std::unique_ptr Clang,
 std::unique_ptr Action,
 std::vector TopLevelDecls,
-std::vector Diags);
+std::vector Diags, IncludeReferenceMap IRM);
 
 private:
   void ensurePreambleDeclsDeserialized();
@@ -114,6 +127,8 @@
   

[PATCH] D38425: [clangd] Document highlights for clangd

2017-12-11 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 126371.
Nebiroth marked 3 inline comments as done.
Nebiroth added a comment.
Herald added a subscriber: mgrang.

Merged with latest llvm/clang
Minor code cleanup


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D38425

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/documenthighlight.test
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:  "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:  "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: test/clangd/documenthighlight.test
===
--- /dev/null
+++ test/clangd/documenthighlight.test
@@ -0,0 +1,42 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 479
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#define MACRO 1\nnamespace ns1 {\nstruct MyClass {\nint xasd;\nvoid anotherOperation() {\n}\nstatic int foo(MyClass*) {\nreturn 0;\n}\n\n};\nstruct Foo {\nint xasd;\n};\n}\nint main() {\nint bonjour;\nbonjour = 2;\nint test1 = bonjour;\nns1::Foo bar = { xasd : 1};\nbar.xasd = 3;\nns1::MyClass* Params;\nParams->anotherOperation();\n}\n"}}}
+
+Content-Length: 156
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":17,"character":2}}}
+# Verify local variable 
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":11,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}},{"kind":2,"range":{"end":{"character":19,"line":18},"start":{"character":12,"line":18}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":18,"character":17}}}
+# Verify struct highlight
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":11,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}},{"kind":2,"range":{"end":{"character":19,"line":18},"start":{"character":12,"line":18}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":21,"character":10}}}
+# Verify method highlight
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":14,"line":2},"start":{"character":7,"line":2}}},{"kind":1,"range":{"end":{"character":22,"line":6},"start":{"character":15,"line":6}}},{"kind":1,"range":{"end":{"character":12,"line":21},"start":{"character":5,"line":21}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":18,"character":14}}}
+# Verify Read-access of a symbol (kind = 2) 
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":11,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}},{"kind":2,"range":{"end":{"character":19,"line":18},"start":{"character":12,"line":18}}}]}
+
+Content-Length: 48
+
+{"jsonrpc":"2.0","id":1,"method":"shutdown"}
+
+Content-Length: 33
+
+{"jsonrpc":"2.0":"method":"exit"}
\ No newline at end of file
Index: 

[PATCH] D39375: [clang] Add PPCallbacks list to preprocessor when building a preacompiled preamble.

2017-12-08 Thread William Enright via Phabricator via cfe-commits
Nebiroth added inline comments.



Comment at: lib/Frontend/PrecompiledPreamble.cpp:242
 std::shared_ptr PCHContainerOps, bool 
StoreInMemory,
-PreambleCallbacks ) {
+PreambleCallbacks , std::unique_ptr PPCallbacks) {
   assert(VFS && "VFS is null");

ilya-biryukov wrote:
> Nebiroth wrote:
> > ilya-biryukov wrote:
> > > Could we add a method to `PreambleCallbacks` to create `PPCallbacks` 
> > > instead?
> > > Otherwise we have both `MacroDefined` in `PreambleCallbacks` and a 
> > > separate set of PPCallbacks, so we have two ways of doing the same thing.
> > > 
> > > ```
> > > class PreambleCallbacks {
> > > public:
> > > // ...
> > > 
> > >   /// Remove this.
> > >   virtual void HandleMacroDefined(...);
> > > 
> > >   // Add this instead.
> > >   virtual std::unique_ptr createPPCallbacks();
> > > 
> > > }
> > > ```
> > > 
> > > Alternatively, follow the current pattern in `PreambleCallbacks` and add 
> > > some extra functions from the `PPCallbacks` interface to it. This would 
> > > not require changes to the existing usages of `PrecompiledPreamble` in 
> > > `ASTUnit`. Albeit, I'd prefer the first option.
> > > ```
> > > class PreambleCallbacks {
> > > public:
> > > // ...
> > > 
> > >   // Keep this
> > >   virtual void HandleMacroDefined(...);
> > >   // Add the ones you need, e.g.
> > >   virtual void InclusionDirective(...);
> > >   virtual void FileChanged(...);
> > > };
> > > ```
> > If we were to do that, one would then be required to define a wrapper class 
> > for PPCallbacks and create an instance of it inside createPPCallbacks() for 
> > the purpose of creating a unique_ptr? Then that unique_ptr would be sent 
> > from within the PreambleCallbacks parameter in the Build function?
> We're already passing our own wrapper around `PreambleCallbacks` anyway (see 
> `PreambleMacroCallbacks`), we'll pass the `unique_ptr` instead.
> But, yes, the clients will have to write their own implementation of 
> `PPCallbacks` and pass it as `unique_ptr`. Is there something wrong with that?
> 
> Or, have I misunderstood the question entirely?
No this is fine. I was just making sure I understood correctly.


Repository:
  rC Clang

https://reviews.llvm.org/D39375



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39375: [clang] Add PPCallbacks list to preprocessor when building a preacompiled preamble.

2017-12-07 Thread William Enright via Phabricator via cfe-commits
Nebiroth added inline comments.



Comment at: lib/Frontend/PrecompiledPreamble.cpp:242
 std::shared_ptr PCHContainerOps, bool 
StoreInMemory,
-PreambleCallbacks ) {
+PreambleCallbacks , std::unique_ptr PPCallbacks) {
   assert(VFS && "VFS is null");

ilya-biryukov wrote:
> Could we add a method to `PreambleCallbacks` to create `PPCallbacks` instead?
> Otherwise we have both `MacroDefined` in `PreambleCallbacks` and a separate 
> set of PPCallbacks, so we have two ways of doing the same thing.
> 
> ```
> class PreambleCallbacks {
> public:
> // ...
> 
>   /// Remove this.
>   virtual void HandleMacroDefined(...);
> 
>   // Add this instead.
>   virtual std::unique_ptr createPPCallbacks();
> 
> }
> ```
> 
> Alternatively, follow the current pattern in `PreambleCallbacks` and add some 
> extra functions from the `PPCallbacks` interface to it. This would not 
> require changes to the existing usages of `PrecompiledPreamble` in `ASTUnit`. 
> Albeit, I'd prefer the first option.
> ```
> class PreambleCallbacks {
> public:
> // ...
> 
>   // Keep this
>   virtual void HandleMacroDefined(...);
>   // Add the ones you need, e.g.
>   virtual void InclusionDirective(...);
>   virtual void FileChanged(...);
> };
> ```
If we were to do that, one would then be required to define a wrapper class for 
PPCallbacks and create an instance of it inside createPPCallbacks() for the 
purpose of creating a unique_ptr? Then that unique_ptr would be sent from 
within the PreambleCallbacks parameter in the Build function?


Repository:
  rC Clang

https://reviews.llvm.org/D39375



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39375: [clang] Add PPCallbacks list to preprocessor when building a preacompiled preamble.

2017-12-06 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 125815.
Nebiroth added a comment.

Reverted formatting changes to ASTUnit


Repository:
  rC Clang

https://reviews.llvm.org/D39375

Files:
  include/clang/Frontend/PrecompiledPreamble.h
  lib/Frontend/ASTUnit.cpp
  lib/Frontend/PrecompiledPreamble.cpp


Index: lib/Frontend/PrecompiledPreamble.cpp
===
--- lib/Frontend/PrecompiledPreamble.cpp
+++ lib/Frontend/PrecompiledPreamble.cpp
@@ -239,7 +239,7 @@
 const llvm::MemoryBuffer *MainFileBuffer, PreambleBounds Bounds,
 DiagnosticsEngine , IntrusiveRefCntPtr VFS,
 std::shared_ptr PCHContainerOps, bool 
StoreInMemory,
-PreambleCallbacks ) {
+PreambleCallbacks , std::unique_ptr PPCallbacks) {
   assert(VFS && "VFS is null");
 
   if (!Bounds.Size)
@@ -351,6 +351,7 @@
   if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0]))
 return BuildPreambleError::BeginSourceFileFailed;
 
+  Clang->getPreprocessor().addPPCallbacks(std::move(PPCallbacks));
   Act->Execute();
 
   // Run the callbacks.
Index: lib/Frontend/ASTUnit.cpp
===
--- lib/Frontend/ASTUnit.cpp
+++ lib/Frontend/ASTUnit.cpp
@@ -1293,7 +1293,7 @@
 
 llvm::ErrorOr NewPreamble = 
PrecompiledPreamble::Build(
 PreambleInvocationIn, MainFileBuffer.get(), Bounds, *Diagnostics, VFS,
-PCHContainerOps, /*StoreInMemory=*/false, Callbacks);
+PCHContainerOps, /*StoreInMemory=*/false, Callbacks, nullptr);
 if (NewPreamble) {
   Preamble = std::move(*NewPreamble);
   PreambleRebuildCounter = 1;
Index: include/clang/Frontend/PrecompiledPreamble.h
===
--- include/clang/Frontend/PrecompiledPreamble.h
+++ include/clang/Frontend/PrecompiledPreamble.h
@@ -81,7 +81,7 @@
 const llvm::MemoryBuffer *MainFileBuffer, PreambleBounds Bounds,
 DiagnosticsEngine , IntrusiveRefCntPtr 
VFS,
 std::shared_ptr PCHContainerOps,
-bool StoreInMemory, PreambleCallbacks );
+bool StoreInMemory, PreambleCallbacks , 
std::unique_ptr PPCallbacks);
 
   PrecompiledPreamble(PrecompiledPreamble &&) = default;
   PrecompiledPreamble =(PrecompiledPreamble &&) = default;


Index: lib/Frontend/PrecompiledPreamble.cpp
===
--- lib/Frontend/PrecompiledPreamble.cpp
+++ lib/Frontend/PrecompiledPreamble.cpp
@@ -239,7 +239,7 @@
 const llvm::MemoryBuffer *MainFileBuffer, PreambleBounds Bounds,
 DiagnosticsEngine , IntrusiveRefCntPtr VFS,
 std::shared_ptr PCHContainerOps, bool StoreInMemory,
-PreambleCallbacks ) {
+PreambleCallbacks , std::unique_ptr PPCallbacks) {
   assert(VFS && "VFS is null");
 
   if (!Bounds.Size)
@@ -351,6 +351,7 @@
   if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0]))
 return BuildPreambleError::BeginSourceFileFailed;
 
+  Clang->getPreprocessor().addPPCallbacks(std::move(PPCallbacks));
   Act->Execute();
 
   // Run the callbacks.
Index: lib/Frontend/ASTUnit.cpp
===
--- lib/Frontend/ASTUnit.cpp
+++ lib/Frontend/ASTUnit.cpp
@@ -1293,7 +1293,7 @@
 
 llvm::ErrorOr NewPreamble = PrecompiledPreamble::Build(
 PreambleInvocationIn, MainFileBuffer.get(), Bounds, *Diagnostics, VFS,
-PCHContainerOps, /*StoreInMemory=*/false, Callbacks);
+PCHContainerOps, /*StoreInMemory=*/false, Callbacks, nullptr);
 if (NewPreamble) {
   Preamble = std::move(*NewPreamble);
   PreambleRebuildCounter = 1;
Index: include/clang/Frontend/PrecompiledPreamble.h
===
--- include/clang/Frontend/PrecompiledPreamble.h
+++ include/clang/Frontend/PrecompiledPreamble.h
@@ -81,7 +81,7 @@
 const llvm::MemoryBuffer *MainFileBuffer, PreambleBounds Bounds,
 DiagnosticsEngine , IntrusiveRefCntPtr VFS,
 std::shared_ptr PCHContainerOps,
-bool StoreInMemory, PreambleCallbacks );
+bool StoreInMemory, PreambleCallbacks , std::unique_ptr PPCallbacks);
 
   PrecompiledPreamble(PrecompiledPreamble &&) = default;
   PrecompiledPreamble =(PrecompiledPreamble &&) = default;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38639: [clangd] #include statements support for Open definition

2017-12-06 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 125814.
Nebiroth added a comment.

Fixed re-added include


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D38639

Files:
  clangd/ClangdServer.cpp
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.h
  unittests/clangd/ClangdTests.cpp

Index: unittests/clangd/ClangdTests.cpp
===
--- unittests/clangd/ClangdTests.cpp
+++ unittests/clangd/ClangdTests.cpp
@@ -7,7 +7,6 @@
 //
 //===--===//
 
-#include "ClangdLSPServer.h"
 #include "ClangdServer.h"
 #include "Logger.h"
 #include "TestFS.h"
@@ -620,7 +619,7 @@
 AddDocument(FileIndex);
 
   Position Pos{LineDist(RandGen), ColumnDist(RandGen)};
-  ASSERT_TRUE(!!Server.findDefinitions(FilePaths[FileIndex], Pos));
+  Server.findDefinitions(FilePaths[FileIndex], Pos);
 };
 
 std::vector> AsyncRequests = {
@@ -749,6 +748,58 @@
   EXPECT_FALSE(PathResult.hasValue());
 }
 
+TEST_F(ClangdVFSTest, CheckDefinitionIncludes) {
+  MockFSProvider FS;
+  ErrorCheckingDiagConsumer DiagConsumer;
+  MockCompilationDatabase CDB;
+
+  ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(),
+  /*StorePreamblesInMemory=*/true,
+  EmptyLogger::getInstance());
+
+  auto FooCpp = getVirtualTestFilePath("foo.cpp");
+  const auto SourceContents = R"cpp(
+  #include "foo.h"
+  #include "invalid.h"
+  int b = a;
+  )cpp";
+  FS.Files[FooCpp] = SourceContents;
+  auto FooH = getVirtualTestFilePath("foo.h");
+  const auto HeaderContents = "int a;";
+
+  FS.Files[FooCpp] = SourceContents;
+  FS.Files[FooH] = HeaderContents;
+
+  Server.addDocument(FooH, HeaderContents);
+  Server.addDocument(FooCpp, SourceContents);
+
+  Position P = Position{1, 11};
+
+  std::vector Locations = Server.findDefinitions(FooCpp, P).get().Value;
+  EXPECT_TRUE(!Locations.empty());
+  std::string s("file:///");
+  std::string check = Locations[0].uri.uri;
+  check = check.erase(0, s.size());
+  check = check.substr(0, check.size() - 1);
+  ASSERT_EQ(check, FooH);
+  ASSERT_EQ(Locations[0].range.start.line, 0);
+  ASSERT_EQ(Locations[0].range.start.character, 0);
+  ASSERT_EQ(Locations[0].range.end.line, 0);
+  ASSERT_EQ(Locations[0].range.end.character, 0);
+
+  // Test ctrl-clicking on the #include part on the statement
+  Position P3 = Position{1, 3};
+
+  Locations = Server.findDefinitions(FooCpp, P3).get().Value;
+  EXPECT_TRUE(!Locations.empty());
+
+  // Test invalid include
+  Position P2 = Position{2, 11};
+
+  Locations = Server.findDefinitions(FooCpp, P2).get().Value;
+  EXPECT_TRUE(Locations.empty());
+}
+
 TEST_F(ClangdThreadingTest, NoConcurrentDiagnostics) {
   class NoConcurrentAccessDiagConsumer : public DiagnosticsConsumer {
   public:
Index: clangd/Protocol.h
===
--- clangd/Protocol.h
+++ clangd/Protocol.h
@@ -108,6 +108,14 @@
 bool fromJSON(const json::Expr &, Range &);
 json::Expr toJSON(const Range &);
 
+class RangeHash {
+public:
+  std::size_t operator()(const Range ) const {
+return ((R.start.line & 0x18) << 3) | ((R.start.character & 0x18) << 1) |
+   ((R.end.line & 0x18) >> 1) | ((R.end.character & 0x18) >> 3);
+  }
+};
+
 struct Location {
   /// The text document's URI.
   URI uri;
Index: clangd/ClangdUnit.h
===
--- clangd/ClangdUnit.h
+++ clangd/ClangdUnit.h
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 namespace llvm {
 class raw_ostream;
@@ -59,6 +60,15 @@
   std::vector Diags;
 };
 
+class IncludeReferenceMap {
+  llvm::Optional findIncludeTargetAtLoc(Location Loc);
+
+public:
+  std::unordered_map IncludeLocationMap;
+  std::vector> DataVector;
+  std::vector RangeVector;
+};
+
 /// Stores and provides access to parsed AST.
 class ParsedAST {
 public:
@@ -69,7 +79,8 @@
 std::shared_ptr Preamble,
 std::unique_ptr Buffer,
 std::shared_ptr PCHs,
-IntrusiveRefCntPtr VFS, clangd::Logger );
+IntrusiveRefCntPtr VFS, clangd::Logger ,
+IncludeReferenceMap IRM);
 
   ParsedAST(ParsedAST &);
   ParsedAST =(ParsedAST &);
@@ -89,12 +100,14 @@
 
   const std::vector () const;
 
+  IncludeReferenceMap takeIRM() { return IRM; };
+
 private:
   ParsedAST(std::shared_ptr Preamble,
 std::unique_ptr Clang,
 std::unique_ptr Action,
 std::vector TopLevelDecls,
-std::vector Diags);
+std::vector Diags, IncludeReferenceMap IRM);
 
 private:
   void ensurePreambleDeclsDeserialized();
@@ -114,6 +127,8 @@
   std::vector Diags;
   std::vector TopLevelDecls;
   bool PreambleDeclsDeserialized;
+  std::vector PendingTopLevelDecls;
+  IncludeReferenceMap IRM;
 };
 
 // Provides thread-safe access to ParsedAST.
@@ -256,14 

[PATCH] D38639: [clangd] #include statements support for Open definition

2017-12-06 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 125813.
Nebiroth added a comment.
Herald added a subscriber: klimek.

Using PPCallbacks interface to find non-preamble includes
Created inner class to store vectors in to find locations
Refactored methods to remove some unnecessary parameters
Refactored Unit tests
Merge with most recent master branch + clang


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D38639

Files:
  clangd/ClangdServer.cpp
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/GlobalCompilationDatabase.cpp
  clangd/Protocol.h
  unittests/clangd/ClangdTests.cpp

Index: unittests/clangd/ClangdTests.cpp
===
--- unittests/clangd/ClangdTests.cpp
+++ unittests/clangd/ClangdTests.cpp
@@ -7,7 +7,6 @@
 //
 //===--===//
 
-#include "ClangdLSPServer.h"
 #include "ClangdServer.h"
 #include "Logger.h"
 #include "TestFS.h"
@@ -620,7 +619,7 @@
 AddDocument(FileIndex);
 
   Position Pos{LineDist(RandGen), ColumnDist(RandGen)};
-  ASSERT_TRUE(!!Server.findDefinitions(FilePaths[FileIndex], Pos));
+  Server.findDefinitions(FilePaths[FileIndex], Pos);
 };
 
 std::vector> AsyncRequests = {
@@ -749,6 +748,58 @@
   EXPECT_FALSE(PathResult.hasValue());
 }
 
+TEST_F(ClangdVFSTest, CheckDefinitionIncludes) {
+  MockFSProvider FS;
+  ErrorCheckingDiagConsumer DiagConsumer;
+  MockCompilationDatabase CDB;
+
+  ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(),
+  /*StorePreamblesInMemory=*/true,
+  EmptyLogger::getInstance());
+
+  auto FooCpp = getVirtualTestFilePath("foo.cpp");
+  const auto SourceContents = R"cpp(
+  #include "foo.h"
+  #include "invalid.h"
+  int b = a;
+  )cpp";
+  FS.Files[FooCpp] = SourceContents;
+  auto FooH = getVirtualTestFilePath("foo.h");
+  const auto HeaderContents = "int a;";
+
+  FS.Files[FooCpp] = SourceContents;
+  FS.Files[FooH] = HeaderContents;
+
+  Server.addDocument(FooH, HeaderContents);
+  Server.addDocument(FooCpp, SourceContents);
+
+  Position P = Position{1, 11};
+
+  std::vector Locations = Server.findDefinitions(FooCpp, P).get().Value;
+  EXPECT_TRUE(!Locations.empty());
+  std::string s("file:///");
+  std::string check = Locations[0].uri.uri;
+  check = check.erase(0, s.size());
+  check = check.substr(0, check.size() - 1);
+  ASSERT_EQ(check, FooH);
+  ASSERT_EQ(Locations[0].range.start.line, 0);
+  ASSERT_EQ(Locations[0].range.start.character, 0);
+  ASSERT_EQ(Locations[0].range.end.line, 0);
+  ASSERT_EQ(Locations[0].range.end.character, 0);
+
+  // Test ctrl-clicking on the #include part on the statement
+  Position P3 = Position{1, 3};
+
+  Locations = Server.findDefinitions(FooCpp, P3).get().Value;
+  EXPECT_TRUE(!Locations.empty());
+
+  // Test invalid include
+  Position P2 = Position{2, 11};
+
+  Locations = Server.findDefinitions(FooCpp, P2).get().Value;
+  EXPECT_TRUE(Locations.empty());
+}
+
 TEST_F(ClangdThreadingTest, NoConcurrentDiagnostics) {
   class NoConcurrentAccessDiagConsumer : public DiagnosticsConsumer {
   public:
Index: clangd/Protocol.h
===
--- clangd/Protocol.h
+++ clangd/Protocol.h
@@ -108,6 +108,14 @@
 bool fromJSON(const json::Expr &, Range &);
 json::Expr toJSON(const Range &);
 
+class RangeHash {
+public:
+  std::size_t operator()(const Range ) const {
+return ((R.start.line & 0x18) << 3) | ((R.start.character & 0x18) << 1) |
+   ((R.end.line & 0x18) >> 1) | ((R.end.character & 0x18) >> 3);
+  }
+};
+
 struct Location {
   /// The text document's URI.
   URI uri;
Index: clangd/GlobalCompilationDatabase.cpp
===
--- clangd/GlobalCompilationDatabase.cpp
+++ clangd/GlobalCompilationDatabase.cpp
@@ -9,6 +9,7 @@
 
 #include "GlobalCompilationDatabase.h"
 #include "Logger.h"
+#include "ProtocolHandlers.h"
 #include "clang/Tooling/CompilationDatabase.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
Index: clangd/ClangdUnit.h
===
--- clangd/ClangdUnit.h
+++ clangd/ClangdUnit.h
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 namespace llvm {
 class raw_ostream;
@@ -59,6 +60,15 @@
   std::vector Diags;
 };
 
+class IncludeReferenceMap {
+  llvm::Optional findIncludeTargetAtLoc(Location Loc);
+
+public:
+  std::unordered_map IncludeLocationMap;
+  std::vector> DataVector;
+  std::vector RangeVector;
+};
+
 /// Stores and provides access to parsed AST.
 class ParsedAST {
 public:
@@ -69,7 +79,8 @@
 std::shared_ptr Preamble,
 std::unique_ptr Buffer,
 std::shared_ptr PCHs,
-IntrusiveRefCntPtr VFS, clangd::Logger );
+IntrusiveRefCntPtr VFS, clangd::Logger ,
+IncludeReferenceMap 

[PATCH] D38425: [clangd] Document highlights for clangd

2017-12-05 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 125619.
Nebiroth added a comment.

Added static_cast when unparsing


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D38425

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/documenthighlight.test
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:  "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:  "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: test/clangd/documenthighlight.test
===
--- /dev/null
+++ test/clangd/documenthighlight.test
@@ -0,0 +1,42 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 479
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#define MACRO 1\nnamespace ns1 {\nstruct MyClass {\nint xasd;\nvoid anotherOperation() {\n}\nstatic int foo(MyClass*) {\nreturn 0;\n}\n\n};\nstruct Foo {\nint xasd;\n};\n}\nint main() {\nint bonjour;\nbonjour = 2;\nint test1 = bonjour;\nns1::Foo bar = { xasd : 1};\nbar.xasd = 3;\nns1::MyClass* Params;\nParams->anotherOperation();\n}\n"}}}
+
+Content-Length: 156
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":17,"character":2}}}
+# Verify local variable 
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":11,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}},{"kind":2,"range":{"end":{"character":19,"line":18},"start":{"character":12,"line":18}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":18,"character":17}}}
+# Verify struct highlight
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":11,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}},{"kind":2,"range":{"end":{"character":19,"line":18},"start":{"character":12,"line":18}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":21,"character":10}}}
+# Verify method highlight
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":14,"line":2},"start":{"character":7,"line":2}}},{"kind":1,"range":{"end":{"character":22,"line":6},"start":{"character":15,"line":6}}},{"kind":1,"range":{"end":{"character":12,"line":21},"start":{"character":5,"line":21}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":18,"character":14}}}
+# Verify Read-access of a symbol (kind = 2) 
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":11,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}},{"kind":2,"range":{"end":{"character":19,"line":18},"start":{"character":12,"line":18}}}]}
+
+Content-Length: 48
+
+{"jsonrpc":"2.0","id":1,"method":"shutdown"}
+
+Content-Length: 33
+
+{"jsonrpc":"2.0":"method":"exit"}			
\ No newline at end of file
Index: clangd/ProtocolHandlers.h

[PATCH] D38639: [clangd] #include statements support for Open definition

2017-12-05 Thread William Enright via Phabricator via cfe-commits
Nebiroth marked an inline comment as done.
Nebiroth added inline comments.



Comment at: clangd/ClangdUnit.cpp:38
 
+class DelegatingPPCallbacks : public PPCallbacks {
+

ilya-biryukov wrote:
> What's the purpose of this class?
We need to be able to use a wrapper class to be able to make a unique_ptr to be 
sent to PrecompiledPreamble::Build in order to add the list of preprocessor 
Callbacks.


https://reviews.llvm.org/D38639



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38425: [clangd] Document highlights for clangd

2017-12-05 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 125522.
Nebiroth added a comment.

Added error returns in findDocumentHighlights
Ran clang-format on ClangdUnit.h, .cpp and ClangdServer.cpp


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D38425

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/documenthighlight.test
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:  "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:  "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: test/clangd/documenthighlight.test
===
--- /dev/null
+++ test/clangd/documenthighlight.test
@@ -0,0 +1,42 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 479
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#define MACRO 1\nnamespace ns1 {\nstruct MyClass {\nint xasd;\nvoid anotherOperation() {\n}\nstatic int foo(MyClass*) {\nreturn 0;\n}\n\n};\nstruct Foo {\nint xasd;\n};\n}\nint main() {\nint bonjour;\nbonjour = 2;\nint test1 = bonjour;\nns1::Foo bar = { xasd : 1};\nbar.xasd = 3;\nns1::MyClass* Params;\nParams->anotherOperation();\n}\n"}}}
+
+Content-Length: 156
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":17,"character":2}}}
+# Verify local variable 
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":11,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}},{"kind":2,"range":{"end":{"character":19,"line":18},"start":{"character":12,"line":18}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":18,"character":17}}}
+# Verify struct highlight
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":11,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}},{"kind":2,"range":{"end":{"character":19,"line":18},"start":{"character":12,"line":18}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":21,"character":10}}}
+# Verify method highlight
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":14,"line":2},"start":{"character":7,"line":2}}},{"kind":1,"range":{"end":{"character":22,"line":6},"start":{"character":15,"line":6}}},{"kind":1,"range":{"end":{"character":12,"line":21},"start":{"character":5,"line":21}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":18,"character":14}}}
+# Verify Read-access of a symbol (kind = 2) 
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":11,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}},{"kind":2,"range":{"end":{"character":19,"line":18},"start":{"character":12,"line":18}}}]}
+
+Content-Length: 48
+
+{"jsonrpc":"2.0","id":1,"method":"shutdown"}
+
+Content-Length: 33
+
+{"jsonrpc":"2.0":"method":"exit"}			
\ No newline at end of file
Index: 

[PATCH] D38425: [clangd] Document highlights for clangd

2017-12-04 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 125346.
Nebiroth added a comment.

Minor code cleanup
Refactored findDocumentHighlights() to make tests pass when assertions are 
enabled


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D38425

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/documenthighlight.test
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:  "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:  "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: test/clangd/documenthighlight.test
===
--- /dev/null
+++ test/clangd/documenthighlight.test
@@ -0,0 +1,42 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 479
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#define MACRO 1\nnamespace ns1 {\nstruct MyClass {\nint xasd;\nvoid anotherOperation() {\n}\nstatic int foo(MyClass*) {\nreturn 0;\n}\n\n};\nstruct Foo {\nint xasd;\n};\n}\nint main() {\nint bonjour;\nbonjour = 2;\nint test1 = bonjour;\nns1::Foo bar = { xasd : 1};\nbar.xasd = 3;\nns1::MyClass* Params;\nParams->anotherOperation();\n}\n"}}}
+
+Content-Length: 156
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":17,"character":2}}}
+# Verify local variable 
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":11,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}},{"kind":2,"range":{"end":{"character":19,"line":18},"start":{"character":12,"line":18}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":18,"character":17}}}
+# Verify struct highlight
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":11,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}},{"kind":2,"range":{"end":{"character":19,"line":18},"start":{"character":12,"line":18}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":21,"character":10}}}
+# Verify method highlight
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":14,"line":2},"start":{"character":7,"line":2}}},{"kind":1,"range":{"end":{"character":22,"line":6},"start":{"character":15,"line":6}}},{"kind":1,"range":{"end":{"character":12,"line":21},"start":{"character":5,"line":21}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":18,"character":14}}}
+# Verify Read-access of a symbol (kind = 2) 
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":11,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}},{"kind":2,"range":{"end":{"character":19,"line":18},"start":{"character":12,"line":18}}}]}
+
+Content-Length: 48
+
+{"jsonrpc":"2.0","id":1,"method":"shutdown"}
+
+Content-Length: 33
+
+{"jsonrpc":"2.0":"method":"exit"}			
\ No newline at end of file
Index: 

[PATCH] D38425: [clangd] Document highlights for clangd

2017-12-01 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 125228.
Nebiroth added a comment.

Minor code cleanup
unparse and parse methods for JSON are updated


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D38425

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/documenthighlight.test
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:  "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:  "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: test/clangd/documenthighlight.test
===
--- /dev/null
+++ test/clangd/documenthighlight.test
@@ -0,0 +1,42 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 479
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#define MACRO 1\nnamespace ns1 {\nstruct MyClass {\nint xasd;\nvoid anotherOperation() {\n}\nstatic int foo(MyClass*) {\nreturn 0;\n}\n\n};\nstruct Foo {\nint xasd;\n};\n}\nint main() {\nint bonjour;\nbonjour = 2;\nint test1 = bonjour;\nns1::Foo bar = { xasd : 1};\nbar.xasd = 3;\nns1::MyClass* Params;\nParams->anotherOperation();\n}\n"}}}
+
+Content-Length: 156
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":17,"character":2}}}
+# Verify local variable 
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":11,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}},{"kind":2,"range":{"end":{"character":19,"line":18},"start":{"character":12,"line":18}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":18,"character":17}}}
+# Verify struct highlight
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":11,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}},{"kind":2,"range":{"end":{"character":19,"line":18},"start":{"character":12,"line":18}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":21,"character":10}}}
+# Verify method highlight
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":14,"line":2},"start":{"character":7,"line":2}}},{"kind":1,"range":{"end":{"character":22,"line":6},"start":{"character":15,"line":6}}},{"kind":1,"range":{"end":{"character":12,"line":21},"start":{"character":5,"line":21}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":18,"character":14}}}
+# Verify Read-access of a symbol (kind = 2) 
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":11,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}},{"kind":2,"range":{"end":{"character":19,"line":18},"start":{"character":12,"line":18}}}]}
+
+Content-Length: 48
+
+{"jsonrpc":"2.0","id":1,"method":"shutdown"}
+
+Content-Length: 33
+
+{"jsonrpc":"2.0":"method":"exit"}			
\ No newline at end of file
Index: clangd/ProtocolHandlers.h

[PATCH] D35894: [clangd] Code hover for Clangd

2017-12-01 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 125224.
Nebiroth added a comment.

Minor code cleanup
Merge with master


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D35894

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/hover.test
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -30,6 +30,7 @@
 # CHECK-NEXT:  "clangd.applyFix"
 # CHECK-NEXT:]
 # CHECK-NEXT:  },
+# CHECK-NEXT:	   "hoverProvider": true,
 # CHECK-NEXT:  "renameProvider": true,
 # CHECK-NEXT:  "signatureHelpProvider": {
 # CHECK-NEXT:"triggerCharacters": [
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -30,6 +30,7 @@
 # CHECK-NEXT:  "clangd.applyFix"
 # CHECK-NEXT:]
 # CHECK-NEXT:  },
+# CHECK-NEXT:	   "hoverProvider": true,
 # CHECK-NEXT:  "renameProvider": true,
 # CHECK-NEXT:  "signatureHelpProvider": {
 # CHECK-NEXT:"triggerCharacters": [
Index: test/clangd/hover.test
===
--- /dev/null
+++ test/clangd/hover.test
@@ -0,0 +1,56 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 611
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#define MACRO 1\nnamespace ns1 {\nint test = 5;\nstruct MyClass {\nint xasd;\nvoid anotherOperation() {\n}\nstatic int foo(MyClass*) {\nreturn 0;\n}\n\n};}\n//comments test\ntemplate\nT templateTest(T foo) {\nreturn foo;}\ntemplate\nclass classTemplateTest {\npublic: T test;};\nint main() {\nint a;\na;\nint b = ns1::test;\nns1::MyClass* Params;\nParams->anotherOperation();\nMACRO;\nint temp = 5;\ntemplateTest(temp);classTemplateTest test;}\n"}}}
+
+Content-Length: 144
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":0,"character":12}}}
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"#define MACRO 1"}],"range":{"end":{"character":15,"line":0},"start":{"character":8,"line":0
+
+Content-Length: 144
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":21,"character":1}}}
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"int a"}],"range":{"end":{"character":5,"line":20},"start":{"character":0,"line":20
+
+Content-Length: 145
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":22,"character":15}}}
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"In ns1"},{"language":"C++","value":"int test = 5"}],"range":{"end":{"character":12,"line":2},"start":{"character":0,"line":2
+
+Content-Length: 145
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":23,"character":10}}}
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"In ns1"},{"language":"C++","value":"struct MyClass {"}],"range":{"end":{"character":16,"line":3},"start":{"character":0,"line":3
+
+Content-Length: 145
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":24,"character":13}}}
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"In ns1::MyClass"},{"language":"C++","value":"void anotherOperation() {"}],"range":{"end":{"character":25,"line":5},"start":{"character":0,"line":5
+
+Content-Length: 144
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":25,"character":1}}}
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"#define MACRO 1"}],"range":{"end":{"character":15,"line":0},"start":{"character":8,"line":0
+
+Content-Length: 144
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":26,"character":8}}}
+# CHECK: 

[PATCH] D35894: [clangd] Code hover for Clangd

2017-12-01 Thread William Enright via Phabricator via cfe-commits
Nebiroth added inline comments.



Comment at: clangd/Protocol.h:26
 #include "llvm/ADT/Optional.h"
-#include 
+#include "llvm/Support/YAMLParser.h"
 #include 

malaperle wrote:
> Nebiroth wrote:
> > malaperle wrote:
> > > revert this change?
> > #include  is not needed.
> I meant removing YAMLParser.h
That's what I figured. I'll remove that.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D35894



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D35894: [clangd] Code hover for Clangd

2017-12-01 Thread William Enright via Phabricator via cfe-commits
Nebiroth marked 9 inline comments as done.
Nebiroth added inline comments.



Comment at: clangd/Protocol.h:26
 #include "llvm/ADT/Optional.h"
-#include 
+#include "llvm/Support/YAMLParser.h"
 #include 

malaperle wrote:
> revert this change?
#include  is not needed.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D35894



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38425: [clangd] Document highlights for clangd

2017-11-30 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 124951.
Nebiroth marked 6 inline comments as done.
Nebiroth added a comment.

  Minor code cleanup
  getDeclarationLocation now returns llvm::Optional
  operator< for DocumentHighlight struct now properly compares the kind field


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D38425

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/documenthighlight.test
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:  "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:  "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: test/clangd/documenthighlight.test
===
--- /dev/null
+++ test/clangd/documenthighlight.test
@@ -0,0 +1,42 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 479
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#define MACRO 1\nnamespace ns1 {\nstruct MyClass {\nint xasd;\nvoid anotherOperation() {\n}\nstatic int foo(MyClass*) {\nreturn 0;\n}\n\n};\nstruct Foo {\nint xasd;\n};\n}\nint main() {\nint bonjour;\nbonjour = 2;\nint test1 = bonjour;\nns1::Foo bar = { xasd : 1};\nbar.xasd = 3;\nns1::MyClass* Params;\nParams->anotherOperation();\n}\n"}}}
+
+Content-Length: 156
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":17,"character":2}}}
+# Verify local variable 
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":11,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}},{"kind":2,"range":{"end":{"character":19,"line":18},"start":{"character":12,"line":18}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":18,"character":17}}}
+# Verify struct highlight
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":11,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}},{"kind":2,"range":{"end":{"character":19,"line":18},"start":{"character":12,"line":18}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":21,"character":10}}}
+# Verify method highlight
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":14,"line":2},"start":{"character":7,"line":2}}},{"kind":1,"range":{"end":{"character":22,"line":6},"start":{"character":15,"line":6}}},{"kind":1,"range":{"end":{"character":12,"line":21},"start":{"character":5,"line":21}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":18,"character":14}}}
+# Verify Read-access of a symbol (kind = 2) 
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":11,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}},{"kind":2,"range":{"end":{"character":19,"line":18},"start":{"character":12,"line":18}}}]}
+
+Content-Length: 48
+
+{"jsonrpc":"2.0","id":1,"method":"shutdown"}
+
+Content-Length: 33
+

[PATCH] D35894: [clangd] Code hover for Clangd

2017-11-30 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 124945.
Nebiroth marked an inline comment as done.
Nebiroth added a comment.

  Simplified getHover() function
  Proper usage of ErrorOr to return errors
  Given range for Hover struct now only applies to the open file
  Fixed crash on MacroExpansion


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D35894

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/hover.test
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -30,6 +30,7 @@
 # CHECK-NEXT:  "clangd.applyFix"
 # CHECK-NEXT:]
 # CHECK-NEXT:  },
+# CHECK-NEXT:	   "hoverProvider": true,
 # CHECK-NEXT:  "renameProvider": true,
 # CHECK-NEXT:  "signatureHelpProvider": {
 # CHECK-NEXT:"triggerCharacters": [
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -30,6 +30,7 @@
 # CHECK-NEXT:  "clangd.applyFix"
 # CHECK-NEXT:]
 # CHECK-NEXT:  },
+# CHECK-NEXT:	   "hoverProvider": true,
 # CHECK-NEXT:  "renameProvider": true,
 # CHECK-NEXT:  "signatureHelpProvider": {
 # CHECK-NEXT:"triggerCharacters": [
Index: test/clangd/hover.test
===
--- /dev/null
+++ test/clangd/hover.test
@@ -0,0 +1,56 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 611
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#define MACRO 1\nnamespace ns1 {\nint test = 5;\nstruct MyClass {\nint xasd;\nvoid anotherOperation() {\n}\nstatic int foo(MyClass*) {\nreturn 0;\n}\n\n};}\n//comments test\ntemplate\nT templateTest(T foo) {\nreturn foo;}\ntemplate\nclass classTemplateTest {\npublic: T test;};\nint main() {\nint a;\na;\nint b = ns1::test;\nns1::MyClass* Params;\nParams->anotherOperation();\nMACRO;\nint temp = 5;\ntemplateTest(temp);classTemplateTest test;}\n"}}}
+
+Content-Length: 144
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":0,"character":12}}}
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"#define MACRO 1"}],"range":{"end":{"character":15,"line":0},"start":{"character":8,"line":0
+
+Content-Length: 144
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":21,"character":1}}}
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"int a"}],"range":{"end":{"character":5,"line":20},"start":{"character":0,"line":20
+
+Content-Length: 145
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":22,"character":15}}}
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"In ns1"},{"language":"C++","value":"int test = 5"}],"range":{"end":{"character":12,"line":2},"start":{"character":0,"line":2
+
+Content-Length: 145
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":23,"character":10}}}
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"In ns1"},{"language":"C++","value":"struct MyClass {"}],"range":{"end":{"character":16,"line":3},"start":{"character":0,"line":3
+
+Content-Length: 145
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":24,"character":13}}}
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"In ns1::MyClass"},{"language":"C++","value":"void anotherOperation() {"}],"range":{"end":{"character":25,"line":5},"start":{"character":0,"line":5
+
+Content-Length: 144
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":25,"character":1}}}
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"#define MACRO 1"}],"range":{"end":{"character":15,"line":0},"start":{"character":8,"line":0
+
+Content-Length: 144
+

[PATCH] D38425: [clangd] Document highlights for clangd

2017-11-29 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 124834.
Nebiroth added a comment.

Fixed wrong content header making the test fail


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D38425

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/documenthighlight.test
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:	   "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:	   "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: test/clangd/documenthighlight.test
===
--- /dev/null
+++ test/clangd/documenthighlight.test
@@ -0,0 +1,42 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 479
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#define MACRO 1\nnamespace ns1 {\nstruct MyClass {\nint xasd;\nvoid anotherOperation() {\n}\nstatic int foo(MyClass*) {\nreturn 0;\n}\n\n};\nstruct Foo {\nint xasd;\n};\n}\nint main() {\nint bonjour;\nbonjour = 2;\nint test1 = bonjour;\nns1::Foo bar = { xasd : 1};\nbar.xasd = 3;\nns1::MyClass* Params;\nParams->anotherOperation();\n}\n"}}}
+
+Content-Length: 156
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":17,"character":2}}}
+# Verify local variable 
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":11,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}},{"kind":2,"range":{"end":{"character":19,"line":18},"start":{"character":12,"line":18}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":18,"character":17}}}
+# Verify struct highlight
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":11,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}},{"kind":2,"range":{"end":{"character":19,"line":18},"start":{"character":12,"line":18}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":21,"character":10}}}
+# Verify method highlight
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":14,"line":2},"start":{"character":7,"line":2}}},{"kind":1,"range":{"end":{"character":22,"line":6},"start":{"character":15,"line":6}}},{"kind":1,"range":{"end":{"character":12,"line":21},"start":{"character":5,"line":21}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":18,"character":14}}}
+# Verify Read-access of a symbol (kind = 2) 
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":11,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}},{"kind":2,"range":{"end":{"character":19,"line":18},"start":{"character":12,"line":18}}}]}
+
+Content-Length: 48
+
+{"jsonrpc":"2.0","id":1,"method":"shutdown"}
+
+Content-Length: 33
+
+{"jsonrpc":"2.0":"method":"exit"}			
\ No newline at end of file
Index: clangd/ProtocolHandlers.h

[PATCH] D35894: [clangd] Code hover for Clangd

2017-11-29 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 124833.
Nebiroth added a comment.
Herald added a subscriber: klimek.

Invalid FileEntries now return llvm:ErrorOr


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D35894

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/hover.test
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -30,6 +30,7 @@
 # CHECK-NEXT:  "clangd.applyFix"
 # CHECK-NEXT:]
 # CHECK-NEXT:  },
+# CHECK-NEXT:	   "hoverProvider": true,
 # CHECK-NEXT:  "renameProvider": true,
 # CHECK-NEXT:  "signatureHelpProvider": {
 # CHECK-NEXT:"triggerCharacters": [
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -30,6 +30,7 @@
 # CHECK-NEXT:  "clangd.applyFix"
 # CHECK-NEXT:]
 # CHECK-NEXT:  },
+# CHECK-NEXT:	   "hoverProvider": true,
 # CHECK-NEXT:  "renameProvider": true,
 # CHECK-NEXT:  "signatureHelpProvider": {
 # CHECK-NEXT:"triggerCharacters": [
Index: test/clangd/hover.test
===
--- /dev/null
+++ test/clangd/hover.test
@@ -0,0 +1,56 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 611
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#define MACRO 1\nnamespace ns1 {\nint test = 5;\nstruct MyClass {\nint xasd;\nvoid anotherOperation() {\n}\nstatic int foo(MyClass*) {\nreturn 0;\n}\n\n};}\n//comments test\ntemplate\nT templateTest(T foo) {\nreturn foo;}\ntemplate\nclass classTemplateTest {\npublic: T test;};\nint main() {\nint a;\na;\nint b = ns1::test;\nns1::MyClass* Params;\nParams->anotherOperation();\nMACRO;\nint temp = 5;\ntemplateTest(temp);classTemplateTest test;}\n"}}}
+
+Content-Length: 144
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":0,"character":12}}}
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"#define MACRO 1"}],"range":{"end":{"character":15,"line":0},"start":{"character":8,"line":0
+
+Content-Length: 144
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":21,"character":1}}}
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"int a"}],"range":{"end":{"character":5,"line":20},"start":{"character":0,"line":20
+
+Content-Length: 145
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":22,"character":15}}}
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"In ns1"},{"language":"C++","value":"int test = 5"}],"range":{"end":{"character":12,"line":2},"start":{"character":0,"line":2
+
+Content-Length: 145
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":23,"character":10}}}
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"In ns1"},{"language":"C++","value":"struct MyClass {"}],"range":{"end":{"character":16,"line":3},"start":{"character":0,"line":3
+
+Content-Length: 145
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":24,"character":13}}}
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"In ns1::MyClass"},{"language":"C++","value":"void anotherOperation() {"}],"range":{"end":{"character":25,"line":5},"start":{"character":0,"line":5
+
+Content-Length: 144
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":25,"character":1}}}
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"#define MACRO 1"}],"range":{"end":{"character":15,"line":0},"start":{"character":8,"line":0
+
+Content-Length: 144
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":26,"character":8}}}
+# 

[PATCH] D38425: [clangd] Document highlights for clangd

2017-11-29 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 124810.
Nebiroth added a comment.

Added verification for llvm::Expected in onDocumentHighlight
Removed unused variable in ClangdUnit


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D38425

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/documenthighlight.test
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:	   "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:	   "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: test/clangd/documenthighlight.test
===
--- /dev/null
+++ test/clangd/documenthighlight.test
@@ -0,0 +1,42 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 479
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#define MACRO 1\nnamespace ns1 {\nstruct MyClass {\nint xasd;\nvoid anotherOperation() {\n}\nstatic int foo(MyClass*) {\nreturn 0;\n}\n\n};\nstruct Foo {\nint xasd;\n};\n}\nint main() {\nint bonjour;\nbonjour = 2;\nint test1 = bonjour;\nns1::Foo bar = { xasd : 1};\nbar.xasd = 3;\nns1::MyClass* Params;\nParams->anotherOperation();\n}\n"}}}
+
+Content-Length: 156
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":17,"character":2}}}
+# Verify local variable 
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":11,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}},{"kind":2,"range":{"end":{"character":19,"line":18},"start":{"character":12,"line":18}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":18,"character":17}}}
+# Verify struct highlight
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":11,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}},{"kind":2,"range":{"end":{"character":19,"line":18},"start":{"character":12,"line":18}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":21,"character":10}}}
+# Verify method highlight
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":14,"line":2},"start":{"character":7,"line":2}}},{"kind":1,"range":{"end":{"character":22,"line":6},"start":{"character":15,"line":6}}},{"kind":1,"range":{"end":{"character":12,"line":21},"start":{"character":5,"line":21}}}]}
+
+Content-Length: 156
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":18,"character":14}}}
+# Verify Read-access of a symbol (kind = 2) 
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":11,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}},{"kind":2,"range":{"end":{"character":19,"line":18},"start":{"character":12,"line":18}}}]}
+
+Content-Length: 48
+
+{"jsonrpc":"2.0","id":1,"method":"shutdown"}
+
+Content-Length: 33
+
+{"jsonrpc":"2.0":"method":"exit"}			
\ No newline at end of file
Index: clangd/ProtocolHandlers.h

[PATCH] D38425: [clangd] Document highlights for clangd

2017-11-27 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 124458.
Nebiroth marked 3 inline comments as done.
Nebiroth added a comment.

Minor code cleanup
Fixed highlights sometimes obtaining one too many characters inside range
Updated test


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D38425

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/documenthighlight.test
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:	   "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:	   "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: test/clangd/documenthighlight.test
===
--- /dev/null
+++ test/clangd/documenthighlight.test
@@ -0,0 +1,42 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 479
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#define MACRO 1\nnamespace ns1 {\nstruct MyClass {\nint xasd;\nvoid anotherOperation() {\n}\nstatic int foo(MyClass*) {\nreturn 0;\n}\n\n};\nstruct Foo {\nint xasd;\n};\n}\nint main() {\nint bonjour;\nbonjour = 2;\nint test1 = bonjour;\nns1::Foo bar = { xasd : 1};\nbar.xasd = 3;\nns1::MyClass* Params;\nParams->anotherOperation();\n}\n"}}}
+
+Content-Length: 156
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":17,"character":2}}}
+# Verify local variable 
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":11,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}},{"kind":2,"range":{"end":{"character":19,"line":18},"start":{"character":12,"line":18}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":18,"character":17}}}
+# Verify struct highlight
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":11,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}},{"kind":2,"range":{"end":{"character":19,"line":18},"start":{"character":12,"line":18}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":21,"character":10}}}
+# Verify method highlight
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":14,"line":2},"start":{"character":7,"line":2}}},{"kind":1,"range":{"end":{"character":22,"line":6},"start":{"character":15,"line":6}}},{"kind":1,"range":{"end":{"character":12,"line":21},"start":{"character":5,"line":21}}}]}
+
+Content-Length: 156
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":18,"character":14}}}
+# Verify Read-access of a symbol (kind = 2) 
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":11,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}},{"kind":2,"range":{"end":{"character":19,"line":18},"start":{"character":12,"line":18}}}]}
+
+Content-Length: 48
+
+{"jsonrpc":"2.0","id":1,"method":"shutdown"}
+
+Content-Length: 33
+
+{"jsonrpc":"2.0":"method":"exit"}			
\ No newline 

[PATCH] D39571: [clangd] DidChangeConfiguration Notification

2017-11-27 Thread William Enright via Phabricator via cfe-commits
Nebiroth marked 12 inline comments as done.
Nebiroth added inline comments.



Comment at: test/clangd/did-change-configuration.test:33
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///compile_commands.json","languageId":"json","version":1,"text":"[\n{\n"directory":"/",\n"command":"/usr/bin/c++-DGTEST_HAS_RTTI=0-D_GNU_SOURCE-D__STDC_CONSTANT_MACROS-D__STDC_FORMAT_MACROS-D__STDC_LIMIT_MACROS-Ilib/Demangle-I../lib/Demangle-I/usr/include/libxml2-Iinclude-I../include-fPIC-fvisibility-inlines-hidden-Werror=date-time-std=c++11-Wall-W-Wno-unused-parameter-Wwrite-strings-Wcast-qual-Wno-missing-field-initializers-pedantic-Wno-long-long-Wno-maybe-uninitialized-Wdelete-non-virtual-dtor-Wno-comment-O0-g-fno-exceptions-fno-rtti-o/foo.c.o-c/foo.c",\n"file":"/foo.c"\n},"}}}
+

ilya-biryukov wrote:
> clangd won't see this file. `didOpen` only sets contents for diagnostics, not 
> any other features.
> You would rather want to add more `# RUN:` directives at the top of the file 
> to create `compile_commands.json`, etc.
> 
> Writing it under root ('/') is obviously not an option. Lit tests allow you 
> to use temporary paths, this is probably an approach you could take. See [[ 
> https://llvm.org/docs/TestingGuide.html#substitutions | lit docs ]] for more 
> details.
Are there examples available on how to use this? I have to use a # RUN: to 
create a file and then use it's path in a workspace/didChangeConfiguration 
notification?


https://reviews.llvm.org/D39571



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38425: [clangd] Document highlights for clangd

2017-11-27 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 124391.
Nebiroth marked an inline comment as done.
Nebiroth added a comment.
Herald added a subscriber: klimek.

Removed temporary test file
Updated test to account for read-access symbol verification


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D38425

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/documenthighlight.test
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:	   "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:	   "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: test/clangd/documenthighlight.test
===
--- /dev/null
+++ test/clangd/documenthighlight.test
@@ -0,0 +1,42 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 479
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#define MACRO 1\nnamespace ns1 {\nstruct MyClass {\nint xasd;\nvoid anotherOperation() {\n}\nstatic int foo(MyClass*) {\nreturn 0;\n}\n\n};\nstruct Foo {\nint xasd;\n};\n}\nint main() {\nint bonjour;\nbonjour = 2;\nint test1 = bonjour;\nns1::Foo bar = { xasd : 1};\nbar.xasd = 3;\nns1::MyClass* Params;\nParams->anotherOperation();\n}\n"}}}
+
+Content-Length: 156
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":17,"character":2}}}
+# Verify local variable 
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":12,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}},{"kind":2,"range":{"end":{"character":20,"line":18},"start":{"character":12,"line":18}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":18,"character":17}}}
+# Verify struct highlight
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":12,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}},{"kind":2,"range":{"end":{"character":20,"line":18},"start":{"character":12,"line":18}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":21,"character":10}}}
+# Verify method highlight
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":14,"line":2},"start":{"character":7,"line":2}}},{"kind":1,"range":{"end":{"character":23,"line":6},"start":{"character":15,"line":6}}},{"kind":1,"range":{"end":{"character":13,"line":21},"start":{"character":5,"line":21}}}]}
+
+Content-Length: 156
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":18,"character":14}}}
+# Verify Read-access of a symbol (kind = 2) 
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":12,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}},{"kind":2,"range":{"end":{"character":20,"line":18},"start":{"character":12,"line":18}}}]}
+
+Content-Length: 48
+
+{"jsonrpc":"2.0","id":1,"method":"shutdown"}
+
+Content-Length: 33
+
+{"jsonrpc":"2.0":"method":"exit"}		

[PATCH] D38425: [clangd] Document highlights for clangd

2017-11-24 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 124238.
Nebiroth marked 3 inline comments as done.
Nebiroth added a comment.

Fixed test checking for values from an incorrect bit shift


https://reviews.llvm.org/D38425

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  clangd/main.cpp
  test/clangd/documenthighlight.test
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:	   "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:	   "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: test/clangd/documenthighlight.test
===
--- /dev/null
+++ test/clangd/documenthighlight.test
@@ -0,0 +1,38 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 455
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#define MACRO 1\nnamespace ns1 {\nstruct MyClass {\nint xasd;\nvoid anotherOperation() {\n}\nstatic int foo(MyClass*) {\nreturn 0;\n}\n\n};\nstruct Foo {\nint xasd;\n};\n}\nint main() {\nint bonjour;\nbonjour = 2;\nns1::Foo bar = { xasd : 1};\nbar.xasd = 3;\nns1::MyClass* Params;\nParams->anotherOperation();}\n"}}}
+
+Content-Length: 156
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":17,"character":2}}}
+# Go to local variable
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":12,"line":16},"start":{"character":4,"line":16}}},{"kind":3,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}}]}
+
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":18,"character":17}}}
+# Go to local variable
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":9,"line":12},"start":{"character":4,"line":12}}},{"kind":1,"range":{"end":{"character":21,"line":18},"start":{"character":17,"line":18}}},{"kind":3,"range":{"end":{"character":8,"line":19},"start":{"character":4,"line":19}}}]}
+
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":21,"character":10}}}
+# Go to local variable
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":22,"line":4},"start":{"character":5,"line":4}}},{"kind":1,"range":{"end":{"character":25,"line":21},"start":{"character":8,"line":21}}}]}
+
+Content-Length: 48
+
+{"jsonrpc":"2.0","id":1,"method":"shutdown"}
+
+Content-Length: 33
+
+{"jsonrpc":"2.0":"method":"exit"}			
\ No newline at end of file
Index: clangd/main.cpp
===
--- /dev/null
+++ clangd/main.cpp
@@ -0,0 +1,22 @@
+#define MACRO 1
+namespace ns1 {
+struct MyClass {
+int xasd;
+void anotherOperation(){
+}
+static int foo(MyClass*) {
+return 0;
+}
+
+};
+struct Foo {
+int xasd;
+};
+}
+int main() {
+int bonjour;
+bonjour = 2;
+ns1::Foo bar = { xasd : 1};
+bar.xasd = 3;
+ns1::MyClass* Params;
+Params->anotherOperation();}
\ No newline at end of file
Index: clangd/ProtocolHandlers.h
===
--- clangd/ProtocolHandlers.h
+++ clangd/ProtocolHandlers.h
@@ -54,6 +54,8 @@
   virtual void onFileEvent(Ctx C, DidChangeWatchedFilesParams ) = 0;
   virtual void onCommand(Ctx C, ExecuteCommandParams ) = 0;
   

[PATCH] D38425: [clangd] Document highlights for clangd

2017-11-24 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 124230.
Nebiroth marked 6 inline comments as done.
Nebiroth added a comment.

Fixed a few outstanding issues that were reported as completed


https://reviews.llvm.org/D38425

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/documenthighlight.test
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:	   "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:	   "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: test/clangd/documenthighlight.test
===
--- /dev/null
+++ test/clangd/documenthighlight.test
@@ -0,0 +1,37 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 455
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#define MACRO 1\nnamespace ns1 {\nstruct MyClass {\nint xasd;\nvoid anotherOperation() {\n}\nstatic int foo(MyClass*) {\nreturn 0;\n}\n\n};\nstruct Foo {\nint xasd;\n};\n}\nint main() {\nint bonjour;\nbonjour = 2;\nns1::Foo bar = { xasd : 1};\nbar.xasd = 3;\nns1::MyClass* Params;\nParams->anotherOperation();}\n"}}}
+
+Content-Length: 156
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":17,"character":2}}}
+# Go to local variable
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":12,"line":16},"start":{"character":4,"line":16}}},{"kind":0,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}}]}
+
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":18,"character":17}}}
+# Go to local variable
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":9,"line":12},"start":{"character":4,"line":12}}},{"kind":1,"range":{"end":{"character":21,"line":18},"start":{"character":17,"line":18}}},{"kind":216,"range":{"end":{"character":21,"line":18},"start":{"character":17,"line":18}}},{"kind":220,"range":{"end":{"character":8,"line":19},"start":{"character":4,"line":19}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":21,"character":10}}}
+# Go to local variable
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":22,"line":4},"start":{"character":5,"line":4}}},{"kind":0,"range":{"end":{"character":25,"line":21},"start":{"character":8,"line":21}}}]}
+
+Content-Length: 48
+
+{"jsonrpc":"2.0","id":1,"method":"shutdown"}
+
+Content-Length: 33
+
+{"jsonrpc":"2.0":"method":"exit"}			
\ No newline at end of file
Index: clangd/ProtocolHandlers.h
===
--- clangd/ProtocolHandlers.h
+++ clangd/ProtocolHandlers.h
@@ -54,6 +54,8 @@
   virtual void onFileEvent(Ctx C, DidChangeWatchedFilesParams ) = 0;
   virtual void onCommand(Ctx C, ExecuteCommandParams ) = 0;
   virtual void onRename(Ctx C, RenameParams ) = 0;
+  virtual void onDocumentHighlight(Ctx C,
+   TextDocumentPositionParams ) = 0;
 };
 
 void registerCallbackHandlers(JSONRPCDispatcher , JSONOutput ,
Index: clangd/ProtocolHandlers.cpp
===
--- clangd/ProtocolHandlers.cpp
+++ clangd/ProtocolHandlers.cpp
@@ -74,4 

[PATCH] D38425: [clangd] Document highlights for clangd

2017-11-24 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 124224.
Nebiroth marked an inline comment as done.
Nebiroth added a comment.

Getting DocumentHighlightKind is now done in DocumentHighlightsFinder
Removed duplicated and unused code
Refactored method and variable names


https://reviews.llvm.org/D38425

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/documenthighlight.test
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:	   "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:	   "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: test/clangd/documenthighlight.test
===
--- /dev/null
+++ test/clangd/documenthighlight.test
@@ -0,0 +1,37 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 455
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#define MACRO 1\nnamespace ns1 {\nstruct MyClass {\nint xasd;\nvoid anotherOperation() {\n}\nstatic int foo(MyClass*) {\nreturn 0;\n}\n\n};\nstruct Foo {\nint xasd;\n};\n}\nint main() {\nint bonjour;\nbonjour = 2;\nns1::Foo bar = { xasd : 1};\nbar.xasd = 3;\nns1::MyClass* Params;\nParams->anotherOperation();}\n"}}}
+
+Content-Length: 156
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":17,"character":2}}}
+# Go to local variable
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":12,"line":16},"start":{"character":4,"line":16}}},{"kind":0,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}}]}
+
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":18,"character":17}}}
+# Go to local variable
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":9,"line":12},"start":{"character":4,"line":12}}},{"kind":1,"range":{"end":{"character":21,"line":18},"start":{"character":17,"line":18}}},{"kind":216,"range":{"end":{"character":21,"line":18},"start":{"character":17,"line":18}}},{"kind":220,"range":{"end":{"character":8,"line":19},"start":{"character":4,"line":19}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":21,"character":10}}}
+# Go to local variable
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":22,"line":4},"start":{"character":5,"line":4}}},{"kind":0,"range":{"end":{"character":25,"line":21},"start":{"character":8,"line":21}}}]}
+
+Content-Length: 48
+
+{"jsonrpc":"2.0","id":1,"method":"shutdown"}
+
+Content-Length: 33
+
+{"jsonrpc":"2.0":"method":"exit"}			
\ No newline at end of file
Index: clangd/ProtocolHandlers.h
===
--- clangd/ProtocolHandlers.h
+++ clangd/ProtocolHandlers.h
@@ -54,6 +54,8 @@
   virtual void onFileEvent(Ctx C, DidChangeWatchedFilesParams ) = 0;
   virtual void onCommand(Ctx C, ExecuteCommandParams ) = 0;
   virtual void onRename(Ctx C, RenameParams ) = 0;
+  virtual void onDocumentHighlight(Ctx C,
+   TextDocumentPositionParams ) = 0;
 };
 
 void registerCallbackHandlers(JSONRPCDispatcher , JSONOutput ,
Index: clangd/ProtocolHandlers.cpp

[PATCH] D38425: [clangd] Document highlights for clangd

2017-11-24 Thread William Enright via Phabricator via cfe-commits
Nebiroth marked 31 inline comments as done.
Nebiroth added inline comments.



Comment at: clangd/ClangdServer.h:291
+  /// Get document highlights for a symbol hovered on.
+  Tagged findDocumentHighlights(PathRef File,
+Position Pos);

malaperle wrote:
> can this thing fail? Should it be Expectedhttps://reviews.llvm.org/D38425



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39571: [clangd] DidChangeConfiguration Notification

2017-11-22 Thread William Enright via Phabricator via cfe-commits
Nebiroth added inline comments.



Comment at: clangd/GlobalCompilationDatabase.cpp:108
   Logger.log("Failed to find compilation database for " + Twine(File) +
- "in overriden directory " + CompileCommandsDir.getValue() +
+ " in overriden directory " + CompileCommandsDir.getValue() +
  "\n");

ilya-biryukov wrote:
> Accidental change?
Twine(File) and "in overriden directory" did not have a space to separate 
otherwise.


https://reviews.llvm.org/D39571



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39571: [clangd] DidChangeConfiguration Notification

2017-11-22 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 124024.
Nebiroth marked 19 inline comments as done.
Nebiroth added a comment.

Fixed DraftStore thread-safe API being broken
Removed superfluous getCompilationDatabase call
Changed name of struct to ClangDConfigurationParamsChange
Removed operator ! overload for struct
Minor code cleanup


https://reviews.llvm.org/D39571

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/DraftStore.cpp
  clangd/DraftStore.h
  clangd/GlobalCompilationDatabase.cpp
  clangd/GlobalCompilationDatabase.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/did-change-configuration.test
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -18,6 +18,7 @@
 # CHECK-NEXT:  ":"
 # CHECK-NEXT:]
 # CHECK-NEXT:  },
+# CHECK-NEXT:  "configurationChangeProvider": true,
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
@@ -48,4 +49,4 @@
 # CHECK-NEXT:  "result": null
 Content-Length: 33
 
-{"jsonrpc":"2.0":"method":"exit"}
+{"jsonrpc":"2.0":"method":"exit"}
\ No newline at end of file
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -1,3 +1,4 @@
+
 # RUN: clangd -pretty -run-synchronously < %s | FileCheck -strict-whitespace %s
 # It is absolutely vital that this file has CRLF line endings.
 #
@@ -18,6 +19,7 @@
 # CHECK-NEXT:  ":"
 # CHECK-NEXT:]
 # CHECK-NEXT:  },
+# CHECK-NEXT:  "configurationChangeProvider": true,
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
@@ -45,4 +47,4 @@
 {"jsonrpc":"2.0","id":3,"method":"shutdown"}
 Content-Length: 33
 
-{"jsonrpc":"2.0":"method":"exit"}
+{"jsonrpc":"2.0":"method":"exit"}
\ No newline at end of file
Index: test/clangd/did-change-configuration.test
===
--- /dev/null
+++ test/clangd/did-change-configuration.test
@@ -0,0 +1,46 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 150
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///foo.c","languageId":"c","version":1,"text":"voidmain(){}"}}}
+
+Content-Length: 86
+
+{"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":""}}
+#Failed to decode workspace/didChangeConfiguration request.
+#Incorrect mapping node
+
+Content-Length: 114
+
+{"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{"compilationDatabasePath":{
+#Failed to decode workspace/didChangeConfiguration request.
+#compilationDatabasePath is not a scalar node
+
+Content-Length: 140
+
+{"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{"compilationDatabasePath":"/","testBadValue":"foo1234"}}}
+#Ignored unknown field "testBadValue"
+#Failed to find compilation database for / in overriden directory /
+#Bad field, bad compilation database
+
+Content-Length: 722
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///compile_commands.json","languageId":"json","version":1,"text":"[\n{\n"directory":"/",\n"command":"/usr/bin/c++-DGTEST_HAS_RTTI=0-D_GNU_SOURCE-D__STDC_CONSTANT_MACROS-D__STDC_FORMAT_MACROS-D__STDC_LIMIT_MACROS-Ilib/Demangle-I../lib/Demangle-I/usr/include/libxml2-Iinclude-I../include-fPIC-fvisibility-inlines-hidden-Werror=date-time-std=c++11-Wall-W-Wno-unused-parameter-Wwrite-strings-Wcast-qual-Wno-missing-field-initializers-pedantic-Wno-long-long-Wno-maybe-uninitialized-Wdelete-non-virtual-dtor-Wno-comment-O0-g-fno-exceptions-fno-rtti-o/foo.c.o-c/foo.c",\n"file":"/foo.c"\n},"}}}
+
+Content-Length: 115
+
+{"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{"compilationDatabasePath":"/"}}}
+#CHECK:{"jsonrpc":"2.0","method":"textDocument/publishDiagnostics","params":{"diagnostics":[{"message":"type specifier missing, defaults to 'int'","range":{"end":{"character":1,"line":0},"start":{"character":1,"line":0}},"severity":2},{"message":"control reaches end of non-void 

[PATCH] D35894: [clangd] Code hover for Clangd

2017-11-22 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 123958.
Nebiroth marked 10 inline comments as done.
Nebiroth added a comment.

Removed accidentally included files
Fixed some coding standard issues
Removed getDeclarationLocation declaration from header file
Replaced getFunctionComments with clang implementation
onCodeHover now follows error-reporting pattern


https://reviews.llvm.org/D35894

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/hover.test
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -5,6 +5,7 @@
 Content-Length: 143
 
 {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootUri":"file:///path/to/workspace","capabilities":{},"trace":"off"}}
+
 #  CHECK:  "id": 0,
 # CHECK-NEXT:  "jsonrpc": "2.0",
 # CHECK-NEXT:  "result": {
@@ -30,6 +31,7 @@
 # CHECK-NEXT:  "clangd.applyFix"
 # CHECK-NEXT:]
 # CHECK-NEXT:  },
+# CHECK-NEXT:	   "hoverProvider": true,
 # CHECK-NEXT:  "renameProvider": true,
 # CHECK-NEXT:  "signatureHelpProvider": {
 # CHECK-NEXT:"triggerCharacters": [
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -30,6 +30,7 @@
 # CHECK-NEXT:  "clangd.applyFix"
 # CHECK-NEXT:]
 # CHECK-NEXT:  },
+# CHECK-NEXT:	   "hoverProvider": true,
 # CHECK-NEXT:  "renameProvider": true,
 # CHECK-NEXT:  "signatureHelpProvider": {
 # CHECK-NEXT:"triggerCharacters": [
@@ -40,6 +41,7 @@
 # CHECK-NEXT:  "textDocumentSync": 1
 # CHECK-NEXT:}
 # CHECK-NEXT:  }
+
 Content-Length: 44
 
 {"jsonrpc":"2.0","id":3,"method":"shutdown"}
Index: test/clangd/hover.test
===
--- /dev/null
+++ test/clangd/hover.test
@@ -0,0 +1,52 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 407
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#define MACRO 1\nnamespace ns1 {\nint test = 5;\nstruct MyClass {\nint xasd;\nvoid anotherOperation() {\n}\nstatic int foo(MyClass*) {\nreturn 0;\n}\n\n};}\nint main() {\nint a;\na;\nint b = ns1::test;\nns1::MyClass* Params;\nParams->anotherOperation();\nMACRO;}\n"}}}
+
+Content-Length: 144
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":0,"character":12}}}
+# Go to local variable
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"#define MACRO 1"}],"range":{"end":{"character":15,"line":0},"start":{"character":8,"line":0
+
+Content-Length: 144
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":14,"character":1}}}
+# Go to local variable
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"int a"}],"range":{"end":{"character":5,"line":13},"start":{"character":0,"line":13
+
+Content-Length: 145
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":15,"character":15}}}
+# Go to local variable
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"In ns1"},{"language":"C++","value":"int test = 5"}],"range":{"end":{"character":12,"line":2},"start":{"character":0,"line":2
+
+Content-Length: 145
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":16,"character":10}}}
+# Go to local variable
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"In ns1"},{"language":"C++","value":"struct MyClass {"}],"range":{"end":{"character":16,"line":3},"start":{"character":0,"line":3
+
+Content-Length: 145
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":17,"character":13}}}
+# Go to local variable
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"In ns1::MyClass"},{"language":"C++","value":"void anotherOperation() 

[PATCH] D38425: [clangd] Document highlights for clangd

2017-11-21 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 123848.
Nebiroth added a comment.

Removed some commented lines and temporary code
Streamlined and removed some code that overlaps/conflicts with code hover patch 
so it's easier to merge (patch https://reviews.llvm.org/D35894)


https://reviews.llvm.org/D38425

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/documenthighlight.test
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:	   "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:	   "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: test/clangd/documenthighlight.test
===
--- /dev/null
+++ test/clangd/documenthighlight.test
@@ -0,0 +1,37 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 455
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#define MACRO 1\nnamespace ns1 {\nstruct MyClass {\nint xasd;\nvoid anotherOperation() {\n}\nstatic int foo(MyClass*) {\nreturn 0;\n}\n\n};\nstruct Foo {\nint xasd;\n};\n}\nint main() {\nint bonjour;\nbonjour = 2;\nns1::Foo bar = { xasd : 1};\nbar.xasd = 3;\nns1::MyClass* Params;\nParams->anotherOperation();}\n"}}}
+
+Content-Length: 156
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":17,"character":2}}}
+# Go to local variable
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":12,"line":16},"start":{"character":4,"line":16}}},{"kind":0,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}}]}
+
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":18,"character":17}}}
+# Go to local variable
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":9,"line":12},"start":{"character":4,"line":12}}},{"kind":1,"range":{"end":{"character":21,"line":18},"start":{"character":17,"line":18}}},{"kind":216,"range":{"end":{"character":21,"line":18},"start":{"character":17,"line":18}}},{"kind":220,"range":{"end":{"character":8,"line":19},"start":{"character":4,"line":19}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":21,"character":10}}}
+# Go to local variable
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":22,"line":4},"start":{"character":5,"line":4}}},{"kind":0,"range":{"end":{"character":25,"line":21},"start":{"character":8,"line":21}}}]}
+
+Content-Length: 48
+
+{"jsonrpc":"2.0","id":1,"method":"shutdown"}
+
+Content-Length: 33
+
+{"jsonrpc":"2.0":"method":"exit"}			
\ No newline at end of file
Index: clangd/ProtocolHandlers.h
===
--- clangd/ProtocolHandlers.h
+++ clangd/ProtocolHandlers.h
@@ -31,7 +31,6 @@
 public:
   using Ctx = RequestContext;
   virtual ~ProtocolCallbacks() = default;
-
   virtual void onInitialize(Ctx C, InitializeParams ) = 0;
   virtual void onShutdown(Ctx C, ShutdownParams ) = 0;
   virtual void onExit(Ctx C, ExitParams ) = 0;
@@ -54,6 +53,8 @@
   virtual void onFileEvent(Ctx C, DidChangeWatchedFilesParams ) = 0;
   virtual void onCommand(Ctx C, ExecuteCommandParams ) = 0;
   virtual void onRename(Ctx C, RenameParams ) = 0;
+  

[PATCH] D35894: [clangd] Code hover for Clangd

2017-11-20 Thread William Enright via Phabricator via cfe-commits
Nebiroth added a comment.

Forgot to mention this last patch also added support for displaying function 
comments above the function definition displayed.


https://reviews.llvm.org/D35894



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D35894: [clangd] Code hover for Clangd

2017-11-20 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 123662.
Nebiroth marked 10 inline comments as done.
Nebiroth added a comment.

Removed all std::pair objects
Fixed and updated all tests
findHover doesn't call findDefinitions anymore
DeclarationLocationsFinder fills two Decl and MacroInfos vectors instead of 
giving out Location objects
Removed constructors for structs MarkedString and Hover
Moved code modifying SourceRange for hover into getHover()


https://reviews.llvm.org/D35894

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/MyClass.cpp
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  clangd/impl.cpp
  test/clangd/hover.test
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -5,6 +5,7 @@
 Content-Length: 143
 
 {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootUri":"file:///path/to/workspace","capabilities":{},"trace":"off"}}
+
 #  CHECK:  "id": 0,
 # CHECK-NEXT:  "jsonrpc": "2.0",
 # CHECK-NEXT:  "result": {
@@ -30,6 +31,7 @@
 # CHECK-NEXT:  "clangd.applyFix"
 # CHECK-NEXT:]
 # CHECK-NEXT:  },
+# CHECK-NEXT:	   "hoverProvider": true,
 # CHECK-NEXT:  "renameProvider": true,
 # CHECK-NEXT:  "signatureHelpProvider": {
 # CHECK-NEXT:"triggerCharacters": [
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -30,6 +30,7 @@
 # CHECK-NEXT:  "clangd.applyFix"
 # CHECK-NEXT:]
 # CHECK-NEXT:  },
+# CHECK-NEXT:	   "hoverProvider": true,
 # CHECK-NEXT:  "renameProvider": true,
 # CHECK-NEXT:  "signatureHelpProvider": {
 # CHECK-NEXT:"triggerCharacters": [
@@ -40,6 +41,7 @@
 # CHECK-NEXT:  "textDocumentSync": 1
 # CHECK-NEXT:}
 # CHECK-NEXT:  }
+
 Content-Length: 44
 
 {"jsonrpc":"2.0","id":3,"method":"shutdown"}
Index: test/clangd/hover.test
===
--- /dev/null
+++ test/clangd/hover.test
@@ -0,0 +1,52 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 407
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#define MACRO 1\nnamespace ns1 {\nint test = 5;\nstruct MyClass {\nint xasd;\nvoid anotherOperation() {\n}\nstatic int foo(MyClass*) {\nreturn 0;\n}\n\n};}\nint main() {\nint a;\na;\nint b = ns1::test;\nns1::MyClass* Params;\nParams->anotherOperation();\nMACRO;}\n"}}}
+
+Content-Length: 144
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":0,"character":12}}}
+# Go to local variable
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"#define MACRO 1"}],"range":{"end":{"character":15,"line":0},"start":{"character":8,"line":0
+
+Content-Length: 144
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":14,"character":1}}}
+# Go to local variable
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"int a"}],"range":{"end":{"character":5,"line":13},"start":{"character":0,"line":13
+
+Content-Length: 145
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":15,"character":15}}}
+# Go to local variable
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"In ns1"},{"language":"C++","value":"int test = 5"}],"range":{"end":{"character":12,"line":2},"start":{"character":0,"line":2
+
+Content-Length: 145
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":16,"character":10}}}
+# Go to local variable
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"In ns1"},{"language":"C++","value":"struct MyClass {"}],"range":{"end":{"character":16,"line":3},"start":{"character":0,"line":3
+
+Content-Length: 145
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":17,"character":13}}}
+# Go to local variable
+# CHECK: {"id":1,"jsonrpc":"2.0","result":{"contents":[{"language":"C++","value":"In 

[PATCH] D35894: [clangd] Code hover for Clangd

2017-11-17 Thread William Enright via Phabricator via cfe-commits
Nebiroth marked 6 inline comments as done.
Nebiroth added inline comments.



Comment at: clangd/ClangdUnit.cpp:981
+}
+
 if (isSearchedLocation(FID, Offset)) {

malaperle wrote:
> I think we need to do a check that the computed SourceRange is valid 
> (isValid) in case we get it wrong. Otherwise, it might not go well later when 
> we use the SourceLocation to convert to lines, etc.
Do we just output a default Range values when SR isn't valid?


https://reviews.llvm.org/D35894



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D35894: [clangd] Code hover for Clangd

2017-11-17 Thread William Enright via Phabricator via cfe-commits
Nebiroth marked 25 inline comments as done.
Nebiroth added inline comments.



Comment at: clangd/ClangdServer.cpp:360
+
+  auto FileContents = DraftMgr.getDraft(File);
+  assert(FileContents.Draft &&

malaperle wrote:
> Why are you adding this? Is this coming from another commit?
> It looks like it makes tests fail:
> <-- 
> {"jsonrpc":"2.0","id":2,"method":"textDocument/definition","params":{"textDocument":{"uri":"file:///doesnotexist.cpp"},"position":{"line":4,"character":7}}}
> clangd: ../tools/clang/tools/extra/clangd/ClangdServer.cpp:362: 
> llvm::Expected  const clang::Decl*> > > > 
> clang::clangd::ClangdServer::findDefinitions(clang::clangd::PathRef, 
> clang::clangd::Position): Assertion `FileContents.Draft && "findDefinitions 
> is called for non-added document"' failed.
> /home/emalape/git/llvm/tools/clang/tools/extra/test/clangd/definitions.test:169:10:
>  error: expected string not found in input
> 
Accidental addition.



Comment at: clangd/ClangdServer.h:281
   /// Get definition of symbol at a specified \p Line and \p Column in \p File.
-  llvm::Expected> findDefinitions(PathRef File,
+  llvm::Expected malaperle wrote:
> > Location can be deduced from Decl*. I don't think this should be a pair. I 
> > also think we need a more general finder that just gets either the Decl* or 
> > MacroDef* at the "cursor". I think CXCursor does something similar in that 
> > it stores either Decl* or MacroDef*. I'm not sure it would be worth moving 
> > CXCursor from libclang but perhaps something stripped down for Clangd would 
> > be OK. This new finder will be able to be reused by findDefinition, 
> > highlights, hover, references and more.
> > We can make one patch that refactors the existing code so that 
> > findDefinitions uses this new finder class.
> We should not return `Decl*` from `ClangdServer::findDefinitions`, it's an 
> internal clang object (there are many other reasons why it's bad). 
> 
> It's ok the change the `findDefinitions` helper function inside 
> `ClangdUnit.cpp`, though. Please change it instead.
> 
> As for the `CXCursor`, I think the simplest approach would be to return two 
> vectors (`vector` and `vector`). I think clangd would 
> eventually get its own `CXCursor`-like things, possible reusing code or 
> wrapping CXCursor. But for now let's keep things simple.
We would have to handle MacroDef occurrences for this to work first. In other 
words, we would have to implement handleMacroDefOccurence in a similar way to 
handleDeclOccurence in DeclarationLocationsFinder. The document highlights 
feature suffers from the exact same problem. I'm planning on working on this 
feature in the near future.



Comment at: clangd/ClangdUnit.cpp:941
+
+// Keep default value.
+SourceRange SR = D->getSourceRange();

malaperle wrote:
> This code doesn't belong here. The hover feature and "find definition" do not 
> need the same range. The hover basically wants everything up to the first 
> left brace but "find definitions" wants everything up to the closing brace. 
> So having this code here will make "find definition" less correct.
Agreed, I'll revert the code to normal here and move this patch's code to 
getHover().


https://reviews.llvm.org/D35894



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39571: [clangd] DidChangeConfiguration Notification

2017-11-15 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 123069.
Nebiroth marked 3 inline comments as done.
Nebiroth added a comment.

Added test for didChangeConfiguration notification.
Compilation database and extra file flags are now properly reloaded when 
changing database path.
ClangdConfigurationParams now used instead of map.
changeConfiguration removed from ClangdServer. This class will now handle more 
specific settings.
Added more checks when parsing notification from client..


https://reviews.llvm.org/D39571

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/DraftStore.cpp
  clangd/DraftStore.h
  clangd/GlobalCompilationDatabase.cpp
  clangd/GlobalCompilationDatabase.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/did-change-configuration.test
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -1,3 +1,4 @@
+
 # RUN: clangd -pretty -run-synchronously < %s | FileCheck -strict-whitespace %s
 # It is absolutely vital that this file has CRLF line endings.
 #
@@ -18,6 +19,7 @@
 # CHECK-NEXT:  ":"
 # CHECK-NEXT:]
 # CHECK-NEXT:  },
+# CHECK-NEXT:	   "configurationChangeProvider": true,
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
@@ -48,4 +50,4 @@
 # CHECK-NEXT:  "result": null
 Content-Length: 33
 
-{"jsonrpc":"2.0":"method":"exit"}
+{"jsonrpc":"2.0":"method":"exit"}
\ No newline at end of file
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -1,3 +1,4 @@
+
 # RUN: clangd -pretty -run-synchronously < %s | FileCheck -strict-whitespace %s
 # It is absolutely vital that this file has CRLF line endings.
 #
@@ -18,6 +19,7 @@
 # CHECK-NEXT:  ":"
 # CHECK-NEXT:]
 # CHECK-NEXT:  },
+# CHECK-NEXT:	   "configurationChangeProvider": true,
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
@@ -45,4 +47,4 @@
 {"jsonrpc":"2.0","id":3,"method":"shutdown"}
 Content-Length: 33
 
-{"jsonrpc":"2.0":"method":"exit"}
+{"jsonrpc":"2.0":"method":"exit"}
\ No newline at end of file
Index: test/clangd/did-change-configuration.test
===
--- /dev/null
+++ test/clangd/did-change-configuration.test
@@ -0,0 +1,46 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 150
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///foo.c","languageId":"c","version":1,"text":"voidmain(){}"}}}
+
+Content-Length: 86
+
+{"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":""}}
+#Failed to decode workspace/didChangeConfiguration request.
+#Incorrect mapping node
+
+Content-Length: 114
+
+{"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{"compilationDatabasePath":{
+#Failed to decode workspace/didChangeConfiguration request.
+#compilationDatabasePath is not a scalar node
+
+Content-Length: 140
+
+{"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{"compilationDatabasePath":"/","testBadValue":"foo1234"}}}
+#Ignored unknown field "testBadValue"
+#Failed to find compilation database for / in overriden directory /
+#Bad field, bad compilation database
+
+Content-Length: 722
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///compile_commands.json","languageId":"json","version":1,"text":"[\n{\n"directory":"/",\n"command":"/usr/bin/c++-DGTEST_HAS_RTTI=0-D_GNU_SOURCE-D__STDC_CONSTANT_MACROS-D__STDC_FORMAT_MACROS-D__STDC_LIMIT_MACROS-Ilib/Demangle-I../lib/Demangle-I/usr/include/libxml2-Iinclude-I../include-fPIC-fvisibility-inlines-hidden-Werror=date-time-std=c++11-Wall-W-Wno-unused-parameter-Wwrite-strings-Wcast-qual-Wno-missing-field-initializers-pedantic-Wno-long-long-Wno-maybe-uninitialized-Wdelete-non-virtual-dtor-Wno-comment-O0-g-fno-exceptions-fno-rtti-o/foo.c.o-c/foo.c",\n"file":"/foo.c"\n},"}}}
+
+Content-Length: 115
+
+{"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{"compilationDatabasePath":"/"}}}

[PATCH] D39571: [clangd] DidChangeConfiguration Notification

2017-11-14 Thread William Enright via Phabricator via cfe-commits
Nebiroth marked 18 inline comments as done.
Nebiroth added inline comments.



Comment at: clangd/Protocol.h:285
+
+  DidChangeConfigurationParams() {}
+

malaperle wrote:
> I don't think you need this constructor?
I do inside parse() for DidChangeConfigurationParams.


https://reviews.llvm.org/D39571



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38425: [clangd] Document highlights for clangd

2017-11-10 Thread William Enright via Phabricator via cfe-commits
Nebiroth added a comment.

This updated patch still does not handle highlighting macro references 
correctly. I will make another patch at a later time for this issue.

In https://reviews.llvm.org/D38425#922408, @ioeric wrote:

> Drive-by comment: in general, have you considered reusing the existing 
> declarations and occurrences finding functionalities in clang-rename? AFAIK, 
> it deals with templates and macros pretty well.
>
> o 
> https://github.com/llvm-mirror/clang/blob/master/include/clang/Tooling/Refactoring/Rename/USRFinder.h
>  
>  o 
> https://github.com/llvm-mirror/clang/blob/master/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h


I'll take a look at it later. Thanks!


https://reviews.llvm.org/D38425



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38425: [clangd] Document highlights for clangd

2017-11-10 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 122529.
Nebiroth added a comment.

Decls and MacroInfos vectors are now private and passed by reference instead of 
copied.
DeclarationLocationsFinder does not store Locations anymore, instead the vector 
is filled in their respective methods in ClangdUnit.cpp
Refactored if condition
Removed redundant newlines at end of test file.


https://reviews.llvm.org/D38425

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/documenthighlight.test
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:	   "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:	   "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
@@ -40,6 +41,7 @@
 # CHECK-NEXT:  "textDocumentSync": 1
 # CHECK-NEXT:}
 # CHECK-NEXT:  }
+
 Content-Length: 44
 
 {"jsonrpc":"2.0","id":3,"method":"shutdown"}
Index: test/clangd/documenthighlight.test
===
--- /dev/null
+++ test/clangd/documenthighlight.test
@@ -0,0 +1,37 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 455
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#define MACRO 1\nnamespace ns1 {\nstruct MyClass {\nint xasd;\nvoid anotherOperation() {\n}\nstatic int foo(MyClass*) {\nreturn 0;\n}\n\n};\nstruct Foo {\nint xasd;\n};\n}\nint main() {\nint bonjour;\nbonjour = 2;\nns1::Foo bar = { xasd : 1};\nbar.xasd = 3;\nns1::MyClass* Params;\nParams->anotherOperation();}\n"}}}
+
+Content-Length: 156
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":17,"character":2}}}
+# Go to local variable
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":12,"line":16},"start":{"character":4,"line":16}}},{"kind":0,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}}]}
+
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":18,"character":17}}}
+# Go to local variable
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":9,"line":12},"start":{"character":4,"line":12}}},{"kind":1,"range":{"end":{"character":21,"line":18},"start":{"character":17,"line":18}}},{"kind":216,"range":{"end":{"character":21,"line":18},"start":{"character":17,"line":18}}},{"kind":220,"range":{"end":{"character":8,"line":19},"start":{"character":4,"line":19}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":21,"character":10}}}
+# Go to local variable
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":22,"line":4},"start":{"character":5,"line":4}}},{"kind":0,"range":{"end":{"character":25,"line":21},"start":{"character":8,"line":21}}}]}
+
+Content-Length: 48
+
+{"jsonrpc":"2.0","id":1,"method":"shutdown"}
+
+Content-Length: 33
+
+{"jsonrpc":"2.0":"method":"exit"}			
\ No newline at end of file
Index: clangd/ProtocolHandlers.h
===
--- clangd/ProtocolHandlers.h
+++ clangd/ProtocolHandlers.h
@@ -31,7 +31,6 @@
 public:
   using Ctx = RequestContext;
   virtual ~ProtocolCallbacks() = default;
-
   virtual void onInitialize(Ctx C, InitializeParams ) = 0;
   virtual void onShutdown(Ctx C, 

[PATCH] D38425: [clangd] Document highlights for clangd

2017-11-10 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 122528.
Nebiroth added a comment.

- Decls and MacroInfos vectors are now private and passed by reference instead 
of copied.


https://reviews.llvm.org/D38425

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/documenthighlight.test
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:	   "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -20,6 +20,7 @@
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
+# CHECK-NEXT:	   "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
@@ -40,6 +41,7 @@
 # CHECK-NEXT:  "textDocumentSync": 1
 # CHECK-NEXT:}
 # CHECK-NEXT:  }
+
 Content-Length: 44
 
 {"jsonrpc":"2.0","id":3,"method":"shutdown"}
Index: test/clangd/documenthighlight.test
===
--- /dev/null
+++ test/clangd/documenthighlight.test
@@ -0,0 +1,37 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 455
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#define MACRO 1\nnamespace ns1 {\nstruct MyClass {\nint xasd;\nvoid anotherOperation() {\n}\nstatic int foo(MyClass*) {\nreturn 0;\n}\n\n};\nstruct Foo {\nint xasd;\n};\n}\nint main() {\nint bonjour;\nbonjour = 2;\nns1::Foo bar = { xasd : 1};\nbar.xasd = 3;\nns1::MyClass* Params;\nParams->anotherOperation();}\n"}}}
+
+Content-Length: 156
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":17,"character":2}}}
+# Go to local variable
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":12,"line":16},"start":{"character":4,"line":16}}},{"kind":0,"range":{"end":{"character":7,"line":17},"start":{"character":0,"line":17}}}]}
+
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":18,"character":17}}}
+# Go to local variable
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":9,"line":12},"start":{"character":4,"line":12}}},{"kind":1,"range":{"end":{"character":21,"line":18},"start":{"character":17,"line":18}}},{"kind":216,"range":{"end":{"character":21,"line":18},"start":{"character":17,"line":18}}},{"kind":220,"range":{"end":{"character":8,"line":19},"start":{"character":4,"line":19}}}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":21,"character":10}}}
+# Go to local variable
+# CHECK: {"id":1,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":22,"line":4},"start":{"character":5,"line":4}}},{"kind":0,"range":{"end":{"character":25,"line":21},"start":{"character":8,"line":21}}}]}
+
+Content-Length: 48
+
+{"jsonrpc":"2.0","id":1,"method":"shutdown"}
+
+Content-Length: 33
+
+{"jsonrpc":"2.0":"method":"exit"}			
\ No newline at end of file
Index: clangd/ProtocolHandlers.h
===
--- clangd/ProtocolHandlers.h
+++ clangd/ProtocolHandlers.h
@@ -31,7 +31,6 @@
 public:
   using Ctx = RequestContext;
   virtual ~ProtocolCallbacks() = default;
-
   virtual void onInitialize(Ctx C, InitializeParams ) = 0;
   virtual void onShutdown(Ctx C, ShutdownParams ) = 0;
   virtual void onExit(Ctx C, ExitParams ) = 0;
@@ -54,6 +53,8 @@
   virtual void onFileEvent(Ctx C, DidChangeWatchedFilesParams ) = 0;
   virtual void onCommand(Ctx C, 

[PATCH] D39571: [clangd] DidChangeConfiguration Notification

2017-11-08 Thread William Enright via Phabricator via cfe-commits
Nebiroth added inline comments.



Comment at: clangd/ClangdLSPServer.cpp:51
+  "definitionProvider": true,
+  "configurationChangeProvider": true
 }})");

malaperle wrote:
> Are you sure the existing tests don't fail? usually when we change this, some 
> tests have to be adjusted.
I'll verify this when I will have the time.



Comment at: clangd/ClangdServer.h:289
+  /// ChangedSettings
+  void changeConfiguration(std::map ChangedSettings);
+

ilya-biryukov wrote:
> This function is way too general for `ClangdServer`'s interface, can we have 
> more fine-grained settings here (i.e. `setCompletionParameters` etc?) and 
> handle the "general" case in `ClangdLSPServer` (i.e., unknown setting names, 
> invalid setting parameters, json parsing, etc.)?
> 
> I suggest we remove this function altogether.
So if I understand correctly, we would have the most generic 
workspace/didChangeConfiguration handler located in ClangdLSPServer
 with a name perhaps similar to  changeConfiguration  that would pass valid 
settings to more specific functions inside ClangdServer ?



Comment at: clangd/Protocol.cpp:534
 
+llvm::Optional
+DidChangeConfigurationParams::parse(llvm::yaml::MappingNode *Params,

malaperle wrote:
> I think this needs a test, perhaps create did-change-configuration.test? It 
> can also test the ClangdConfigurationParams::parse code
> If you do, I think it's a good idea to test a few failing cases:
> - "settings" is not a mapping node. You can test this with a scalar node like 
> "settings": ""
> - Something else than "settings" is present, so that it goes through 
> logIgnoredField
> - "settings" is not set at all. In this case, because it's mandatory in the 
> protocol, return llvm::None. This can be checked after the loop after all 
> key/values were read.
> 
> There are similar tests in execute-command.test if you'd like an example.
> And of course also add a "successful" case as well  :)
Yes, I was planning on adding a simple test in the coming days. I imagine this 
test will be greatly expanded on once more settings become available to change 
on the server side.


https://reviews.llvm.org/D39571



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39571: [clangd] DidChangeConfiguration Notification

2017-11-02 Thread William Enright via Phabricator via cfe-commits
Nebiroth created this revision.

Implementation of DidChangeConfiguration notification handling in clangd.
This currently only supports changing one setting: the path of the compilation 
database to be used for the current project
In other words, it is no longer necessary to restart clangd with a different 
command line argument in order to change
the compilation database.


https://reviews.llvm.org/D39571

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/GlobalCompilationDatabase.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h

Index: clangd/ProtocolHandlers.h
===
--- clangd/ProtocolHandlers.h
+++ clangd/ProtocolHandlers.h
@@ -52,6 +52,8 @@
   virtual void onGoToDefinition(Ctx C, TextDocumentPositionParams ) = 0;
   virtual void onSwitchSourceHeader(Ctx C, TextDocumentIdentifier ) = 0;
   virtual void onFileEvent(Ctx C, DidChangeWatchedFilesParams ) = 0;
+  virtual void onChangeConfiguration(Ctx C,
+ DidChangeConfigurationParams ) = 0;
 };
 
 void registerCallbackHandlers(JSONRPCDispatcher , JSONOutput ,
Index: clangd/ProtocolHandlers.cpp
===
--- clangd/ProtocolHandlers.cpp
+++ clangd/ProtocolHandlers.cpp
@@ -72,4 +72,6 @@
   Register("textDocument/switchSourceHeader",
::onSwitchSourceHeader);
   Register("workspace/didChangeWatchedFiles", ::onFileEvent);
+  Register("workspace/didChangeConfiguration",
+   ::onChangeConfiguration);
 }
Index: clangd/Protocol.h
===
--- clangd/Protocol.h
+++ clangd/Protocol.h
@@ -273,6 +273,27 @@
   parse(llvm::yaml::MappingNode *Params, clangd::Logger );
 };
 
+struct ClangdConfigurationParams {
+
+  llvm::Optional compilationDatabasePath;
+  static llvm::Optional
+  parse(llvm::yaml::MappingNode *Params, clangd::Logger );
+};
+
+struct DidChangeConfigurationParams {
+
+  DidChangeConfigurationParams() {}
+
+  DidChangeConfigurationParams(ClangdConfigurationParams settings)
+  : settings(settings) {}
+
+  ClangdConfigurationParams settings;
+
+  static llvm::Optional
+  parse(llvm::yaml::MappingNode *Params, clangd::Logger );
+  static std::string unparse(const DidChangeConfigurationParams );
+};
+
 struct FormattingOptions {
   /// Size of a tab in spaces.
   int tabSize;
Index: clangd/Protocol.cpp
===
--- clangd/Protocol.cpp
+++ clangd/Protocol.cpp
@@ -531,6 +531,59 @@
   return Result;
 }
 
+llvm::Optional
+DidChangeConfigurationParams::parse(llvm::yaml::MappingNode *Params,
+clangd::Logger ) {
+  DidChangeConfigurationParams Result;
+  for (auto  : *Params) {
+auto *KeyString = dyn_cast(NextKeyValue.getKey());
+if (!KeyString)
+  return llvm::None;
+
+llvm::SmallString<10> KeyStorage;
+StringRef KeyValue = KeyString->getValue(KeyStorage);
+auto *Value =
+dyn_cast_or_null(NextKeyValue.getValue());
+if (!Value)
+  return llvm::None;
+
+llvm::SmallString<10> Storage;
+if (KeyValue == "settings") {
+  auto Parsed = ClangdConfigurationParams::parse(Value, Logger);
+  if (!Parsed)
+return llvm::None;
+  Result.settings = Parsed.getValue();
+} else {
+  logIgnoredField(KeyValue, Logger);
+}
+  }
+
+  return Result;
+}
+
+llvm::Optional
+ClangdConfigurationParams::parse(llvm::yaml::MappingNode *Params,
+ clangd::Logger ) {
+  ClangdConfigurationParams Result;
+  for (auto  : *Params) {
+auto *KeyString = dyn_cast(NextKeyValue.getKey());
+if (!KeyString)
+  return llvm::None;
+
+llvm::SmallString<10> KeyStorage;
+StringRef KeyValue = KeyString->getValue(KeyStorage);
+auto *Value =
+dyn_cast_or_null(NextKeyValue.getValue());
+if (!Value)
+  return llvm::None;
+
+if (KeyValue == "compilationDatabasePath") {
+  Result.compilationDatabasePath = Value->getValue(KeyStorage);
+}
+  }
+  return Result;
+}
+
 llvm::Optional
 TextDocumentContentChangeEvent::parse(llvm::yaml::MappingNode *Params,
   clangd::Logger ) {
Index: clangd/GlobalCompilationDatabase.h
===
--- clangd/GlobalCompilationDatabase.h
+++ clangd/GlobalCompilationDatabase.h
@@ -52,11 +52,14 @@
 
   std::vector
   getCompileCommands(PathRef File) override;
+  llvm::Optional getCompileCommandsDir() { return CompileCommandsDir; }
+  void setCompileCommandsDir(Path P) { CompileCommandsDir = P; }
+
+  tooling::CompilationDatabase *getCompilationDatabase(PathRef File);
 
   void setExtraFlagsForFile(PathRef File, std::vector ExtraFlags);
 
 private:
-  tooling::CompilationDatabase 

[PATCH] D35894: [clangd] Code hover for Clangd

2017-10-30 Thread William Enright via Phabricator via cfe-commits
Nebiroth added a comment.

I also have a quick patch that supports displaying comments preceding the 
declaration of a function. Once the review comments have been addressed for 
this revision I will submit it.


https://reviews.llvm.org/D35894



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D35894: [clangd] Code hover for Clangd

2017-10-30 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 120894.
Nebiroth added a comment.

Code hover now displays declaration of symbol instead of source code by default.
Code hover now displays context information such as namespace and class name.
Array of MarkedString objects is now sent as response in JSON.


https://reviews.llvm.org/D35894

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/hover.test
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -5,16 +5,17 @@
 Content-Length: 143
 
 {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootUri":"file:///path/to/workspace","capabilities":{},"trace":"off"}}
-# CHECK: Content-Length: 535
+# CHECK: Content-Length: 568
 # CHECK: {"jsonrpc":"2.0","id":0,"result":{"capabilities":{
 # CHECK:   "textDocumentSync": 1,
 # CHECK:   "documentFormattingProvider": true,
 # CHECK:   "documentRangeFormattingProvider": true,
 # CHECK:   "documentOnTypeFormattingProvider": {"firstTriggerCharacter":"}","moreTriggerCharacter":[]},
 # CHECK:   "codeActionProvider": true,
 # CHECK:   "completionProvider": {"resolveProvider": false, "triggerCharacters": [".",">",":"]},
 # CHECK:   "signatureHelpProvider": {"triggerCharacters": ["(",","]},
-# CHECK:   "definitionProvider": true
+# CHECK:   "definitionProvider": true,
+# CHECK:   "hoverProvider": true
 # CHECK: }}}
 #
 Content-Length: 44
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -5,16 +5,17 @@
 Content-Length: 142
 
 {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":"","rootUri":"file:///path/to/workspace","capabilities":{},"trace":"off"}}
-# CHECK: Content-Length: 535
+# CHECK: Content-Length: 568
 # CHECK: {"jsonrpc":"2.0","id":0,"result":{"capabilities":{
 # CHECK:   "textDocumentSync": 1,
 # CHECK:   "documentFormattingProvider": true,
 # CHECK:   "documentRangeFormattingProvider": true,
 # CHECK:   "documentOnTypeFormattingProvider": {"firstTriggerCharacter":"}","moreTriggerCharacter":[]},
 # CHECK:   "codeActionProvider": true,
 # CHECK:   "completionProvider": {"resolveProvider": false, "triggerCharacters": [".",">",":"]},
 # CHECK:   "signatureHelpProvider": {"triggerCharacters": ["(",","]},
-# CHECK:   "definitionProvider": true
+# CHECK:   "definitionProvider": true,
+# CHECK:   "hoverProvider": true
 # CHECK: }}}
 #
 Content-Length: 44
Index: test/clangd/hover.test
===
--- /dev/null
+++ test/clangd/hover.test
@@ -0,0 +1,52 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 407
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#define MACRO 1\nnamespace ns1 {\nint test = 5;\nstruct MyClass {\nint xasd;\nvoid anotherOperation() {\n}\nstatic int foo(MyClass*) {\nreturn 0;\n}\n\n};}\nint main() {\nint a;\na;\nint b = ns1::test;\nns1::MyClass* Params;\nParams->anotherOperation();\nMACRO;}\n"}}}
+
+Content-Length: 144
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":0,"character":12}}}
+# Go to local variable
+# CHECK: {"jsonrpc":"2.0","id":1,"result":{"contents": ["#define statement",{"language": "C++", "value": "MACRO 1"}], "range": {"start": {"line": 0, "character": 8}, "end": {"line": 0, "character": 15
+
+Content-Length: 144
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":14,"character":1}}}
+# Go to local variable
+# CHECK: {"jsonrpc":"2.0","id":1,"result":{"contents": [{"language": "C++", "value": "int a"}], "range": {"start": {"line": 13, "character": 0}, "end": {"line": 13, "character": 5
+
+Content-Length: 145
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":15,"character":15}}}
+# Go to local variable
+# CHECK: {"jsonrpc":"2.0","id":1,"result":{"contents": ["In namespace named ns1",{"language": "C++", "value": "int test = 5"}], "range": {"start": {"line": 2, "character": 0}, "end": {"line": 2, "character": 12
+
+Content-Length: 145
+

[PATCH] D39375: [clang] Add PPCallbacks list to preprocessor when building a preacompiled preamble.

2017-10-27 Thread William Enright via Phabricator via cfe-commits
Nebiroth created this revision.

Revision https://reviews.llvm.org/D38639 needs this commit in order to properly 
make open definition calls on include statements work.
Since this modifies clang and not clangd, I decided to include it in a 
different patch.


https://reviews.llvm.org/D39375

Files:
  include/clang/Frontend/PrecompiledPreamble.h
  lib/Frontend/ASTUnit.cpp
  lib/Frontend/PrecompiledPreamble.cpp

Index: lib/Frontend/PrecompiledPreamble.cpp
===
--- lib/Frontend/PrecompiledPreamble.cpp
+++ lib/Frontend/PrecompiledPreamble.cpp
@@ -203,7 +203,7 @@
 const llvm::MemoryBuffer *MainFileBuffer, PreambleBounds Bounds,
 DiagnosticsEngine , IntrusiveRefCntPtr VFS,
 std::shared_ptr PCHContainerOps,
-PreambleCallbacks ) {
+PreambleCallbacks , std::unique_ptr PPCallbacks) {
   assert(VFS && "VFS is null");
 
   if (!Bounds.Size)
@@ -307,6 +307,7 @@
   if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0]))
 return BuildPreambleError::BeginSourceFileFailed;
 
+  Clang->getPreprocessor().addPPCallbacks(std::move(PPCallbacks));
   Act->Execute();
 
   // Run the callbacks.
Index: lib/Frontend/ASTUnit.cpp
===
--- lib/Frontend/ASTUnit.cpp
+++ lib/Frontend/ASTUnit.cpp
@@ -53,54 +53,52 @@
 using llvm::TimeRecord;
 
 namespace {
-  class SimpleTimer {
-bool WantTiming;
-TimeRecord Start;
-std::string Output;
-
-  public:
-explicit SimpleTimer(bool WantTiming) : WantTiming(WantTiming) {
-  if (WantTiming)
-Start = TimeRecord::getCurrentTime();
-}
-
-void setOutput(const Twine ) {
-  if (WantTiming)
-this->Output = Output.str();
-}
-
-~SimpleTimer() {
-  if (WantTiming) {
-TimeRecord Elapsed = TimeRecord::getCurrentTime();
-Elapsed -= Start;
-llvm::errs() << Output << ':';
-Elapsed.print(Elapsed, llvm::errs());
-llvm::errs() << '\n';
-  }
-}
-  };
+class SimpleTimer {
+  bool WantTiming;
+  TimeRecord Start;
+  std::string Output;
 
-  template 
-  std::unique_ptr valueOrNull(llvm::ErrorOr Val) {
-if (!Val)
-  return nullptr;
-return std::move(*Val);
+public:
+  explicit SimpleTimer(bool WantTiming) : WantTiming(WantTiming) {
+if (WantTiming)
+  Start = TimeRecord::getCurrentTime();
+  }
+
+  void setOutput(const Twine ) {
+if (WantTiming)
+  this->Output = Output.str();
+  }
+
+  ~SimpleTimer() {
+if (WantTiming) {
+  TimeRecord Elapsed = TimeRecord::getCurrentTime();
+  Elapsed -= Start;
+  llvm::errs() << Output << ':';
+  Elapsed.print(Elapsed, llvm::errs());
+  llvm::errs() << '\n';
+}
   }
+};
 
-  template 
-  bool moveOnNoError(llvm::ErrorOr Val, T ) {
-if (!Val)
-  return false;
-Output = std::move(*Val);
-return true;
-  }
+template 
+std::unique_ptr valueOrNull(llvm::ErrorOr Val) {
+  if (!Val)
+return nullptr;
+  return std::move(*Val);
+}
+
+template  bool moveOnNoError(llvm::ErrorOr Val, T ) {
+  if (!Val)
+return false;
+  Output = std::move(*Val);
+  return true;
+}
 
 /// \brief Get a source buffer for \p MainFilePath, handling all file-to-file
 /// and file-to-buffer remappings inside \p Invocation.
 static std::unique_ptr
 getBufferForFileHandlingRemapping(const CompilerInvocation ,
-  vfs::FileSystem *VFS,
-  StringRef FilePath) {
+  vfs::FileSystem *VFS, StringRef FilePath) {
   const auto  = Invocation.getPreprocessorOpts();
 
   // Try to determine if the main file has been remapped, either from the
@@ -156,7 +154,7 @@
 return nullptr;
   return llvm::MemoryBuffer::getMemBufferCopy(Buffer->getBuffer(), FilePath);
 }
-}
+} // namespace
 
 struct ASTUnit::ASTWriterData {
   SmallString<128> Buffer;
@@ -167,9 +165,7 @@
   : Stream(Buffer), Writer(Stream, Buffer, PCMCache, {}) {}
 };
 
-void ASTUnit::clearFileLevelDecls() {
-  llvm::DeleteContainerSeconds(FileDecls);
-}
+void ASTUnit::clearFileLevelDecls() { llvm::DeleteContainerSeconds(FileDecls); }
 
 /// \brief After failing to build a precompiled preamble (due to
 /// errors in the source that occurs in the preamble), the number of
@@ -183,20 +179,15 @@
 static std::atomic ActiveASTUnitObjects;
 
 ASTUnit::ASTUnit(bool _MainFileIsAST)
-  : Reader(nullptr), HadModuleLoaderFatalFailure(false),
-OnlyLocalDecls(false), CaptureDiagnostics(false),
-MainFileIsAST(_MainFileIsAST), 
-TUKind(TU_Complete), WantTiming(getenv("LIBCLANG_TIMING")),
-OwnsRemappedFileBuffers(true),
-NumStoredDiagnosticsFromDriver(0),
-PreambleRebuildCounter(0),
-NumWarningsInPreamble(0),
-ShouldCacheCodeCompletionResults(false),
-IncludeBriefCommentsInCodeCompletion(false), UserFilesAreVolatile(false),
-CompletionCacheTopLevelHashValue(0),
-

[PATCH] D38639: [clangd] #include statements support for Open definition

2017-10-26 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 120485.
Nebiroth added a comment.

- Fixed adding incorrect test file.


https://reviews.llvm.org/D38639

Files:
  clangd/ClangdServer.cpp
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/GlobalCompilationDatabase.cpp
  clangd/Protocol.h
  unittests/clangd/ClangdTests.cpp

Index: unittests/clangd/ClangdTests.cpp
===
--- unittests/clangd/ClangdTests.cpp
+++ unittests/clangd/ClangdTests.cpp
@@ -7,7 +7,6 @@
 //
 //===--===//
 
-#include "ClangdLSPServer.h"
 #include "ClangdServer.h"
 #include "Logger.h"
 #include "clang/Basic/VirtualFileSystem.h"
@@ -1056,7 +1055,7 @@
 AddDocument(FileIndex);
 
   Position Pos{LineDist(RandGen), ColumnDist(RandGen)};
-  ASSERT_TRUE(!!Server.findDefinitions(FilePaths[FileIndex], Pos));
+  Server.findDefinitions(FilePaths[FileIndex], Pos);
 };
 
 std::vector> AsyncRequests = {
@@ -1185,6 +1184,57 @@
   EXPECT_FALSE(PathResult.hasValue());
 }
 
+TEST_F(ClangdVFSTest, CheckDefinitionIncludes) {
+  MockFSProvider FS;
+  ErrorCheckingDiagConsumer DiagConsumer;
+  MockCompilationDatabase CDB(/*AddFreestandingFlag=*/true);
+
+  ClangdServer Server(CDB, DiagConsumer, FS, 0, clangd::CodeCompleteOptions(),
+  EmptyLogger::getInstance());
+
+  auto FooCpp = getVirtualTestFilePath("foo.cpp");
+  const auto SourceContents = R"cpp(
+  #include "foo.h"
+  #include "invalid.h"
+  int b = a;
+  )cpp";
+  FS.Files[FooCpp] = SourceContents;
+  auto FooH = getVirtualTestFilePath("foo.h");
+  const auto HeaderContents = "int a;";
+
+  FS.Files[FooCpp] = SourceContents;
+  FS.Files[FooH] = HeaderContents;
+
+  Server.addDocument(FooH, HeaderContents);
+  Server.addDocument(FooCpp, SourceContents);
+
+  Position P = Position{1, 11};
+
+  std::vector Locations = Server.findDefinitions(FooCpp, P).get().Value;
+  EXPECT_TRUE(!Locations.empty());
+  std::string s("file:///");
+  std::string check = URI::unparse(Locations[0].uri);
+  check = check.erase(0, s.size());
+  check = check.substr(0, check.size() - 1);
+  ASSERT_EQ(check, FooH);
+  ASSERT_EQ(Locations[0].range.start.line, 0);
+  ASSERT_EQ(Locations[0].range.start.character, 0);
+  ASSERT_EQ(Locations[0].range.end.line, 0);
+  ASSERT_EQ(Locations[0].range.end.character, 0);
+
+  // Test ctrl-clicking on the #include part on the statement
+  Position P3 = Position{1, 3};
+
+  Locations = Server.findDefinitions(FooCpp, P3).get().Value;
+  EXPECT_TRUE(!Locations.empty());
+
+  // Test invalid include
+  Position P2 = Position{2, 11};
+
+  Locations = Server.findDefinitions(FooCpp, P2).get().Value;
+  EXPECT_TRUE(Locations.empty());
+}
+
 TEST_F(ClangdThreadingTest, NoConcurrentDiagnostics) {
   class NoConcurrentAccessDiagConsumer : public DiagnosticsConsumer {
   public:
Index: clangd/Protocol.h
===
--- clangd/Protocol.h
+++ clangd/Protocol.h
@@ -96,12 +96,21 @@
   friend bool operator<(const Range , const Range ) {
 return std::tie(LHS.start, LHS.end) < std::tie(RHS.start, RHS.end);
   }
-
   static llvm::Optional parse(llvm::yaml::MappingNode *Params,
  clangd::Logger );
   static std::string unparse(const Range );
+
+};
+
+class RangeHash {
+public:
+  std::size_t operator()(const Range ) const
+  {
+return ((R.start.line & 0x18) << 3) | ((R.start.character & 0x18) << 1) | ((R.end.line & 0x18) >> 1) | ((R.end.character & 0x18) >> 3);
+  }
 };
 
+
 struct Location {
   /// The text document's URI.
   URI uri;
Index: clangd/GlobalCompilationDatabase.cpp
===
--- clangd/GlobalCompilationDatabase.cpp
+++ clangd/GlobalCompilationDatabase.cpp
@@ -9,6 +9,7 @@
 
 #include "GlobalCompilationDatabase.h"
 #include "Logger.h"
+#include "ProtocolHandlers.h"
 #include "clang/Tooling/CompilationDatabase.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
@@ -30,6 +31,8 @@
   Command.CommandLine.insert(It, ExtraFlags.begin(), ExtraFlags.end());
 }
 
+
+
 tooling::CompileCommand getDefaultCompileCommand(PathRef File) {
   std::vector CommandLine{"clang", "-fsyntax-only", File.str()};
   return tooling::CompileCommand(llvm::sys::path::parent_path(File),
Index: clangd/ClangdUnit.h
===
--- clangd/ClangdUnit.h
+++ clangd/ClangdUnit.h
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 namespace llvm {
 class raw_ostream;
@@ -128,11 +129,17 @@
 struct PreambleData {
   PreambleData(PrecompiledPreamble Preamble,
std::vector TopLevelDeclIDs,
-   std::vector Diags);
+   std::vector Diags,
+   std::unordered_map IncludeMap,
+   std::vector> 

[PATCH] D38639: [clangd] #include statements support for Open definition

2017-10-26 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 120482.
Nebiroth added a comment.

- Now overriding InclusionDirective as a callback to get proper includes 
information.
- Fixed tests.


https://reviews.llvm.org/D38639

Files:
  clangd/ClangdServer.cpp
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/GlobalCompilationDatabase.cpp
  clangd/Protocol.h
  test/clangd/documenthighlight.test
  unittests/clangd/ClangdTests.cpp

Index: unittests/clangd/ClangdTests.cpp
===
--- unittests/clangd/ClangdTests.cpp
+++ unittests/clangd/ClangdTests.cpp
@@ -7,7 +7,6 @@
 //
 //===--===//
 
-#include "ClangdLSPServer.h"
 #include "ClangdServer.h"
 #include "Logger.h"
 #include "clang/Basic/VirtualFileSystem.h"
@@ -1056,7 +1055,7 @@
 AddDocument(FileIndex);
 
   Position Pos{LineDist(RandGen), ColumnDist(RandGen)};
-  ASSERT_TRUE(!!Server.findDefinitions(FilePaths[FileIndex], Pos));
+  Server.findDefinitions(FilePaths[FileIndex], Pos);
 };
 
 std::vector> AsyncRequests = {
@@ -1185,6 +1184,57 @@
   EXPECT_FALSE(PathResult.hasValue());
 }
 
+TEST_F(ClangdVFSTest, CheckDefinitionIncludes) {
+  MockFSProvider FS;
+  ErrorCheckingDiagConsumer DiagConsumer;
+  MockCompilationDatabase CDB(/*AddFreestandingFlag=*/true);
+
+  ClangdServer Server(CDB, DiagConsumer, FS, 0, clangd::CodeCompleteOptions(),
+  EmptyLogger::getInstance());
+
+  auto FooCpp = getVirtualTestFilePath("foo.cpp");
+  const auto SourceContents = R"cpp(
+  #include "foo.h"
+  #include "invalid.h"
+  int b = a;
+  )cpp";
+  FS.Files[FooCpp] = SourceContents;
+  auto FooH = getVirtualTestFilePath("foo.h");
+  const auto HeaderContents = "int a;";
+
+  FS.Files[FooCpp] = SourceContents;
+  FS.Files[FooH] = HeaderContents;
+
+  Server.addDocument(FooH, HeaderContents);
+  Server.addDocument(FooCpp, SourceContents);
+
+  Position P = Position{1, 11};
+
+  std::vector Locations = Server.findDefinitions(FooCpp, P).get().Value;
+  EXPECT_TRUE(!Locations.empty());
+  std::string s("file:///");
+  std::string check = URI::unparse(Locations[0].uri);
+  check = check.erase(0, s.size());
+  check = check.substr(0, check.size() - 1);
+  ASSERT_EQ(check, FooH);
+  ASSERT_EQ(Locations[0].range.start.line, 0);
+  ASSERT_EQ(Locations[0].range.start.character, 0);
+  ASSERT_EQ(Locations[0].range.end.line, 0);
+  ASSERT_EQ(Locations[0].range.end.character, 0);
+
+  // Test ctrl-clicking on the #include part on the statement
+  Position P3 = Position{1, 3};
+
+  Locations = Server.findDefinitions(FooCpp, P3).get().Value;
+  EXPECT_TRUE(!Locations.empty());
+
+  // Test invalid include
+  Position P2 = Position{2, 11};
+
+  Locations = Server.findDefinitions(FooCpp, P2).get().Value;
+  EXPECT_TRUE(Locations.empty());
+}
+
 TEST_F(ClangdThreadingTest, NoConcurrentDiagnostics) {
   class NoConcurrentAccessDiagConsumer : public DiagnosticsConsumer {
   public:
Index: test/clangd/documenthighlight.test
===
--- /dev/null
+++ test/clangd/documenthighlight.test
@@ -0,0 +1,42 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+# CHECK: Content-Length: 580
+# CHECK: {"jsonrpc":"2.0","id":0,"result":{"capabilities":{
+# CHECK:   "textDocumentSync": 1,
+# CHECK:   "documentFormattingProvider": true,
+# CHECK:   "documentRangeFormattingProvider": true,
+# CHECK:   "documentOnTypeFormattingProvider": {"firstTriggerCharacter":"}","moreTriggerCharacter":[]},
+# CHECK:   "codeActionProvider": true,
+# CHECK:   "completionProvider": {"resolveProvider": false, "triggerCharacters": [".",">",":"]},
+# CHECK:   "signatureHelpProvider": {"triggerCharacters": ["(",","]},
+# CHECK:   "definitionProvider": true,
+# CHECK:   "documentHighlightProvider": true
+# CHECK: }}}
+#
+
+Content-Length: 455
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#define MACRO 1\nnamespace ns1 {\nstruct MyClass {\nint xasd;\nvoid anotherOperation() {\n}\nstatic int foo(MyClass*) {\nreturn 0;\n}\n\n};\nstruct Foo {\nint xasd;\n};\n}\nint main() {\nint bonjour;\nbonjour = 2;\nns1::Foo bar = { xasd : 1};\nbar.xasd = 3;\nns1::MyClass* Params;\nParams->anotherOperation();}\n"}}}
+
+Content-Length: 156
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":17,"character":2}}}
+# Go to local variable
+# CHECK: {"jsonrpc":"2.0","id":1,"result":[{"range": {"start": {"line": 16, "character": 4}, "end": {"line": 16, "character": 12}}, "kind": 1},{"range": {"start": {"line": 17, 

[PATCH] D35894: [clangd] Code hover for Clangd

2017-10-23 Thread William Enright via Phabricator via cfe-commits
Nebiroth added a comment.

In https://reviews.llvm.org/D35894#903594, @ilya-biryukov wrote:

> In https://reviews.llvm.org/D35894#903552, @malaperle wrote:
>
> > I think he meant to have multiple sections in the hover, one C/C++ and one 
> > not. But we noticed you can have an array of MarkedString in Hover so it 
> > should be fine.
>
>
> I totally misunderstood the question. Good to know it all works without 
> changing the LSP.
>  Just to make sure I got it right this time: the use-case is to, e.g., return 
> both a code snippet (having `"language": cpp`) and a documentation string 
> (without `language`) as a result of hover request?


That's about it.

I'm sitting on a code hover patch that does more or less what you just 
described. One MarkedString with it's language field set to "C++" returns the 
appropriate code snippet for the code hover and another MarkedString with it's 
language field set to "markdown" returns the associated scope.


https://reviews.llvm.org/D35894



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38639: [clangd] #include statements support for Open definition

2017-10-16 Thread William Enright via Phabricator via cfe-commits
Nebiroth marked 21 inline comments as done.
Nebiroth added inline comments.



Comment at: clangd/ClangdUnit.cpp:103
 
+  void AfterExecute(CompilerInstance ) override {
+const SourceManager  = CI.getSourceManager();

ilya-biryukov wrote:
> There's a much better public API to get all includes that were encountered by 
> the `Preprocessor`: we need to override `PPCallbacks ::InclusionDirective`.
> 
> 
> `PrecompiledPreamble` does not currently expose this callbacks, but could you 
> add to `PreambleCallbacks` in a separate commit?
> 
If I were to use InclusionDirective , how would that callback be called 
automatically? As far as I know, it wouldn't be called automatically for every 
file that gets indexed the same way AfterExecute would be.


https://reviews.llvm.org/D38639



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38425: [clangd] Document highlights for clangd

2017-10-12 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 118838.
Nebiroth marked an inline comment as done.
Nebiroth added a comment.

Addressed review comments.
Fixed some tests not having updated providers.
Removed TargetDeclarationFinder for less code reuse.
DocumentHighlight struct is now unparsed correctly.


https://reviews.llvm.org/D38425

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/documenthighlight.test
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -5,18 +5,21 @@
 Content-Length: 143
 
 {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootUri":"file:///path/to/workspace","capabilities":{},"trace":"off"}}
-# CHECK: Content-Length: 535
+# CHECK: Content-Length: 580
 # CHECK: {"jsonrpc":"2.0","id":0,"result":{"capabilities":{
 # CHECK:   "textDocumentSync": 1,
 # CHECK:   "documentFormattingProvider": true,
 # CHECK:   "documentRangeFormattingProvider": true,
 # CHECK:   "documentOnTypeFormattingProvider": {"firstTriggerCharacter":"}","moreTriggerCharacter":[]},
 # CHECK:   "codeActionProvider": true,
 # CHECK:   "completionProvider": {"resolveProvider": false, "triggerCharacters": [".",">",":"]},
 # CHECK:   "signatureHelpProvider": {"triggerCharacters": ["(",","]},
-# CHECK:   "definitionProvider": true
+# CHECK:   "definitionProvider": true,
+# CHECK:   "documentHighlightProvider": true
 # CHECK: }}}
 #
 Content-Length: 44
 
 {"jsonrpc":"2.0","id":3,"method":"shutdown"}
+
+
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -5,16 +5,17 @@
 Content-Length: 142
 
 {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":"","rootUri":"file:///path/to/workspace","capabilities":{},"trace":"off"}}
-# CHECK: Content-Length: 535
+# CHECK: Content-Length: 580
 # CHECK: {"jsonrpc":"2.0","id":0,"result":{"capabilities":{
 # CHECK:   "textDocumentSync": 1,
 # CHECK:   "documentFormattingProvider": true,
 # CHECK:   "documentRangeFormattingProvider": true,
 # CHECK:   "documentOnTypeFormattingProvider": {"firstTriggerCharacter":"}","moreTriggerCharacter":[]},
 # CHECK:   "codeActionProvider": true,
 # CHECK:   "completionProvider": {"resolveProvider": false, "triggerCharacters": [".",">",":"]},
 # CHECK:   "signatureHelpProvider": {"triggerCharacters": ["(",","]},
-# CHECK:   "definitionProvider": true
+# CHECK:   "definitionProvider": true,
+# CHECK:   "documentHighlightProvider": true
 # CHECK: }}}
 #
 Content-Length: 44
Index: test/clangd/documenthighlight.test
===
--- /dev/null
+++ test/clangd/documenthighlight.test
@@ -0,0 +1,42 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+# CHECK: Content-Length: 580
+# CHECK: {"jsonrpc":"2.0","id":0,"result":{"capabilities":{
+# CHECK:   "textDocumentSync": 1,
+# CHECK:   "documentFormattingProvider": true,
+# CHECK:   "documentRangeFormattingProvider": true,
+# CHECK:   "documentOnTypeFormattingProvider": {"firstTriggerCharacter":"}","moreTriggerCharacter":[]},
+# CHECK:   "codeActionProvider": true,
+# CHECK:   "completionProvider": {"resolveProvider": false, "triggerCharacters": [".",">",":"]},
+# CHECK:   "signatureHelpProvider": {"triggerCharacters": ["(",","]},
+# CHECK:   "definitionProvider": true,
+# CHECK:   "documentHighlightProvider": true
+# CHECK: }}}
+#
+
+Content-Length: 455
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#define MACRO 1\nnamespace ns1 {\nstruct MyClass {\nint xasd;\nvoid anotherOperation() {\n}\nstatic int foo(MyClass*) {\nreturn 0;\n}\n\n};\nstruct Foo {\nint xasd;\n};\n}\nint main() {\nint bonjour;\nbonjour = 2;\nns1::Foo bar = { xasd : 1};\nbar.xasd = 3;\nns1::MyClass* Params;\nParams->anotherOperation();}\n"}}}
+
+Content-Length: 156
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":17,"character":2}}}
+# Go to local variable
+# CHECK: {"jsonrpc":"2.0","id":1,"result":[{"range": {"start": {"line": 16, "character": 4}, "end": {"line": 16, "character": 12}}, "kind": 1},{"range": {"start": {"line": 17, "character": 0}, "end": {"line": 17, 

[PATCH] D38425: [clangd] Document highlights for clangd

2017-10-11 Thread William Enright via Phabricator via cfe-commits
Nebiroth marked an inline comment as done.
Nebiroth added inline comments.



Comment at: clangd/ClangdUnit.cpp:784
+/// Finds declarations locations that a given source location refers to.
+class TargetDeclarationFinder : public index::IndexDataConsumer {
+  std::vector DeclarationLocations;

ilya-biryukov wrote:
> This `IndexDataConsumer` effectively does the same thing as 
> `DeclarationLocationsFinder`.
> We should reuse the code between those two.
> 
> To do that we could:
> 1. Change `DeclarationLocationsFinder` to return a list of `Decl*`s and 
> `MacroDef*`s that are under caret.
> 2. In `findDefinition` we should return locations of found `Decl` and 
> `MacroDef`.
> 3. In `documentHighlights` we would rerun `DocumentHighlightsFinder`to 
> capture locations of `Decls` referenced in step 1.
> 
> Do you think this approach would work?
I have something similar to this implemented. Will upstream it soon.


https://reviews.llvm.org/D38425



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D35894: [clangd] Code hover for Clangd

2017-10-11 Thread William Enright via Phabricator via cfe-commits
Nebiroth added a comment.

Bumping this.

I've worked on a patch for this feature that currently supports showing the 
declaration of whatever is being hovered on instead of the raw source code. It 
also has basic support to distinguish declarations in types ( class/struct, 
namespace, global variable,  typedef, enum, namespace, etc.) so that we can 
have a 'kind' of a symbol like mentioned in the comments above.

The step I am at right now is figuring out a way to display this information 
inside the box that will be displayed to the client once a response 
(MarkedString) is sent back by the server. I would like some 
feedback/suggestions on whether it's possible to "append" information to a 
MarkedString to be displayed on client? I was also considering extending LSP to 
include more than just a MarkedString for the response in order to have 
something a bit more flexible to use in-client.


https://reviews.llvm.org/D35894



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38425: [clangd] Document highlights for clangd

2017-10-11 Thread William Enright via Phabricator via cfe-commits
Nebiroth marked 3 inline comments as done.
Nebiroth added inline comments.



Comment at: clangd/ClangdUnit.cpp:1017
+
+  auto DeclLocationsFinder = std::make_shared(
+  llvm::errs(), SourceLocationBeg, AST.getASTContext(),

ilya-biryukov wrote:
> I wonder if we really need to rerun indexer twice here. Probably ok for the 
> first version, but we should definitely think about a faster way to get the 
> `Decl` under cursor than visiting the whole AST. Not sure if it's easy to do 
> with clang's AST, though, maybe we'll need a separate index for that.
Yeah I realise it's definitely not the fastest way to go about it. Maybe there 
is a way to stop handling occurrences once the highlighted declaration is 
found. This would be the most straightforward way of improving the performance 
of the feature without re-writing a new AST indexer.


https://reviews.llvm.org/D38425



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38425: [clangd] Document highlights for clangd

2017-10-10 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 118482.
Nebiroth added a comment.

Rebased on master.


https://reviews.llvm.org/D38425

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/documenthighlight.test
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -5,18 +5,21 @@
 Content-Length: 143
 
 {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootUri":"file:///path/to/workspace","capabilities":{},"trace":"off"}}
-# CHECK: Content-Length: 535
+# CHECK: Content-Length: 580
 # CHECK: {"jsonrpc":"2.0","id":0,"result":{"capabilities":{
 # CHECK:   "textDocumentSync": 1,
 # CHECK:   "documentFormattingProvider": true,
 # CHECK:   "documentRangeFormattingProvider": true,
 # CHECK:   "documentOnTypeFormattingProvider": {"firstTriggerCharacter":"}","moreTriggerCharacter":[]},
 # CHECK:   "codeActionProvider": true,
 # CHECK:   "completionProvider": {"resolveProvider": false, "triggerCharacters": [".",">",":"]},
 # CHECK:   "signatureHelpProvider": {"triggerCharacters": ["(",","]},
-# CHECK:   "definitionProvider": true
+# CHECK:   "definitionProvider": true,
+# CHECK:   "documentHighlightProvider": true
 # CHECK: }}}
 #
 Content-Length: 44
 
 {"jsonrpc":"2.0","id":3,"method":"shutdown"}
+
+
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -5,16 +5,17 @@
 Content-Length: 142
 
 {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":"","rootUri":"file:///path/to/workspace","capabilities":{},"trace":"off"}}
-# CHECK: Content-Length: 535
+# CHECK: Content-Length: 580
 # CHECK: {"jsonrpc":"2.0","id":0,"result":{"capabilities":{
 # CHECK:   "textDocumentSync": 1,
 # CHECK:   "documentFormattingProvider": true,
 # CHECK:   "documentRangeFormattingProvider": true,
 # CHECK:   "documentOnTypeFormattingProvider": {"firstTriggerCharacter":"}","moreTriggerCharacter":[]},
 # CHECK:   "codeActionProvider": true,
 # CHECK:   "completionProvider": {"resolveProvider": false, "triggerCharacters": [".",">",":"]},
 # CHECK:   "signatureHelpProvider": {"triggerCharacters": ["(",","]},
-# CHECK:   "definitionProvider": true
+# CHECK:   "definitionProvider": true,
+# CHECK:   "documentHighlightProvider": true
 # CHECK: }}}
 #
 Content-Length: 44
Index: test/clangd/documenthighlight.test
===
--- /dev/null
+++ test/clangd/documenthighlight.test
@@ -0,0 +1,42 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+# CHECK: Content-Length: 580
+# CHECK: {"jsonrpc":"2.0","id":0,"result":{"capabilities":{
+# CHECK:   "textDocumentSync": 1,
+# CHECK:   "documentFormattingProvider": true,
+# CHECK:   "documentRangeFormattingProvider": true,
+# CHECK:   "documentOnTypeFormattingProvider": {"firstTriggerCharacter":"}","moreTriggerCharacter":[]},
+# CHECK:   "codeActionProvider": true,
+# CHECK:   "completionProvider": {"resolveProvider": false, "triggerCharacters": [".",">",":"]},
+# CHECK:   "signatureHelpProvider": {"triggerCharacters": ["(",","]},
+# CHECK:   "definitionProvider": true,
+# CHECK:   "documentHighlightProvider": true
+# CHECK: }}}
+#
+
+Content-Length: 455
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#define MACRO 1\nnamespace ns1 {\nstruct MyClass {\nint xasd;\nvoid anotherOperation() {\n}\nstatic int foo(MyClass*) {\nreturn 0;\n}\n\n};\nstruct Foo {\nint xasd;\n};\n}\nint main() {\nint bonjour;\nbonjour = 2;\nns1::Foo bar = { xasd : 1};\nbar.xasd = 3;\nns1::MyClass* Params;\nParams->anotherOperation();}\n"}}}
+
+Content-Length: 156
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":17,"character":2}}}
+# Go to local variable
+# CHECK: {"jsonrpc":"2.0","id":1,"result":[{"range": {"start": {"line": 16, "character": 4}, "end": {"line": 16, "character": 12}}, "kind": 1},{"range": {"start": {"line": 17, "character": 0}, "end": {"line": 17, "character": 7}}, "kind": 1}]}
+
+Content-Length: 157
+

[PATCH] D38639: [clangd] #include statements support for Open definition

2017-10-06 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 118046.
Nebiroth added a comment.

Fixed accidental removal of CheckSourceHeaderSwitch test


https://reviews.llvm.org/D38639

Files:
  clangd/ClangdServer.cpp
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  unittests/clangd/ClangdTests.cpp

Index: unittests/clangd/ClangdTests.cpp
===
--- unittests/clangd/ClangdTests.cpp
+++ unittests/clangd/ClangdTests.cpp
@@ -7,7 +7,6 @@
 //
 //===--===//
 
-#include "ClangdLSPServer.h"
 #include "ClangdServer.h"
 #include "Logger.h"
 #include "clang/Basic/VirtualFileSystem.h"
@@ -978,6 +977,57 @@
   EXPECT_FALSE(PathResult.hasValue());
 }
 
+TEST_F(ClangdVFSTest, CheckDefinitionIncludes) {
+  MockFSProvider FS;
+  ErrorCheckingDiagConsumer DiagConsumer;
+  MockCompilationDatabase CDB(/*AddFreestandingFlag=*/true);
+
+  ClangdServer Server(CDB, DiagConsumer, FS, 0,
+  /*SnippetCompletions=*/false, EmptyLogger::getInstance());
+
+  auto FooCpp = getVirtualTestFilePath("foo.cpp");
+  const auto SourceContents = R"cpp(
+  #include "foo.h"
+  #include "invalid.h"
+  int b = a;
+  )cpp";
+  FS.Files[FooCpp] = SourceContents;
+  auto FooH = getVirtualTestFilePath("foo.h");
+  const auto HeaderContents = "int a;";
+
+  FS.Files[FooCpp] = SourceContents;
+  FS.Files[FooH] = HeaderContents;
+
+  Server.addDocument(FooH, HeaderContents);
+  Server.addDocument(FooCpp, SourceContents);
+
+  Position P = Position{1, 11};
+
+  std::vector Locations = (Server.findDefinitions(FooCpp, P)).Value;
+  EXPECT_TRUE(!Locations.empty());
+  std::string s("file:///");
+  std::string check = URI::unparse(Locations[0].uri);
+  check = check.erase(0, s.size());
+  check = check.substr(0, check.size() - 1);
+  ASSERT_EQ(check, FooH);
+  ASSERT_EQ(Locations[0].range.start.line, 0);
+  ASSERT_EQ(Locations[0].range.start.character, 0);
+  ASSERT_EQ(Locations[0].range.end.line, 0);
+  ASSERT_EQ(Locations[0].range.end.character, 0);
+
+  // Test ctrl-clicking on the #include part on the statement
+  Position P3 = Position{1, 3};
+
+  Locations = (Server.findDefinitions(FooCpp, P3)).Value;
+  EXPECT_TRUE(!Locations.empty());
+
+  // Test invalid include
+  Position P2 = Position{2, 11};
+
+  Locations = (Server.findDefinitions(FooCpp, P2)).Value;
+  EXPECT_TRUE(Locations.empty());
+}
+
 TEST_F(ClangdThreadingTest, NoConcurrentDiagnostics) {
   class NoConcurrentAccessDiagConsumer : public DiagnosticsConsumer {
   public:
Index: clangd/ClangdUnit.h
===
--- clangd/ClangdUnit.h
+++ clangd/ClangdUnit.h
@@ -127,11 +127,13 @@
 struct PreambleData {
   PreambleData(PrecompiledPreamble Preamble,
std::vector TopLevelDeclIDs,
-   std::vector Diags);
+   std::vector Diags,
+   std::map IncludeMap);
 
   PrecompiledPreamble Preamble;
   std::vector TopLevelDeclIDs;
   std::vector Diags;
+  std::map IncludeMap;
 };
 
 /// Manages resources, required by clangd. Allows to rebuild file with new
@@ -261,7 +263,8 @@
 
 /// Get definition of symbol at a specified \p Pos.
 std::vector findDefinitions(ParsedAST , Position Pos,
-  clangd::Logger );
+  clangd::Logger ,
+  std::map);
 
 /// For testing/debugging purposes. Note that this method deserializes all
 /// unserialized Decls, so use with care.
Index: clangd/ClangdUnit.cpp
===
--- clangd/ClangdUnit.cpp
+++ clangd/ClangdUnit.cpp
@@ -78,6 +78,10 @@
 return std::move(TopLevelDeclIDs);
   }
 
+  std::map takeIncludeMap() {
+return std::move(IncludeMap);
+  }
+
   void AfterPCHEmitted(ASTWriter ) override {
 TopLevelDeclIDs.reserve(TopLevelDecls.size());
 for (Decl *D : TopLevelDecls) {
@@ -96,9 +100,55 @@
 }
   }
 
+  void AfterExecute(CompilerInstance ) override {
+const SourceManager  = CI.getSourceManager();
+unsigned n = SM.local_sloc_entry_size();
+SmallVector InclusionStack;
+std::map::iterator it = IncludeMap.begin();
+
+for (unsigned i = 0; i < n; ++i) {
+  bool Invalid = false;
+  const SrcMgr::SLocEntry  = SM.getLocalSLocEntry(i, );
+  if (!SL.isFile() || Invalid)
+continue;
+  const SrcMgr::FileInfo  = SL.getFile();
+  SourceLocation L = FI.getIncludeLoc();
+  InclusionStack.clear();
+
+  SourceLocation LocationToInsert;
+
+  while (L.isValid()) {
+PresumedLoc PLoc = SM.getPresumedLoc(L);
+InclusionStack.push_back(L);
+L = PLoc.isValid() ? PLoc.getIncludeLoc() : SourceLocation();
+  }
+  if (InclusionStack.size() == 0) {

[PATCH] D38639: [clangd] #include statements support for Open definition

2017-10-06 Thread William Enright via Phabricator via cfe-commits
Nebiroth created this revision.

ctrl-clicking on #include statements now opens the file being pointed by that 
statement.


https://reviews.llvm.org/D38639

Files:
  clangd/ClangdServer.cpp
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  unittests/clangd/ClangdTests.cpp

Index: unittests/clangd/ClangdTests.cpp
===
--- unittests/clangd/ClangdTests.cpp
+++ unittests/clangd/ClangdTests.cpp
@@ -7,7 +7,6 @@
 //
 //===--===//
 
-#include "ClangdLSPServer.h"
 #include "ClangdServer.h"
 #include "Logger.h"
 #include "clang/Basic/VirtualFileSystem.h"
@@ -900,82 +899,55 @@
   }
 }
 
-TEST_F(ClangdVFSTest, CheckSourceHeaderSwitch) {
+TEST_F(ClangdVFSTest, CheckDefinitionIncludes) {
   MockFSProvider FS;
   ErrorCheckingDiagConsumer DiagConsumer;
   MockCompilationDatabase CDB(/*AddFreestandingFlag=*/true);
 
-  ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(),
+  ClangdServer Server(CDB, DiagConsumer, FS, 0,
   /*SnippetCompletions=*/false, EmptyLogger::getInstance());
 
-  auto SourceContents = R"cpp(
+  auto FooCpp = getVirtualTestFilePath("foo.cpp");
+  const auto SourceContents = R"cpp(
   #include "foo.h"
+  #include "invalid.h"
   int b = a;
   )cpp";
-
-  auto FooCpp = getVirtualTestFilePath("foo.cpp");
+  FS.Files[FooCpp] = SourceContents;
   auto FooH = getVirtualTestFilePath("foo.h");
-  auto Invalid = getVirtualTestFilePath("main.cpp");
+  const auto HeaderContents = "int a;";
 
   FS.Files[FooCpp] = SourceContents;
-  FS.Files[FooH] = "int a;";
-  FS.Files[Invalid] = "int main() { \n return 0; \n }";
+  FS.Files[FooH] = HeaderContents;
 
-  llvm::Optional PathResult = Server.switchSourceHeader(FooCpp);
-  EXPECT_TRUE(PathResult.hasValue());
-  ASSERT_EQ(PathResult.getValue(), FooH);
-
-  PathResult = Server.switchSourceHeader(FooH);
-  EXPECT_TRUE(PathResult.hasValue());
-  ASSERT_EQ(PathResult.getValue(), FooCpp);
+  Server.addDocument(FooH, HeaderContents);
+  Server.addDocument(FooCpp, SourceContents);
 
-  SourceContents = R"c(
-  #include "foo.HH"
-  int b = a;
-  )c";
+  Position P = Position{1, 11};
 
-  // Test with header file in capital letters and different extension, source
-  // file with different extension
-  auto FooC = getVirtualTestFilePath("bar.c");
-  auto FooHH = getVirtualTestFilePath("bar.HH");
-
-  FS.Files[FooC] = SourceContents;
-  FS.Files[FooHH] = "int a;";
-
-  PathResult = Server.switchSourceHeader(FooC);
-  EXPECT_TRUE(PathResult.hasValue());
-  ASSERT_EQ(PathResult.getValue(), FooHH);
-
-  // Test with both capital letters
-  auto Foo2C = getVirtualTestFilePath("foo2.C");
-  auto Foo2HH = getVirtualTestFilePath("foo2.HH");
-  FS.Files[Foo2C] = SourceContents;
-  FS.Files[Foo2HH] = "int a;";
-
-  PathResult = Server.switchSourceHeader(Foo2C);
-  EXPECT_TRUE(PathResult.hasValue());
-  ASSERT_EQ(PathResult.getValue(), Foo2HH);
-
-  // Test with source file as capital letter and .hxx header file
-  auto Foo3C = getVirtualTestFilePath("foo3.C");
-  auto Foo3HXX = getVirtualTestFilePath("foo3.hxx");
+  std::vector Locations = (Server.findDefinitions(FooCpp, P)).Value;
+  EXPECT_TRUE(!Locations.empty());
+  std::string s("file:///");
+  std::string check = URI::unparse(Locations[0].uri);
+  check = check.erase(0, s.size());
+  check = check.substr(0, check.size() - 1);
+  ASSERT_EQ(check, FooH);
+  ASSERT_EQ(Locations[0].range.start.line, 0);
+  ASSERT_EQ(Locations[0].range.start.character, 0);
+  ASSERT_EQ(Locations[0].range.end.line, 0);
+  ASSERT_EQ(Locations[0].range.end.character, 0);
+
+  // Test ctrl-clicking on the #include part on the statement
+  Position P3 = Position{1, 3};
 
-  SourceContents = R"c(
-  #include "foo3.hxx"
-  int b = a;
-  )c";
+  Locations = (Server.findDefinitions(FooCpp, P3)).Value;
+  EXPECT_TRUE(!Locations.empty());
 
-  FS.Files[Foo3C] = SourceContents;
-  FS.Files[Foo3HXX] = "int a;";
+  // Test invalid include
+  Position P2 = Position{2, 11};
 
-  PathResult = Server.switchSourceHeader(Foo3C);
-  EXPECT_TRUE(PathResult.hasValue());
-  ASSERT_EQ(PathResult.getValue(), Foo3HXX);
-
-  // Test if asking for a corresponding file that doesn't exist returns an empty
-  // string.
-  PathResult = Server.switchSourceHeader(Invalid);
-  EXPECT_FALSE(PathResult.hasValue());
+  Locations = (Server.findDefinitions(FooCpp, P2)).Value;
+  EXPECT_TRUE(Locations.empty());
 }
 
 TEST_F(ClangdThreadingTest, NoConcurrentDiagnostics) {
Index: clangd/ClangdUnit.h
===
--- clangd/ClangdUnit.h
+++ clangd/ClangdUnit.h
@@ -127,11 +127,13 @@
 struct PreambleData {
   PreambleData(PrecompiledPreamble Preamble,
std::vector TopLevelDeclIDs,
-   std::vector Diags);
+   std::vector Diags,
+   std::map IncludeMap);
 
   PrecompiledPreamble Preamble;
   

[PATCH] D38425: [clangd] Document highlights for clangd

2017-10-02 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 117351.
Nebiroth marked 3 inline comments as done.
Nebiroth added a comment.

Addressed initial comments.
Formatted ClangdUnit.h


https://reviews.llvm.org/D38425

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/documenthighlight.test

Index: test/clangd/documenthighlight.test
===
--- /dev/null
+++ test/clangd/documenthighlight.test
@@ -0,0 +1,29 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 455
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#define MACRO 1\nnamespace ns1 {\nstruct MyClass {\nint xasd;\nvoid anotherOperation() {\n}\nstatic int foo(MyClass*) {\nreturn 0;\n}\n\n};\nstruct Foo {\nint xasd;\n};\n}\nint main() {\nint bonjour;\nbonjour = 2;\nns1::Foo bar = { xasd : 1};\nbar.xasd = 3;\nns1::MyClass* Params;\nParams->anotherOperation();}\n"}}}
+
+Content-Length: 156
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":17,"character":2}}}
+# Go to local variable
+# CHECK: {"jsonrpc":"2.0","id":1,"result":[{"range": {"start": {"line": 16, "character": 4}, "end": {"line": 16, "character": 12}}, "number": 1},{"range": {"start": {"line": 17, "character": 0}, "end": {"line": 17, "character": 7}}, "number": 1}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":18,"character":17}}}
+# Go to local variable
+# CHECK: {"jsonrpc":"2.0","id":1,"result":[{"range": {"start": {"line": 12, "character": 4}, "end": {"line": 12, "character": 9}}, "number": 1},{"range": {"start": {"line": 18, "character": 17}, "end": {"line": 18, "character": 21}}, "number": 1},{"range": {"start": {"line": 19, "character": 4}, "end": {"line": 19, "character": 8}}, "number": 1}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":21,"character":10}}}
+# Go to local variable
+# CHECK: {"jsonrpc":"2.0","id":1,"result":[{"range": {"start": {"line": 4, "character": 5}, "end": {"line": 4, "character": 22}}, "number": 1},{"range": {"start": {"line": 21, "character": 8}, "end": {"line": 21, "character": 25}}, "number": 1}]}
+
Index: clangd/ProtocolHandlers.h
===
--- clangd/ProtocolHandlers.h
+++ clangd/ProtocolHandlers.h
@@ -47,7 +47,9 @@
   virtual void onCompletion(TextDocumentPositionParams Params, StringRef ID,
 JSONOutput ) = 0;
   virtual void onGoToDefinition(TextDocumentPositionParams Params, StringRef ID,
-JSONOutput ) = 0;
+JSONOutput ) = 0;
+  virtual void onDocumentHighlight(TextDocumentPositionParams Params, StringRef ID,
+JSONOutput ) = 0;  
 };
 
 void regiterCallbackHandlers(JSONRPCDispatcher , JSONOutput ,
Index: clangd/ProtocolHandlers.cpp
===
--- clangd/ProtocolHandlers.cpp
+++ clangd/ProtocolHandlers.cpp
@@ -204,6 +204,24 @@
   ProtocolCallbacks 
 };
 
+struct DocumentHighlightHandler : Handler {
+  DocumentHighlightHandler(JSONOutput , ProtocolCallbacks )
+  : Handler(Output), Callbacks(Callbacks) {}
+
+  void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override {
+auto TDPP = TextDocumentPositionParams::parse(Params, Output);
+if (!TDPP) {
+  Output.log("Failed to decode TextDocumentPositionParams!\n");
+  return;
+}
+
+Callbacks.onDocumentHighlight(*TDPP, ID, Output);
+  }
+
+private:
+  ProtocolCallbacks 
+};
+
 } // namespace
 
 void clangd::regiterCallbackHandlers(JSONRPCDispatcher ,
@@ -240,4 +258,7 @@
   Dispatcher.registerHandler(
   "textDocument/definition",
   llvm::make_unique(Out, Callbacks));
+  Dispatcher.registerHandler(
+  "textDocument/documentHighlight",
+  llvm::make_unique(Out, Callbacks));
 }
Index: clangd/Protocol.h
===
--- clangd/Protocol.h
+++ clangd/Protocol.h
@@ -416,6 +416,41 @@
   static std::string unparse(const CompletionItem );
 };
 
+enum class DocumentHighlightKind {
+  Text = 1,
+  Read = 2,
+  Write = 3
+};
+
+/**
+ * A document highlight is a range inside 

[PATCH] D37150: [clangd] Command line arg to specify compile_commands.json path

2017-10-02 Thread William Enright via Phabricator via cfe-commits
Nebiroth added a comment.

In https://reviews.llvm.org/D37150#885749, @ilya-biryukov wrote:

> Thanks for fixing the last comment.
>  Do you want me to land this for you?


Yes please!


https://reviews.llvm.org/D37150



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D37150: [clangd] Command line arg to specify compile_commands.json path

2017-10-02 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 117340.
Nebiroth added a comment.

Improved logging message when unable to find compilation database in specified 
overriden directory.


https://reviews.llvm.org/D37150

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/GlobalCompilationDatabase.cpp
  clangd/GlobalCompilationDatabase.h
  clangd/tool/ClangdMain.cpp

Index: clangd/tool/ClangdMain.cpp
===
--- clangd/tool/ClangdMain.cpp
+++ clangd/tool/ClangdMain.cpp
@@ -11,16 +11,22 @@
 #include "JSONRPCDispatcher.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
-
 #include 
 #include 
 #include 
 #include 
 
 using namespace clang;
 using namespace clang::clangd;
 
+static llvm::cl::opt CompileCommandsDir(
+"compile-commands-dir",
+llvm::cl::desc("Specify a path to look for compile_commands.json. If path "
+   "is invalid, clangd will look in the current directory and "
+   "parent paths of each source file."));
+
 static llvm::cl::opt
 WorkerThreadsCount("j",
llvm::cl::desc("Number of async workers used by clangd"),
@@ -56,18 +62,37 @@
   if (RunSynchronously)
 WorkerThreadsCount = 0;
 
+  /// Validate command line arguments.
   llvm::raw_ostream  = llvm::outs();
   llvm::raw_ostream  = llvm::errs();
   JSONOutput Out(Outs, Logs);
 
-  // Change stdin to binary to not lose \r\n on windows.
-  llvm::sys::ChangeStdinToBinary();
+  // If --compile-commands-dir arg was invoked, check value and override default
+  // path.
+  namespace path = llvm::sys::path;
+  llvm::Optional CompileCommandsDirPath;
+
+  if (CompileCommandsDir.empty()) {
+CompileCommandsDirPath = llvm::None;
+  } else if (!llvm::sys::path::is_absolute(CompileCommandsDir) ||
+ !llvm::sys::fs::exists(CompileCommandsDir)) {
+llvm::errs() << "Path specified by --compile-commands-dir either does not "
+"exist or is not an absolute "
+"path. The argument will be ignored.\n";
+CompileCommandsDirPath = llvm::None;
+  } else {
+CompileCommandsDirPath = CompileCommandsDir;
+  }
 
   llvm::Optional ResourceDirRef = None;
   if (!ResourceDir.empty())
 ResourceDirRef = ResourceDir;
 
+  /// Change stdin to binary to not lose \r\n on windows.
+  llvm::sys::ChangeStdinToBinary();
+
+  /// Initialize and run ClangdLSPServer.
   ClangdLSPServer LSPServer(Out, WorkerThreadsCount, EnableSnippets,
-ResourceDirRef);
+ResourceDirRef, CompileCommandsDirPath);
   LSPServer.run(std::cin);
 }
Index: clangd/GlobalCompilationDatabase.h
===
--- clangd/GlobalCompilationDatabase.h
+++ clangd/GlobalCompilationDatabase.h
@@ -47,15 +47,17 @@
 class DirectoryBasedGlobalCompilationDatabase
 : public GlobalCompilationDatabase {
 public:
-  DirectoryBasedGlobalCompilationDatabase(clangd::Logger );
+  DirectoryBasedGlobalCompilationDatabase(
+  clangd::Logger , llvm::Optional NewCompileCommandsDir);
 
   std::vector
   getCompileCommands(PathRef File) override;
 
   void setExtraFlagsForFile(PathRef File, std::vector ExtraFlags);
 
 private:
   tooling::CompilationDatabase *getCompilationDatabase(PathRef File);
+  tooling::CompilationDatabase *tryLoadDatabaseFromPath(PathRef File);
 
   std::mutex Mutex;
   /// Caches compilation databases loaded from directories(keys are
@@ -67,6 +69,9 @@
   llvm::StringMap ExtraFlagsForFile;
   /// Used for logging.
   clangd::Logger 
+  /// Used for command argument pointing to folder where compile_commands.json
+  /// is located.
+  llvm::Optional CompileCommandsDir;
 };
 } // namespace clangd
 } // namespace clang
Index: clangd/GlobalCompilationDatabase.cpp
===
--- clangd/GlobalCompilationDatabase.cpp
+++ clangd/GlobalCompilationDatabase.cpp
@@ -8,10 +8,10 @@
 //===-===//
 
 #include "GlobalCompilationDatabase.h"
+#include "Logger.h"
 #include "clang/Tooling/CompilationDatabase.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
-#include "Logger.h"
 
 namespace clang {
 namespace clangd {
@@ -38,8 +38,9 @@
 }
 
 DirectoryBasedGlobalCompilationDatabase::
-DirectoryBasedGlobalCompilationDatabase(clangd::Logger )
-: Logger(Logger) {}
+DirectoryBasedGlobalCompilationDatabase(
+clangd::Logger , llvm::Optional NewCompileCommandsDir)
+: Logger(Logger), CompileCommandsDir(NewCompileCommandsDir) {}
 
 std::vector
 DirectoryBasedGlobalCompilationDatabase::getCompileCommands(PathRef File) {
@@ -67,31 +68,50 @@
 }
 
 tooling::CompilationDatabase *
-DirectoryBasedGlobalCompilationDatabase::getCompilationDatabase(PathRef File) {
-  

[PATCH] D37150: [clangd] Command line arg to specify compile_commands.json path

2017-10-02 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 117337.
Nebiroth marked 2 inline comments as done.
Nebiroth added a comment.

Changed placement of logging instruction to reduce logging output.


https://reviews.llvm.org/D37150

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/GlobalCompilationDatabase.cpp
  clangd/GlobalCompilationDatabase.h
  clangd/tool/ClangdMain.cpp

Index: clangd/tool/ClangdMain.cpp
===
--- clangd/tool/ClangdMain.cpp
+++ clangd/tool/ClangdMain.cpp
@@ -11,16 +11,22 @@
 #include "JSONRPCDispatcher.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
-
 #include 
 #include 
 #include 
 #include 
 
 using namespace clang;
 using namespace clang::clangd;
 
+static llvm::cl::opt CompileCommandsDir(
+"compile-commands-dir",
+llvm::cl::desc("Specify a path to look for compile_commands.json. If path "
+   "is invalid, clangd will look in the current directory and "
+   "parent paths of each source file."));
+
 static llvm::cl::opt
 WorkerThreadsCount("j",
llvm::cl::desc("Number of async workers used by clangd"),
@@ -56,18 +62,37 @@
   if (RunSynchronously)
 WorkerThreadsCount = 0;
 
+  /// Validate command line arguments.
   llvm::raw_ostream  = llvm::outs();
   llvm::raw_ostream  = llvm::errs();
   JSONOutput Out(Outs, Logs);
 
-  // Change stdin to binary to not lose \r\n on windows.
-  llvm::sys::ChangeStdinToBinary();
+  // If --compile-commands-dir arg was invoked, check value and override default
+  // path.
+  namespace path = llvm::sys::path;
+  llvm::Optional CompileCommandsDirPath;
+
+  if (CompileCommandsDir.empty()) {
+CompileCommandsDirPath = llvm::None;
+  } else if (!llvm::sys::path::is_absolute(CompileCommandsDir) ||
+ !llvm::sys::fs::exists(CompileCommandsDir)) {
+llvm::errs() << "Path specified by --compile-commands-dir either does not "
+"exist or is not an absolute "
+"path. The argument will be ignored.\n";
+CompileCommandsDirPath = llvm::None;
+  } else {
+CompileCommandsDirPath = CompileCommandsDir;
+  }
 
   llvm::Optional ResourceDirRef = None;
   if (!ResourceDir.empty())
 ResourceDirRef = ResourceDir;
 
+  /// Change stdin to binary to not lose \r\n on windows.
+  llvm::sys::ChangeStdinToBinary();
+
+  /// Initialize and run ClangdLSPServer.
   ClangdLSPServer LSPServer(Out, WorkerThreadsCount, EnableSnippets,
-ResourceDirRef);
+ResourceDirRef, CompileCommandsDirPath);
   LSPServer.run(std::cin);
 }
Index: clangd/GlobalCompilationDatabase.h
===
--- clangd/GlobalCompilationDatabase.h
+++ clangd/GlobalCompilationDatabase.h
@@ -47,15 +47,17 @@
 class DirectoryBasedGlobalCompilationDatabase
 : public GlobalCompilationDatabase {
 public:
-  DirectoryBasedGlobalCompilationDatabase(clangd::Logger );
+  DirectoryBasedGlobalCompilationDatabase(
+  clangd::Logger , llvm::Optional NewCompileCommandsDir);
 
   std::vector
   getCompileCommands(PathRef File) override;
 
   void setExtraFlagsForFile(PathRef File, std::vector ExtraFlags);
 
 private:
   tooling::CompilationDatabase *getCompilationDatabase(PathRef File);
+  tooling::CompilationDatabase *tryLoadDatabaseFromPath(PathRef File);
 
   std::mutex Mutex;
   /// Caches compilation databases loaded from directories(keys are
@@ -67,6 +69,9 @@
   llvm::StringMap ExtraFlagsForFile;
   /// Used for logging.
   clangd::Logger 
+  /// Used for command argument pointing to folder where compile_commands.json
+  /// is located.
+  llvm::Optional CompileCommandsDir;
 };
 } // namespace clangd
 } // namespace clang
Index: clangd/GlobalCompilationDatabase.cpp
===
--- clangd/GlobalCompilationDatabase.cpp
+++ clangd/GlobalCompilationDatabase.cpp
@@ -8,10 +8,10 @@
 //===-===//
 
 #include "GlobalCompilationDatabase.h"
+#include "Logger.h"
 #include "clang/Tooling/CompilationDatabase.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
-#include "Logger.h"
 
 namespace clang {
 namespace clangd {
@@ -38,8 +38,9 @@
 }
 
 DirectoryBasedGlobalCompilationDatabase::
-DirectoryBasedGlobalCompilationDatabase(clangd::Logger )
-: Logger(Logger) {}
+DirectoryBasedGlobalCompilationDatabase(
+clangd::Logger , llvm::Optional NewCompileCommandsDir)
+: Logger(Logger), CompileCommandsDir(NewCompileCommandsDir) {}
 
 std::vector
 DirectoryBasedGlobalCompilationDatabase::getCompileCommands(PathRef File) {
@@ -67,31 +68,49 @@
 }
 
 tooling::CompilationDatabase *
-DirectoryBasedGlobalCompilationDatabase::getCompilationDatabase(PathRef 

[PATCH] D37150: [clangd] Command line arg to specify compile_commands.json path

2017-10-02 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 117327.
Nebiroth added a comment.

Fixed changes that were lost while merging with head.


https://reviews.llvm.org/D37150

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/GlobalCompilationDatabase.cpp
  clangd/GlobalCompilationDatabase.h
  clangd/tool/ClangdMain.cpp

Index: clangd/tool/ClangdMain.cpp
===
--- clangd/tool/ClangdMain.cpp
+++ clangd/tool/ClangdMain.cpp
@@ -11,16 +11,22 @@
 #include "JSONRPCDispatcher.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
-
 #include 
 #include 
 #include 
 #include 
 
 using namespace clang;
 using namespace clang::clangd;
 
+static llvm::cl::opt CompileCommandsDir(
+"compile-commands-dir",
+llvm::cl::desc("Specify a path to look for compile_commands.json. If path "
+   "is invalid, clangd will look in the current directory and "
+   "parent paths of each source file."));
+
 static llvm::cl::opt
 WorkerThreadsCount("j",
llvm::cl::desc("Number of async workers used by clangd"),
@@ -56,18 +62,37 @@
   if (RunSynchronously)
 WorkerThreadsCount = 0;
 
+  /// Validate command line arguments.
   llvm::raw_ostream  = llvm::outs();
   llvm::raw_ostream  = llvm::errs();
   JSONOutput Out(Outs, Logs);
 
-  // Change stdin to binary to not lose \r\n on windows.
-  llvm::sys::ChangeStdinToBinary();
+  // If --compile-commands-dir arg was invoked, check value and override default
+  // path.
+  namespace path = llvm::sys::path;
+  llvm::Optional CompileCommandsDirPath;
+
+  if (CompileCommandsDir.empty()) {
+CompileCommandsDirPath = llvm::None;
+  } else if (!llvm::sys::path::is_absolute(CompileCommandsDir) ||
+ !llvm::sys::fs::exists(CompileCommandsDir)) {
+llvm::errs() << "Path specified by --compile-commands-dir either does not "
+"exist or is not an absolute "
+"path. The argument will be ignored.\n";
+CompileCommandsDirPath = llvm::None;
+  } else {
+CompileCommandsDirPath = CompileCommandsDir;
+  }
 
   llvm::Optional ResourceDirRef = None;
   if (!ResourceDir.empty())
 ResourceDirRef = ResourceDir;
 
+  /// Change stdin to binary to not lose \r\n on windows.
+  llvm::sys::ChangeStdinToBinary();
+
+  /// Initialize and run ClangdLSPServer.
   ClangdLSPServer LSPServer(Out, WorkerThreadsCount, EnableSnippets,
-ResourceDirRef);
+ResourceDirRef, CompileCommandsDirPath);
   LSPServer.run(std::cin);
 }
Index: clangd/GlobalCompilationDatabase.h
===
--- clangd/GlobalCompilationDatabase.h
+++ clangd/GlobalCompilationDatabase.h
@@ -47,15 +47,17 @@
 class DirectoryBasedGlobalCompilationDatabase
 : public GlobalCompilationDatabase {
 public:
-  DirectoryBasedGlobalCompilationDatabase(clangd::Logger );
+  DirectoryBasedGlobalCompilationDatabase(
+  clangd::Logger , llvm::Optional NewCompileCommandsDir);
 
   std::vector
   getCompileCommands(PathRef File) override;
 
   void setExtraFlagsForFile(PathRef File, std::vector ExtraFlags);
 
 private:
   tooling::CompilationDatabase *getCompilationDatabase(PathRef File);
+  tooling::CompilationDatabase *tryLoadDatabaseFromPath(PathRef File);
 
   std::mutex Mutex;
   /// Caches compilation databases loaded from directories(keys are
@@ -67,6 +69,9 @@
   llvm::StringMap ExtraFlagsForFile;
   /// Used for logging.
   clangd::Logger 
+  /// Used for command argument pointing to folder where compile_commands.json
+  /// is located.
+  llvm::Optional CompileCommandsDir;
 };
 } // namespace clangd
 } // namespace clang
Index: clangd/GlobalCompilationDatabase.cpp
===
--- clangd/GlobalCompilationDatabase.cpp
+++ clangd/GlobalCompilationDatabase.cpp
@@ -8,10 +8,10 @@
 //===-===//
 
 #include "GlobalCompilationDatabase.h"
+#include "Logger.h"
 #include "clang/Tooling/CompilationDatabase.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
-#include "Logger.h"
 
 namespace clang {
 namespace clangd {
@@ -38,8 +38,9 @@
 }
 
 DirectoryBasedGlobalCompilationDatabase::
-DirectoryBasedGlobalCompilationDatabase(clangd::Logger )
-: Logger(Logger) {}
+DirectoryBasedGlobalCompilationDatabase(
+clangd::Logger , llvm::Optional NewCompileCommandsDir)
+: Logger(Logger), CompileCommandsDir(NewCompileCommandsDir) {}
 
 std::vector
 DirectoryBasedGlobalCompilationDatabase::getCompileCommands(PathRef File) {
@@ -67,34 +68,46 @@
 }
 
 tooling::CompilationDatabase *
-DirectoryBasedGlobalCompilationDatabase::getCompilationDatabase(PathRef File) {
-  std::lock_guard Lock(Mutex);

[PATCH] D37150: [clangd] Command line arg to specify compile_commands.json path

2017-09-29 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 117217.
Nebiroth added a comment.

Fixed missed comments and suggstions.


https://reviews.llvm.org/D37150

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/GlobalCompilationDatabase.cpp
  clangd/GlobalCompilationDatabase.h
  clangd/tool/ClangdMain.cpp

Index: clangd/tool/ClangdMain.cpp
===
--- clangd/tool/ClangdMain.cpp
+++ clangd/tool/ClangdMain.cpp
@@ -11,16 +11,22 @@
 #include "JSONRPCDispatcher.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
-
 #include 
 #include 
 #include 
 #include 
 
 using namespace clang;
 using namespace clang::clangd;
 
+static llvm::cl::opt CompileCommandsDir(
+"compile-commands-dir",
+llvm::cl::desc("Specify a path to look for compile_commands.json. If path "
+   "is invalid, clangd will look in the current directory and "
+   "parent paths of each source file."));
+
 static llvm::cl::opt
 WorkerThreadsCount("j",
llvm::cl::desc("Number of async workers used by clangd"),
@@ -56,18 +62,37 @@
   if (RunSynchronously)
 WorkerThreadsCount = 0;
 
+  /// Validate command line arguments.
   llvm::raw_ostream  = llvm::outs();
   llvm::raw_ostream  = llvm::errs();
   JSONOutput Out(Outs, Logs);
 
-  // Change stdin to binary to not lose \r\n on windows.
-  llvm::sys::ChangeStdinToBinary();
+  // If --compile-commands-dir arg was invoked, check value and override default
+  // path.
+  namespace path = llvm::sys::path;
+  llvm::Optional CompileCommandsDirPath;
+
+  if (CompileCommandsDir.empty()) {
+CompileCommandsDirPath = llvm::None;
+  } else if (!llvm::sys::path::is_absolute(CompileCommandsDir) ||
+ !llvm::sys::fs::exists(CompileCommandsDir)) {
+llvm::errs() << "Path specified by --compile-commands-dir either does not "
+"exist or is not an absolute "
+"path. The argument will be ignored.\n";
+CompileCommandsDirPath = llvm::None;
+  } else {
+CompileCommandsDirPath = CompileCommandsDir;
+  }
 
   llvm::Optional ResourceDirRef = None;
   if (!ResourceDir.empty())
 ResourceDirRef = ResourceDir;
 
+  /// Change stdin to binary to not lose \r\n on windows.
+  llvm::sys::ChangeStdinToBinary();
+
+  /// Initialize and run ClangdLSPServer.
   ClangdLSPServer LSPServer(Out, WorkerThreadsCount, EnableSnippets,
-ResourceDirRef);
+ResourceDirRef, CompileCommandsDirPath);
   LSPServer.run(std::cin);
 }
Index: clangd/GlobalCompilationDatabase.h
===
--- clangd/GlobalCompilationDatabase.h
+++ clangd/GlobalCompilationDatabase.h
@@ -47,15 +47,17 @@
 class DirectoryBasedGlobalCompilationDatabase
 : public GlobalCompilationDatabase {
 public:
-  DirectoryBasedGlobalCompilationDatabase(clangd::Logger );
+  DirectoryBasedGlobalCompilationDatabase(
+  clangd::Logger , llvm::Optional NewCompileCommandsDir);
 
   std::vector
   getCompileCommands(PathRef File) override;
 
   void setExtraFlagsForFile(PathRef File, std::vector ExtraFlags);
 
 private:
   tooling::CompilationDatabase *getCompilationDatabase(PathRef File);
+  tooling::CompilationDatabase *tryLoadDatabaseFromPath(PathRef File);
 
   std::mutex Mutex;
   /// Caches compilation databases loaded from directories(keys are
@@ -67,6 +69,9 @@
   llvm::StringMap ExtraFlagsForFile;
   /// Used for logging.
   clangd::Logger 
+  /// Used for command argument pointing to folder where compile_commands.json
+  /// is located.
+  llvm::Optional CompileCommandsDir;
 };
 } // namespace clangd
 } // namespace clang
Index: clangd/GlobalCompilationDatabase.cpp
===
--- clangd/GlobalCompilationDatabase.cpp
+++ clangd/GlobalCompilationDatabase.cpp
@@ -8,10 +8,10 @@
 //===-===//
 
 #include "GlobalCompilationDatabase.h"
+#include "Logger.h"
 #include "clang/Tooling/CompilationDatabase.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
-#include "Logger.h"
 
 namespace clang {
 namespace clangd {
@@ -38,8 +38,9 @@
 }
 
 DirectoryBasedGlobalCompilationDatabase::
-DirectoryBasedGlobalCompilationDatabase(clangd::Logger )
-: Logger(Logger) {}
+DirectoryBasedGlobalCompilationDatabase(
+clangd::Logger , llvm::Optional NewCompileCommandsDir)
+: Logger(Logger), CompileCommandsDir(NewCompileCommandsDir) {}
 
 std::vector
 DirectoryBasedGlobalCompilationDatabase::getCompileCommands(PathRef File) {
@@ -67,34 +68,48 @@
 }
 
 tooling::CompilationDatabase *
-DirectoryBasedGlobalCompilationDatabase::getCompilationDatabase(PathRef File) {
-  std::lock_guard Lock(Mutex);

[PATCH] D38425: [clangd] Document highlights for clangd

2017-09-29 Thread William Enright via Phabricator via cfe-commits
Nebiroth created this revision.

Implementation of Document Highlights Request as described in LSP.


https://reviews.llvm.org/D38425

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/documenthighlight.test

Index: test/clangd/documenthighlight.test
===
--- /dev/null
+++ test/clangd/documenthighlight.test
@@ -0,0 +1,29 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 455
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#define MACRO 1\nnamespace ns1 {\nstruct MyClass {\nint xasd;\nvoid anotherOperation() {\n}\nstatic int foo(MyClass*) {\nreturn 0;\n}\n\n};\nstruct Foo {\nint xasd;\n};\n}\nint main() {\nint bonjour;\nbonjour = 2;\nns1::Foo bar = { xasd : 1};\nbar.xasd = 3;\nns1::MyClass* Params;\nParams->anotherOperation();}\n"}}}
+
+Content-Length: 156
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":17,"character":2}}}
+# Go to local variable
+# CHECK: {"jsonrpc":"2.0","id":1,"result":[{"range": {"start": {"line": 16, "character": 4}, "end": {"line": 16, "character": 12}}, "number": 1},{"range": {"start": {"line": 17, "character": 0}, "end": {"line": 17, "character": 7}}, "number": 1}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":18,"character":17}}}
+# Go to local variable
+# CHECK: {"jsonrpc":"2.0","id":1,"result":[{"range": {"start": {"line": 12, "character": 4}, "end": {"line": 12, "character": 9}}, "number": 1},{"range": {"start": {"line": 18, "character": 17}, "end": {"line": 18, "character": 21}}, "number": 1},{"range": {"start": {"line": 19, "character": 4}, "end": {"line": 19, "character": 8}}, "number": 1}]}
+
+Content-Length: 157
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":21,"character":10}}}
+# Go to local variable
+# CHECK: {"jsonrpc":"2.0","id":1,"result":[{"range": {"start": {"line": 4, "character": 5}, "end": {"line": 4, "character": 22}}, "number": 1},{"range": {"start": {"line": 21, "character": 8}, "end": {"line": 21, "character": 25}}, "number": 1}]}
+
Index: clangd/ProtocolHandlers.h
===
--- clangd/ProtocolHandlers.h
+++ clangd/ProtocolHandlers.h
@@ -47,7 +47,9 @@
   virtual void onCompletion(TextDocumentPositionParams Params, StringRef ID,
 JSONOutput ) = 0;
   virtual void onGoToDefinition(TextDocumentPositionParams Params, StringRef ID,
-JSONOutput ) = 0;
+JSONOutput ) = 0;
+  virtual void onDocumentHighlight(TextDocumentPositionParams Params, StringRef ID,
+JSONOutput ) = 0;  
 };
 
 void regiterCallbackHandlers(JSONRPCDispatcher , JSONOutput ,
Index: clangd/ProtocolHandlers.cpp
===
--- clangd/ProtocolHandlers.cpp
+++ clangd/ProtocolHandlers.cpp
@@ -204,6 +204,24 @@
   ProtocolCallbacks 
 };
 
+struct DocumentHighlightHandler : Handler {
+  DocumentHighlightHandler(JSONOutput , ProtocolCallbacks )
+  : Handler(Output), Callbacks(Callbacks) {}
+
+  void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override {
+auto TDPP = TextDocumentPositionParams::parse(Params, Output);
+if (!TDPP) {
+  Output.log("Failed to decode TextDocumentPositionParams!\n");
+  return;
+}
+
+Callbacks.onDocumentHighlight(*TDPP, ID, Output);
+  }
+
+private:
+  ProtocolCallbacks 
+};
+
 } // namespace
 
 void clangd::regiterCallbackHandlers(JSONRPCDispatcher ,
@@ -240,4 +258,7 @@
   Dispatcher.registerHandler(
   "textDocument/definition",
   llvm::make_unique(Out, Callbacks));
+  Dispatcher.registerHandler(
+  "textDocument/documentHighlight",
+  llvm::make_unique(Out, Callbacks));
 }
Index: clangd/Protocol.h
===
--- clangd/Protocol.h
+++ clangd/Protocol.h
@@ -416,6 +416,41 @@
   static std::string unparse(const CompletionItem );
 };
 
+enum class DocumentHighlightKind {
+  Text = 1,
+  Read = 2,
+  Write = 3
+};
+
+/**
+ * A document highlight is a range inside a text document which deserves
+ * special attention. Usually a 

[PATCH] D37150: [clangd] Command line arg to specify compile_commands.json path

2017-09-28 Thread William Enright via Phabricator via cfe-commits
Nebiroth added inline comments.



Comment at: clangd/tool/ClangdMain.cpp:20
 #include 
+#include 
 

malaperle wrote:
> William, did you perhaps miss this comment? I don't think unistd.h makes 
> sense here.
I indeed missed it.


https://reviews.llvm.org/D37150



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D37150: [clangd] Command line arg to specify compile_commands.json path

2017-09-25 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 116559.
Nebiroth added a comment.

Fixed inverted compile_commands check logic that made tests fail.
More readable command arg checks.


https://reviews.llvm.org/D37150

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/GlobalCompilationDatabase.cpp
  clangd/GlobalCompilationDatabase.h
  clangd/tool/ClangdMain.cpp

Index: clangd/tool/ClangdMain.cpp
===
--- clangd/tool/ClangdMain.cpp
+++ clangd/tool/ClangdMain.cpp
@@ -11,16 +11,23 @@
 #include "JSONRPCDispatcher.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
-
 #include 
 #include 
 #include 
 #include 
+#include 
 
 using namespace clang;
 using namespace clang::clangd;
 
+static llvm::cl::opt CompileCommandsDir(
+"compile-commands-dir",
+llvm::cl::desc("Specify a path to look for compile_commands.json. If path "
+   "is invalid, clangd will look in the current directory and "
+   "parent paths of each source file."));
+
 static llvm::cl::opt
 WorkerThreadsCount("j",
llvm::cl::desc("Number of async workers used by clangd"),
@@ -56,18 +63,40 @@
   if (RunSynchronously)
 WorkerThreadsCount = 0;
 
+  /// Validate command line arguments.
   llvm::raw_ostream  = llvm::outs();
   llvm::raw_ostream  = llvm::errs();
   JSONOutput Out(Outs, Logs);
 
-  // Change stdin to binary to not lose \r\n on windows.
-  llvm::sys::ChangeStdinToBinary();
+  // If --compile-commands-dir arg was invoked, check value and override default
+  // path.
+  namespace path = llvm::sys::path;
+  llvm::Optional CompileCommandsDirPath;
+
+  if (CompileCommandsDir.empty())
+CompileCommandsDirPath = llvm::None;
+  else if (!llvm::sys::path::is_absolute(CompileCommandsDir)) {
+llvm::errs()
+<< "Path specified by --compile-commands-dir must be an absolute "
+   "path. The argument will be ignored.\n";
+CompileCommandsDirPath = llvm::None;
+  } else if (!llvm::sys::fs::exists(CompileCommandsDir)) {
+llvm::errs() << "Path specified by --compile-commands-dir does not exist. "
+"The argument will be "
+"ignored.\n";
+CompileCommandsDirPath = llvm::None;
+  } else
+CompileCommandsDirPath = CompileCommandsDir;
 
   llvm::Optional ResourceDirRef = None;
   if (!ResourceDir.empty())
 ResourceDirRef = ResourceDir;
 
+  /// Change stdin to binary to not lose \r\n on windows.
+  llvm::sys::ChangeStdinToBinary();
+
+  /// Initialize and run ClangdLSPServer.
   ClangdLSPServer LSPServer(Out, WorkerThreadsCount, EnableSnippets,
-ResourceDirRef);
+ResourceDirRef, CompileCommandsDirPath);
   LSPServer.run(std::cin);
 }
Index: clangd/GlobalCompilationDatabase.h
===
--- clangd/GlobalCompilationDatabase.h
+++ clangd/GlobalCompilationDatabase.h
@@ -47,15 +47,17 @@
 class DirectoryBasedGlobalCompilationDatabase
 : public GlobalCompilationDatabase {
 public:
-  DirectoryBasedGlobalCompilationDatabase(clangd::Logger );
+  DirectoryBasedGlobalCompilationDatabase(
+  clangd::Logger , llvm::Optional NewCompileCommandsDir);
 
   std::vector
   getCompileCommands(PathRef File) override;
 
   void setExtraFlagsForFile(PathRef File, std::vector ExtraFlags);
 
 private:
   tooling::CompilationDatabase *getCompilationDatabase(PathRef File);
+  tooling::CompilationDatabase *tryLoadDatabaseFromPath(PathRef File);
 
   std::mutex Mutex;
   /// Caches compilation databases loaded from directories(keys are
@@ -67,6 +69,9 @@
   llvm::StringMap ExtraFlagsForFile;
   /// Used for logging.
   clangd::Logger 
+  /// Used for command argument pointing to folder where compile_commands.json
+  /// is located.
+  llvm::Optional CompileCommandsDir;
 };
 } // namespace clangd
 } // namespace clang
Index: clangd/GlobalCompilationDatabase.cpp
===
--- clangd/GlobalCompilationDatabase.cpp
+++ clangd/GlobalCompilationDatabase.cpp
@@ -38,8 +38,9 @@
 }
 
 DirectoryBasedGlobalCompilationDatabase::
-DirectoryBasedGlobalCompilationDatabase(clangd::Logger )
-: Logger(Logger) {}
+DirectoryBasedGlobalCompilationDatabase(
+clangd::Logger , llvm::Optional NewCompileCommandsDir)
+: Logger(Logger), CompileCommandsDir(NewCompileCommandsDir) {}
 
 std::vector
 DirectoryBasedGlobalCompilationDatabase::getCompileCommands(PathRef File) {
@@ -67,34 +68,48 @@
 }
 
 tooling::CompilationDatabase *
-DirectoryBasedGlobalCompilationDatabase::getCompilationDatabase(PathRef File) {
-  std::lock_guard Lock(Mutex);
+DirectoryBasedGlobalCompilationDatabase::tryLoadDatabaseFromPath(PathRef File) {
 
   namespace path = llvm::sys::path;
+  auto CachedIt = 

[PATCH] D36150: [clangd] LSP extension to switch between source/header file

2017-09-25 Thread William Enright via Phabricator via cfe-commits
Nebiroth added a comment.

In https://reviews.llvm.org/D36150#879194, @ilya-biryukov wrote:

> Looks good.
>  Do you want me to submit this patch for you?


Yes please.


https://reviews.llvm.org/D36150



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D36150: [clangd] LSP extension to switch between source/header file

2017-09-22 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 116387.
Nebiroth marked 2 inline comments as done.
Nebiroth added a comment.

Rebased on latest version.
Corrected code style issues in test file.


https://reviews.llvm.org/D36150

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  unittests/clangd/ClangdTests.cpp

Index: unittests/clangd/ClangdTests.cpp
===
--- unittests/clangd/ClangdTests.cpp
+++ unittests/clangd/ClangdTests.cpp
@@ -7,6 +7,7 @@
 //
 //===--===//
 
+#include "ClangdLSPServer.h"
 #include "ClangdServer.h"
 #include "Logger.h"
 #include "clang/Basic/VirtualFileSystem.h"
@@ -899,6 +900,84 @@
   }
 }
 
+TEST_F(ClangdVFSTest, CheckSourceHeaderSwitch) {
+  MockFSProvider FS;
+  ErrorCheckingDiagConsumer DiagConsumer;
+  MockCompilationDatabase CDB(/*AddFreestandingFlag=*/true);
+
+  ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(),
+  /*SnippetCompletions=*/false, EmptyLogger::getInstance());
+
+  auto SourceContents = R"cpp(
+  #include "foo.h"
+  int b = a;
+  )cpp";
+
+  auto FooCpp = getVirtualTestFilePath("foo.cpp");
+  auto FooH = getVirtualTestFilePath("foo.h");
+  auto Invalid = getVirtualTestFilePath("main.cpp");
+
+  FS.Files[FooCpp] = SourceContents;
+  FS.Files[FooH] = "int a;";
+  FS.Files[Invalid] = "int main() { \n return 0; \n }";
+
+  llvm::Optional PathResult = Server.switchSourceHeader(FooCpp);
+  EXPECT_TRUE(PathResult.hasValue());
+  ASSERT_EQ(PathResult.getValue(), FooH);
+
+  PathResult = Server.switchSourceHeader(FooH);
+  EXPECT_TRUE(PathResult.hasValue());
+  ASSERT_EQ(PathResult.getValue(), FooCpp);
+
+  SourceContents = R"c(
+  #include "foo.HH"
+  int b = a;
+  )c";
+
+  // Test with header file in capital letters and different extension, source
+  // file with different extension
+  auto FooC = getVirtualTestFilePath("bar.c");
+  auto FooHH = getVirtualTestFilePath("bar.HH");
+
+  FS.Files[FooC] = SourceContents;
+  FS.Files[FooHH] = "int a;";
+
+  PathResult = Server.switchSourceHeader(FooC);
+  EXPECT_TRUE(PathResult.hasValue());
+  ASSERT_EQ(PathResult.getValue(), FooHH);
+
+  // Test with both capital letters
+  auto Foo2C = getVirtualTestFilePath("foo2.C");
+  auto Foo2HH = getVirtualTestFilePath("foo2.HH");
+  FS.Files[Foo2C] = SourceContents;
+  FS.Files[Foo2HH] = "int a;";
+
+  PathResult = Server.switchSourceHeader(Foo2C);
+  EXPECT_TRUE(PathResult.hasValue());
+  ASSERT_EQ(PathResult.getValue(), Foo2HH);
+
+  // Test with source file as capital letter and .hxx header file
+  auto Foo3C = getVirtualTestFilePath("foo3.C");
+  auto Foo3HXX = getVirtualTestFilePath("foo3.hxx");
+
+  SourceContents = R"c(
+  #include "foo3.hxx"
+  int b = a;
+  )c";
+
+  FS.Files[Foo3C] = SourceContents;
+  FS.Files[Foo3HXX] = "int a;";
+
+  PathResult = Server.switchSourceHeader(Foo3C);
+  EXPECT_TRUE(PathResult.hasValue());
+  ASSERT_EQ(PathResult.getValue(), Foo3HXX);
+
+  // Test if asking for a corresponding file that doesn't exist returns an empty
+  // string.
+  PathResult = Server.switchSourceHeader(Invalid);
+  EXPECT_FALSE(PathResult.hasValue());
+}
+
 TEST_F(ClangdThreadingTest, NoConcurrentDiagnostics) {
   class NoConcurrentAccessDiagConsumer : public DiagnosticsConsumer {
   public:
Index: clangd/ProtocolHandlers.h
===
--- clangd/ProtocolHandlers.h
+++ clangd/ProtocolHandlers.h
@@ -48,6 +48,8 @@
 JSONOutput ) = 0;
   virtual void onGoToDefinition(TextDocumentPositionParams Params, StringRef ID,
 JSONOutput ) = 0;
+  virtual void onSwitchSourceHeader(TextDocumentIdentifier Params, StringRef ID,
+JSONOutput ) = 0;  
 };
 
 void regiterCallbackHandlers(JSONRPCDispatcher , JSONOutput ,
Index: clangd/ProtocolHandlers.cpp
===
--- clangd/ProtocolHandlers.cpp
+++ clangd/ProtocolHandlers.cpp
@@ -204,6 +204,22 @@
   ProtocolCallbacks 
 };
 
+struct SwitchSourceHeaderHandler : Handler {
+  SwitchSourceHeaderHandler(JSONOutput , ProtocolCallbacks )
+  : Handler(Output), Callbacks(Callbacks) {}
+
+  void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override {
+auto TDPP = TextDocumentIdentifier::parse(Params, Output);
+if (!TDPP)
+  return;
+
+Callbacks.onSwitchSourceHeader(*TDPP, ID, Output);
+  }
+
+private:
+  ProtocolCallbacks 
+};
+
 } // namespace
 
 void clangd::regiterCallbackHandlers(JSONRPCDispatcher ,
@@ -240,4 +256,7 @@
   Dispatcher.registerHandler(
   "textDocument/definition",
   llvm::make_unique(Out, Callbacks));
+  Dispatcher.registerHandler(
+  "textDocument/switchSourceHeader",
+  

[PATCH] D37150: [clangd] Command line arg to specify compile_commands.json path

2017-09-21 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 116198.
Nebiroth added a comment.

More consistent logging in clangdmain.
Restructured argument checking in ClangdMain
Fixed empty compile-commands-dir triggering error messages.
Fixed failing standard tests.


https://reviews.llvm.org/D37150

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/GlobalCompilationDatabase.cpp
  clangd/GlobalCompilationDatabase.h
  clangd/tool/ClangdMain.cpp

Index: clangd/tool/ClangdMain.cpp
===
--- clangd/tool/ClangdMain.cpp
+++ clangd/tool/ClangdMain.cpp
@@ -11,16 +11,24 @@
 #include "JSONRPCDispatcher.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
-
 #include 
 #include 
 #include 
 #include 
+#include 
 
 using namespace clang;
 using namespace clang::clangd;
 
+static llvm::cl::opt CompileCommandsDir(
+"compile-commands-dir",
+llvm::cl::desc("Specify a path to look for compile_commands.json. If path "
+   "is invalid, clangd will look in the current directory and "
+   "parent paths of each source file."));
+
+
 static llvm::cl::opt
 WorkerThreadsCount("j",
llvm::cl::desc("Number of async workers used by clangd"),
@@ -56,18 +64,44 @@
   if (RunSynchronously)
 WorkerThreadsCount = 0;
 
+  /// Validate command line arguments.
   llvm::raw_ostream  = llvm::outs();
   llvm::raw_ostream  = llvm::errs();
-  JSONOutput Out(Outs, Logs);
+  JSONOutput Out(Outs, Logs);  
 
-  // Change stdin to binary to not lose \r\n on windows.
-  llvm::sys::ChangeStdinToBinary();
+  // If --compile-commands-dir arg was invoked, check value and override default
+  // path.
+  namespace path = llvm::sys::path;
+  llvm::Optional CompileCommandsDirPath;
+
+  if (CompileCommandsDir.empty())
+CompileCommandsDirPath = llvm::None;
+  else
+  {
+if (!llvm::sys::path::is_absolute(CompileCommandsDir)) {
+  llvm::errs() << "Path specified by --compile-commands-dir must be an absolute "
+  "path. The argument will be ignored.\n";
+  CompileCommandsDir = "";
+}
+
+if (!llvm::sys::fs::exists(CompileCommandsDir)) {
+  llvm::errs() << "Path specified by --compile-commands-dir does not exist. The argument will be "
+  "ignored.\n";
+  CompileCommandsDir = "";
+}
+CompileCommandsDirPath = CompileCommandsDir;
+  }  
 
   llvm::Optional ResourceDirRef = None;
   if (!ResourceDir.empty())
 ResourceDirRef = ResourceDir;
 
+  /// Change stdin to binary to not lose \r\n on windows.
+  llvm::sys::ChangeStdinToBinary();  
+
+  /// Initialize and run ClangdLSPServer.
+
   ClangdLSPServer LSPServer(Out, WorkerThreadsCount, EnableSnippets,
-ResourceDirRef);
+ResourceDirRef, CompileCommandsDirPath);
   LSPServer.run(std::cin);
 }
Index: clangd/GlobalCompilationDatabase.h
===
--- clangd/GlobalCompilationDatabase.h
+++ clangd/GlobalCompilationDatabase.h
@@ -45,14 +45,19 @@
 class DirectoryBasedGlobalCompilationDatabase
 : public GlobalCompilationDatabase {
 public:
+  DirectoryBasedGlobalCompilationDatabase(
+  llvm::Optional NewCompileCommandsDir)
+  : CompileCommandsDir(NewCompileCommandsDir) {}
   std::vector
   getCompileCommands(PathRef File) override;
 
   void setExtraFlagsForFile(PathRef File, std::vector ExtraFlags);
 
 private:
-  tooling::CompilationDatabase *getCompilationDatabase(PathRef File);
+  tooling::CompilationDatabase *getCompilationDatabase(PathRef File);  
+  tooling::CompilationDatabase *tryLoadDatabaseFromPath(PathRef File);
 
+  llvm::Optional CompileCommandsDir;
   std::mutex Mutex;
   /// Caches compilation databases loaded from directories(keys are
   /// directories).
Index: clangd/GlobalCompilationDatabase.cpp
===
--- clangd/GlobalCompilationDatabase.cpp
+++ clangd/GlobalCompilationDatabase.cpp
@@ -62,43 +62,54 @@
 }
 
 tooling::CompilationDatabase *
-DirectoryBasedGlobalCompilationDatabase::getCompilationDatabase(PathRef File) {
-  std::lock_guard Lock(Mutex);
-
+DirectoryBasedGlobalCompilationDatabase::tryLoadDatabaseFromPath(PathRef File) {
+  
   namespace path = llvm::sys::path;
+  auto CachedIt = CompilationDatabases.find(File);
+  std::string Error = "";
 
   assert((path::is_absolute(File, path::Style::posix) ||
   path::is_absolute(File, path::Style::windows)) &&
  "path must be absolute");
 
-  for (auto Path = path::parent_path(File); !Path.empty();
-   Path = path::parent_path(Path)) {
-
-auto CachedIt = CompilationDatabases.find(Path);
-if (CachedIt != CompilationDatabases.end())
-  return CachedIt->second.get();
-std::string Error;
-auto CDB = 

[PATCH] D36150: [clangd] LSP extension to switch between source/header file

2017-09-20 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 116038.
Nebiroth added a comment.

Added unit test.


https://reviews.llvm.org/D36150

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  unittests/clangd/ClangdTests.cpp

Index: unittests/clangd/ClangdTests.cpp
===
--- unittests/clangd/ClangdTests.cpp
+++ unittests/clangd/ClangdTests.cpp
@@ -892,5 +892,83 @@
   }
 }
 
+TEST_F(ClangdVFSTest, CheckSourceHeaderSwitch) {
+  MockFSProvider FS;
+  ErrorCheckingDiagConsumer DiagConsumer;
+  MockCompilationDatabase CDB(/*AddFreestandingFlag=*/true);
+
+  ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(),
+  /*SnippetCompletions=*/false);
+
+  auto SourceContents = R"cpp(
+  #include "foo.h"
+  int b = a;
+  )cpp";
+
+  auto FooCpp = getVirtualTestFilePath("foo.cpp");
+  auto FooH = getVirtualTestFilePath("foo.h");
+  auto invalid = getVirtualTestFilePath("main.cpp");
+
+  FS.Files[FooCpp] = SourceContents;
+  FS.Files[FooH] = "int a;";   
+  FS.Files[invalid] = "int main() { \n return 0; \n }";
+
+  llvm::Optional pathResult = Server.switchSourceHeader(FooCpp);
+  EXPECT_TRUE(pathResult.hasValue());
+  ASSERT_EQ(pathResult.getValue(), FooH);
+
+  pathResult = Server.switchSourceHeader(FooH);
+  EXPECT_TRUE(pathResult.hasValue());
+  ASSERT_EQ(pathResult.getValue(), FooCpp);
+
+  SourceContents = R"c(
+  #include "foo.HH"
+  int b = a;
+  )c";
+
+  // Test with header file in capital letters and different extension, source file with different extension
+  auto FooC = getVirtualTestFilePath("bar.c");
+  auto FooHH = getVirtualTestFilePath("bar.HH");
+
+  FS.Files[FooC] = SourceContents; 
+  FS.Files[FooHH] = "int a;";
+
+  pathResult = Server.switchSourceHeader(FooC);
+  EXPECT_TRUE(pathResult.hasValue());
+  ASSERT_EQ(pathResult.getValue(), FooHH);
+
+  // Test with both capital letters
+  auto Foo2C = getVirtualTestFilePath("foo2.C");
+  auto Foo2HH = getVirtualTestFilePath("foo2.HH");
+  FS.Files[Foo2C] = SourceContents;
+  FS.Files[Foo2HH] = "int a;"; 
+
+  pathResult = Server.switchSourceHeader(Foo2C);
+  EXPECT_TRUE(pathResult.hasValue());
+  ASSERT_EQ(pathResult.getValue(), Foo2HH);
+
+  // Test with source file as capital letter and .hxx header file
+  auto Foo3C = getVirtualTestFilePath("foo3.C");
+  auto Foo3HXX = getVirtualTestFilePath("foo3.hxx");
+
+  SourceContents = R"c(
+  #include "foo3.hxx"
+  int b = a;
+  )c";
+
+  FS.Files[Foo3C] = SourceContents;
+  FS.Files[Foo3HXX] = "int a;"; 
+
+  pathResult = Server.switchSourceHeader(Foo3C);
+  EXPECT_TRUE(pathResult.hasValue());
+  ASSERT_EQ(pathResult.getValue(), Foo3HXX);
+  
+
+  // Test if asking for a corresponding file that doesn't exist returns an empty string.
+  pathResult = Server.switchSourceHeader(invalid);
+  EXPECT_FALSE(pathResult.hasValue());
+
+} 
+
 } // namespace clangd
 } // namespace clang
Index: clangd/ProtocolHandlers.h
===
--- clangd/ProtocolHandlers.h
+++ clangd/ProtocolHandlers.h
@@ -48,6 +48,8 @@
 JSONOutput ) = 0;
   virtual void onGoToDefinition(TextDocumentPositionParams Params, StringRef ID,
 JSONOutput ) = 0;
+  virtual void onSwitchSourceHeader(TextDocumentIdentifier Params, StringRef ID,
+JSONOutput ) = 0;  
 };
 
 void regiterCallbackHandlers(JSONRPCDispatcher , JSONOutput ,
Index: clangd/ProtocolHandlers.cpp
===
--- clangd/ProtocolHandlers.cpp
+++ clangd/ProtocolHandlers.cpp
@@ -204,6 +204,22 @@
   ProtocolCallbacks 
 };
 
+struct SwitchSourceHeaderHandler : Handler {
+  SwitchSourceHeaderHandler(JSONOutput , ProtocolCallbacks )
+  : Handler(Output), Callbacks(Callbacks) {}
+
+  void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override {
+auto TDPP = TextDocumentIdentifier::parse(Params);
+if (!TDPP)
+  return;
+
+Callbacks.onSwitchSourceHeader(*TDPP, ID, Output);
+  }
+
+private:
+  ProtocolCallbacks 
+};
+
 } // namespace
 
 void clangd::regiterCallbackHandlers(JSONRPCDispatcher ,
@@ -240,4 +256,7 @@
   Dispatcher.registerHandler(
   "textDocument/definition",
   llvm::make_unique(Out, Callbacks));
+  Dispatcher.registerHandler(
+  "textDocument/switchSourceHeader",
+  llvm::make_unique(Out, Callbacks));
 }
Index: clangd/ClangdServer.h
===
--- clangd/ClangdServer.h
+++ clangd/ClangdServer.h
@@ -241,6 +241,10 @@
   /// Get definition of symbol at a specified \p Line and \p Column in \p File.
   Tagged findDefinitions(PathRef File, Position Pos);
 
+  /// Helper function that returns a path to the corresponding source file when
+  /// 

[PATCH] D36150: [clangd] LSP extension to switch between source/header file

2017-09-19 Thread William Enright via Phabricator via cfe-commits
Nebiroth added a comment.

In https://reviews.llvm.org/D36150#867971, @ilya-biryukov wrote:

> Overall looks good, but still needs at least a few tests.


I have a test for this commit that uses included source and header files, would 
that be okay to do or should I generate files dynamically? If so, how can I 
accomplish this?


https://reviews.llvm.org/D36150



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D37150: [clangd] Command line arg to specify compile_commands.json path

2017-09-15 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 115462.
Nebiroth marked an inline comment as done.
Nebiroth added a comment.

Fixed a few comments.
Rebased on latest clangd version.


https://reviews.llvm.org/D37150

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/GlobalCompilationDatabase.cpp
  clangd/GlobalCompilationDatabase.h
  clangd/tool/ClangdMain.cpp

Index: clangd/tool/ClangdMain.cpp
===
--- clangd/tool/ClangdMain.cpp
+++ clangd/tool/ClangdMain.cpp
@@ -11,16 +11,23 @@
 #include "JSONRPCDispatcher.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
-
 #include 
 #include 
 #include 
 #include 
 
 using namespace clang;
 using namespace clang::clangd;
 
+static llvm::cl::opt CompileCommandsDir(
+"compile-commands-dir",
+llvm::cl::desc("Specify a path to look for compile_commands.json. If path "
+   "is invalid, clangd will look in the current directory and "
+   "parent paths of each source file."));
+
+
 static llvm::cl::opt
 WorkerThreadsCount("j",
llvm::cl::desc("Number of async workers used by clangd"),
@@ -59,15 +66,37 @@
   llvm::raw_ostream  = llvm::outs();
   llvm::raw_ostream  = llvm::errs();
   JSONOutput Out(Outs, Logs);
-
+  
   // Change stdin to binary to not lose \r\n on windows.
   llvm::sys::ChangeStdinToBinary();
 
+  // If --compile-commands-dir arg was invoked, check value and override default
+  // path.
+  namespace path = llvm::sys::path;
+
+  if (!llvm::sys::path::is_absolute(CompileCommandsDir)) {
+Out.log("Path specified by --compile-commands-dir must be an absolute "
+"path. The argument will be ignored.\n");
+CompileCommandsDir = "";
+  }
+
+  if (!llvm::sys::fs::exists(CompileCommandsDir)) {
+Out.log("Path specified by --compile-commands-dir does not exist. The argument will be "
+"ignored.\n");
+CompileCommandsDir = "";
+  }  
+  llvm::Optional CompileCommandsDirPath;
+
+  if (CompileCommandsDir.empty())
+CompileCommandsDirPath = llvm::None;
+  else
+CompileCommandsDirPath = CompileCommandsDir;
+
   llvm::Optional ResourceDirRef = None;
   if (!ResourceDir.empty())
 ResourceDirRef = ResourceDir;
 
   ClangdLSPServer LSPServer(Out, WorkerThreadsCount, EnableSnippets,
-ResourceDirRef);
+ResourceDirRef, CompileCommandsDirPath);
   LSPServer.run(std::cin);
 }
Index: clangd/GlobalCompilationDatabase.h
===
--- clangd/GlobalCompilationDatabase.h
+++ clangd/GlobalCompilationDatabase.h
@@ -45,14 +45,19 @@
 class DirectoryBasedGlobalCompilationDatabase
 : public GlobalCompilationDatabase {
 public:
+  DirectoryBasedGlobalCompilationDatabase(
+  llvm::Optional NewCompileCommandsDir)
+  : CompileCommandsDir(NewCompileCommandsDir) {}
   std::vector
   getCompileCommands(PathRef File) override;
 
   void setExtraFlagsForFile(PathRef File, std::vector ExtraFlags);
 
 private:
-  tooling::CompilationDatabase *getCompilationDatabase(PathRef File);
+  tooling::CompilationDatabase *getCompilationDatabase(PathRef File);  
+  tooling::CompilationDatabase *tryLoadDatabaseFromPath(PathRef File);
 
+  llvm::Optional CompileCommandsDir;
   std::mutex Mutex;
   /// Caches compilation databases loaded from directories(keys are
   /// directories).
Index: clangd/GlobalCompilationDatabase.cpp
===
--- clangd/GlobalCompilationDatabase.cpp
+++ clangd/GlobalCompilationDatabase.cpp
@@ -62,43 +62,50 @@
 }
 
 tooling::CompilationDatabase *
-DirectoryBasedGlobalCompilationDatabase::getCompilationDatabase(PathRef File) {
-  std::lock_guard Lock(Mutex);
-
+DirectoryBasedGlobalCompilationDatabase::tryLoadDatabaseFromPath(PathRef File) {
   namespace path = llvm::sys::path;
+  auto CachedIt = CompilationDatabases.find(File);
+  std::string Error = "";
 
   assert((path::is_absolute(File, path::Style::posix) ||
   path::is_absolute(File, path::Style::windows)) &&
  "path must be absolute");
 
-  for (auto Path = path::parent_path(File); !Path.empty();
-   Path = path::parent_path(Path)) {
-
-auto CachedIt = CompilationDatabases.find(Path);
-if (CachedIt != CompilationDatabases.end())
-  return CachedIt->second.get();
-std::string Error;
-auto CDB = tooling::CompilationDatabase::loadFromDirectory(Path, Error);
-if (!CDB) {
-  if (!Error.empty()) {
-// FIXME(ibiryukov): logging
-// Output.log("Error when trying to load compilation database from " +
-//Twine(Path) + ": " + Twine(Error) + "\n");
-  }
-  continue;
-}
+  if (CachedIt != CompilationDatabases.end())
+return CachedIt->second.get();
+  auto CDB = 

[PATCH] D37150: [clangd] Command line arg to specify compile_commands.json path

2017-09-11 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 114654.
Nebiroth added a comment.

Simpilified a pointer return value.


https://reviews.llvm.org/D37150

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/GlobalCompilationDatabase.cpp
  clangd/GlobalCompilationDatabase.h
  clangd/tool/ClangdMain.cpp

Index: clangd/tool/ClangdMain.cpp
===
--- clangd/tool/ClangdMain.cpp
+++ clangd/tool/ClangdMain.cpp
@@ -11,8 +11,8 @@
 #include "JSONRPCDispatcher.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
-
 #include 
 #include 
 #include 
@@ -25,16 +25,43 @@
  llvm::cl::desc("parse on main thread"),
  llvm::cl::init(false), llvm::cl::Hidden);
 
+static llvm::cl::opt CompileCommandsDir(
+"compile-commands-dir",
+llvm::cl::desc("Specify a path to look for compile_commands.json. If path "
+   "is invalid, clangd will look in the current directory and "
+   "parent paths of each source file."));
+
 int main(int argc, char *argv[]) {
   llvm::cl::ParseCommandLineOptions(argc, argv, "clangd");
 
   llvm::raw_ostream  = llvm::outs();
   llvm::raw_ostream  = llvm::errs();
   JSONOutput Out(Outs, Logs);
 
+  // If --compile-commands-dir arg was invoked, check value and override default
+  // path.
+  namespace path = llvm::sys::path;
+
+  if (!llvm::sys::path::is_absolute(CompileCommandsDir)) {
+Out.log("Path specified by --compile-commands-dir must be an absolute "
+"path. The argument will be ignored.\n");
+CompileCommandsDir = "";
+  }
+
+  if (!llvm::sys::fs::exists(CompileCommandsDir)) {
+Out.log("Path specified by --compile-commands-dir. The argument will be "
+"ignored.\n");
+CompileCommandsDir = "";
+  }
+  llvm::Optional CompileCommandsDirPath;
+
   // Change stdin to binary to not lose \r\n on windows.
   llvm::sys::ChangeStdinToBinary();
+  if (CompileCommandsDir.empty())
+CompileCommandsDirPath = llvm::None;
+  else
+CompileCommandsDirPath = CompileCommandsDir;
 
-  ClangdLSPServer LSPServer(Out, RunSynchronously);
+  ClangdLSPServer LSPServer(Out, RunSynchronously, CompileCommandsDirPath);
   LSPServer.run(std::cin);
 }
Index: clangd/GlobalCompilationDatabase.h
===
--- clangd/GlobalCompilationDatabase.h
+++ clangd/GlobalCompilationDatabase.h
@@ -45,13 +45,18 @@
 class DirectoryBasedGlobalCompilationDatabase
 : public GlobalCompilationDatabase {
 public:
+  DirectoryBasedGlobalCompilationDatabase(
+  llvm::Optional NewCompileCommandsDir)
+  : CompileCommandsDir(NewCompileCommandsDir.getValue()) {}
   std::vector
   getCompileCommands(PathRef File) override;
 
   void setExtraFlagsForFile(PathRef File, std::vector ExtraFlags);
 
 private:
   tooling::CompilationDatabase *getCompilationDatabase(PathRef File);
+  Path CompileCommandsDir;
+  tooling::CompilationDatabase *tryLoadDatabaseFromPath(PathRef File);
 
   std::mutex Mutex;
   /// Caches compilation databases loaded from directories(keys are
Index: clangd/GlobalCompilationDatabase.cpp
===
--- clangd/GlobalCompilationDatabase.cpp
+++ clangd/GlobalCompilationDatabase.cpp
@@ -62,43 +62,52 @@
 }
 
 tooling::CompilationDatabase *
-DirectoryBasedGlobalCompilationDatabase::getCompilationDatabase(PathRef File) {
-  std::lock_guard Lock(Mutex);
-
+DirectoryBasedGlobalCompilationDatabase::tryLoadDatabaseFromPath(PathRef File) {
   namespace path = llvm::sys::path;
+  auto CachedIt = CompilationDatabases.find(File);
+  std::string Error = "";
 
   assert((path::is_absolute(File, path::Style::posix) ||
   path::is_absolute(File, path::Style::windows)) &&
  "path must be absolute");
 
-  for (auto Path = path::parent_path(File); !Path.empty();
-   Path = path::parent_path(Path)) {
-
-auto CachedIt = CompilationDatabases.find(Path);
-if (CachedIt != CompilationDatabases.end())
-  return CachedIt->second.get();
-std::string Error;
-auto CDB = tooling::CompilationDatabase::loadFromDirectory(Path, Error);
-if (!CDB) {
-  if (!Error.empty()) {
-// FIXME(ibiryukov): logging
-// Output.log("Error when trying to load compilation database from " +
-//Twine(Path) + ": " + Twine(Error) + "\n");
-  }
-  continue;
-}
+  if (CachedIt != CompilationDatabases.end())
+return (CachedIt->second.get());
+  auto CDB = tooling::CompilationDatabase::loadFromDirectory(File, Error);
+  if (CDB && Error.empty()) {
+auto result = CDB.get();
+CompilationDatabases.insert(std::make_pair(File, std::move(CDB)));
 
 // FIXME(ibiryukov): Invalidate cached compilation databases on changes
-auto result = CDB.get();
-

[PATCH] D36150: [clangd] LSP extension to switch between source/header file

2017-09-11 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 114652.
Nebiroth added a comment.

Return value when no file is found is now an empty string instead of file://
Minor code style changes and cleanup.
Ran clang-format on ClangdServer.h


https://reviews.llvm.org/D36150

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  clangd/tool/ClangdMain.cpp

Index: clangd/tool/ClangdMain.cpp
===
--- clangd/tool/ClangdMain.cpp
+++ clangd/tool/ClangdMain.cpp
@@ -12,7 +12,6 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Program.h"
-
 #include 
 #include 
 #include 
Index: clangd/ProtocolHandlers.h
===
--- clangd/ProtocolHandlers.h
+++ clangd/ProtocolHandlers.h
@@ -47,7 +47,9 @@
   virtual void onCompletion(TextDocumentPositionParams Params, StringRef ID,
 JSONOutput ) = 0;
   virtual void onGoToDefinition(TextDocumentPositionParams Params, StringRef ID,
-JSONOutput ) = 0;
+JSONOutput ) = 0;
+  virtual void onSwitchSourceHeader(TextDocumentIdentifier Params, StringRef ID,
+JSONOutput ) = 0;
 };
 
 void regiterCallbackHandlers(JSONRPCDispatcher , JSONOutput ,
Index: clangd/ProtocolHandlers.cpp
===
--- clangd/ProtocolHandlers.cpp
+++ clangd/ProtocolHandlers.cpp
@@ -204,6 +204,22 @@
   ProtocolCallbacks 
 };
 
+struct SwitchSourceHeaderHandler : Handler {
+  SwitchSourceHeaderHandler(JSONOutput , ProtocolCallbacks )
+  : Handler(Output), Callbacks(Callbacks) {}
+
+  void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override {
+auto TDPP = TextDocumentIdentifier::parse(Params);
+if (!TDPP)
+  return;
+
+Callbacks.onSwitchSourceHeader(*TDPP, ID, Output);
+  }
+
+private:
+  ProtocolCallbacks 
+};
+
 } // namespace
 
 void clangd::regiterCallbackHandlers(JSONRPCDispatcher ,
@@ -237,6 +253,10 @@
   Dispatcher.registerHandler(
   "textDocument/completion",
   llvm::make_unique(Out, Callbacks));
-  Dispatcher.registerHandler("textDocument/definition",
+  Dispatcher.registerHandler(
+  "textDocument/definition",
   llvm::make_unique(Out, Callbacks));
+  Dispatcher.registerHandler(
+  "textDocument/switchSourceHeader",
+  llvm::make_unique(Out, Callbacks));
 }
Index: clangd/ClangdServer.h
===
--- clangd/ClangdServer.h
+++ clangd/ClangdServer.h
@@ -182,6 +182,10 @@
   /// Get definition of symbol at a specified \p Line and \p Column in \p File.
   Tagged findDefinitions(PathRef File, Position Pos);
 
+  /// Helper function that returns a path to the corresponding source file when
+  /// given a header file and vice versa.
+  llvm::Optional switchSourceHeader(PathRef Path);
+
   /// Run formatting for \p Rng inside \p File.
   std::vector formatRange(PathRef File, Range Rng);
   /// Run formatting for the whole \p File.
Index: clangd/ClangdServer.cpp
===
--- clangd/ClangdServer.cpp
+++ clangd/ClangdServer.cpp
@@ -15,6 +15,7 @@
 #include "clang/Tooling/CompilationDatabase.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 #include 
 
@@ -273,16 +274,76 @@
   return DumpFuture.get();
 }
 
-Tagged
-ClangdServer::findDefinitions(PathRef File, Position Pos) {
+Tagged ClangdServer::findDefinitions(PathRef File,
+Position Pos) {
   auto FileContents = DraftMgr.getDraft(File);
-  assert(FileContents.Draft && "findDefinitions is called for non-added document");
+  assert(FileContents.Draft &&
+ "findDefinitions is called for non-added document");
 
   std::vector Result;
   auto TaggedFS = FSProvider.getTaggedFileSystem(File);
-  Units.runOnUnit(File, *FileContents.Draft, ResourceDir, CDB, PCHs,
-  TaggedFS.Value, [&](ClangdUnit ) {
-Result = Unit.findDefinitions(Pos);
-  });
+  Units.runOnUnit(
+  File, *FileContents.Draft, ResourceDir, CDB, PCHs, TaggedFS.Value,
+  [&](ClangdUnit ) { Result = Unit.findDefinitions(Pos); });
   return make_tagged(std::move(Result), TaggedFS.Tag);
 }
+
+llvm::Optional ClangdServer::switchSourceHeader(PathRef Path) {
+
+  StringRef SourceExtensions[] = {".cpp", ".c", ".cc", ".cxx",
+  ".c++", ".m", ".mm"};
+  StringRef HeaderExtensions[] = {".h", ".hh", ".hpp", ".hxx", ".inc"};
+
+  StringRef PathExt = llvm::sys::path::extension(Path);
+
+  // Lookup in a list of known extensions.
+  auto SourceIter =
+  

[PATCH] D36150: [clangd] LSP extension to switch between source/header file

2017-09-11 Thread William Enright via Phabricator via cfe-commits
Nebiroth marked 5 inline comments as done.
Nebiroth added inline comments.



Comment at: clangd/ClangdLSPServer.cpp:234
+  else
+ResultUri = URI::fromFile("");
+

ilya-biryukov wrote:
> Running `unparse` on an instance created via `URI::fromFile("")`  will result 
> in `"file:///"`. 
> 
> Have you considered returning a list of paths as a result from 
> `switchHeaderSource`?
> That way you could capture the "no file matched" case with an empty list.
> Later when an implementation will look into index, that would allow to return 
> multiple source files for a header file, which also  happens in some C++ 
> projects.
> 
> Returning an empty string is also an option we could start with.
I think I will start by returning an empty string for now. Returning a list of 
paths sounds like a good idea once an indexer is implemented, but that would 
require changing some parts of the code like find_if which returns only the 
first instance of a match.


https://reviews.llvm.org/D36150



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D36150: [clangd] LSP extension to switch between source/header file

2017-09-08 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 114424.
Nebiroth marked 7 inline comments as done.
Nebiroth added a comment.

Ran clang-format on modified files.
Minor refactoring.


https://reviews.llvm.org/D36150

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  clangd/tool/ClangdMain.cpp

Index: clangd/tool/ClangdMain.cpp
===
--- clangd/tool/ClangdMain.cpp
+++ clangd/tool/ClangdMain.cpp
@@ -12,7 +12,6 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Program.h"
-
 #include 
 #include 
 #include 
Index: clangd/ProtocolHandlers.h
===
--- clangd/ProtocolHandlers.h
+++ clangd/ProtocolHandlers.h
@@ -47,7 +47,9 @@
   virtual void onCompletion(TextDocumentPositionParams Params, StringRef ID,
 JSONOutput ) = 0;
   virtual void onGoToDefinition(TextDocumentPositionParams Params, StringRef ID,
-JSONOutput ) = 0;
+JSONOutput ) = 0;
+  virtual void onSwitchSourceHeader(TextDocumentIdentifier Params, StringRef ID,
+JSONOutput ) = 0;
 };
 
 void regiterCallbackHandlers(JSONRPCDispatcher , JSONOutput ,
Index: clangd/ProtocolHandlers.cpp
===
--- clangd/ProtocolHandlers.cpp
+++ clangd/ProtocolHandlers.cpp
@@ -204,6 +204,22 @@
   ProtocolCallbacks 
 };
 
+struct SwitchSourceHeaderHandler : Handler {
+  SwitchSourceHeaderHandler(JSONOutput , ProtocolCallbacks )
+  : Handler(Output), Callbacks(Callbacks) {}
+
+  void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override {
+auto TDPP = TextDocumentIdentifier::parse(Params);
+if (!TDPP)
+  return;
+
+Callbacks.onSwitchSourceHeader(*TDPP, ID, Output);
+  }
+
+private:
+  ProtocolCallbacks 
+};
+
 } // namespace
 
 void clangd::regiterCallbackHandlers(JSONRPCDispatcher ,
@@ -237,6 +253,10 @@
   Dispatcher.registerHandler(
   "textDocument/completion",
   llvm::make_unique(Out, Callbacks));
-  Dispatcher.registerHandler("textDocument/definition",
+  Dispatcher.registerHandler(
+  "textDocument/definition",
   llvm::make_unique(Out, Callbacks));
+  Dispatcher.registerHandler(
+  "textDocument/switchSourceHeader",
+  llvm::make_unique(Out, Callbacks));
 }
Index: clangd/ClangdServer.h
===
--- clangd/ClangdServer.h
+++ clangd/ClangdServer.h
@@ -182,6 +182,9 @@
   /// Get definition of symbol at a specified \p Line and \p Column in \p File.
   Tagged findDefinitions(PathRef File, Position Pos);
 
+  /// Helper function that returns a path to the corresponding source file when given a header file and vice versa.
+  llvm::Optional switchSourceHeader(PathRef Path);
+
   /// Run formatting for \p Rng inside \p File.
   std::vector formatRange(PathRef File, Range Rng);
   /// Run formatting for the whole \p File.
Index: clangd/ClangdServer.cpp
===
--- clangd/ClangdServer.cpp
+++ clangd/ClangdServer.cpp
@@ -15,9 +15,11 @@
 #include "clang/Tooling/CompilationDatabase.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 #include 
 
+using namespace llvm;
 using namespace clang;
 using namespace clang::clangd;
 
@@ -273,16 +275,76 @@
   return DumpFuture.get();
 }
 
-Tagged
-ClangdServer::findDefinitions(PathRef File, Position Pos) {
+Tagged ClangdServer::findDefinitions(PathRef File,
+Position Pos) {
   auto FileContents = DraftMgr.getDraft(File);
-  assert(FileContents.Draft && "findDefinitions is called for non-added document");
+  assert(FileContents.Draft &&
+ "findDefinitions is called for non-added document");
 
   std::vector Result;
   auto TaggedFS = FSProvider.getTaggedFileSystem(File);
-  Units.runOnUnit(File, *FileContents.Draft, ResourceDir, CDB, PCHs,
-  TaggedFS.Value, [&](ClangdUnit ) {
-Result = Unit.findDefinitions(Pos);
-  });
+  Units.runOnUnit(
+  File, *FileContents.Draft, ResourceDir, CDB, PCHs, TaggedFS.Value,
+  [&](ClangdUnit ) { Result = Unit.findDefinitions(Pos); });
   return make_tagged(std::move(Result), TaggedFS.Tag);
 }
+
+llvm::Optional ClangdServer::switchSourceHeader(PathRef Path) {
+
+  StringRef SourceExtensions[] = {".cpp", ".c", ".cc", ".cxx",
+  ".c++", ".m", ".mm"};
+  StringRef HeaderExtensions[] = {".h", ".hh", ".hpp", ".hxx", ".inc"};
+
+  StringRef PathExt = llvm::sys::path::extension(Path);
+
+  // Lookup in a list of known extensions.
+  auto SourceIter =
+

[PATCH] D37150: [clangd] Command line arg to specify compile_commands.json path

2017-09-08 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 114371.
Nebiroth marked 10 inline comments as done.
Nebiroth added a comment.

Ran clang-format on modified files.
More minor refactoring.


https://reviews.llvm.org/D37150

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/GlobalCompilationDatabase.cpp
  clangd/GlobalCompilationDatabase.h
  clangd/tool/ClangdMain.cpp

Index: clangd/tool/ClangdMain.cpp
===
--- clangd/tool/ClangdMain.cpp
+++ clangd/tool/ClangdMain.cpp
@@ -11,8 +11,8 @@
 #include "JSONRPCDispatcher.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
-
 #include 
 #include 
 #include 
@@ -25,16 +25,43 @@
  llvm::cl::desc("parse on main thread"),
  llvm::cl::init(false), llvm::cl::Hidden);
 
+static llvm::cl::opt CompileCommandsDir(
+"compile-commands-dir",
+llvm::cl::desc("Specify a path to look for compile_commands.json. If path "
+   "is invalid, clangd will look in the current directory and "
+   "parent paths of each source file."));
+
 int main(int argc, char *argv[]) {
   llvm::cl::ParseCommandLineOptions(argc, argv, "clangd");
 
   llvm::raw_ostream  = llvm::outs();
   llvm::raw_ostream  = llvm::errs();
   JSONOutput Out(Outs, Logs);
 
+  // If --compile-commands-dir arg was invoked, check value and override default
+  // path.
+  namespace path = llvm::sys::path;
+
+  if (!llvm::sys::path::is_absolute(CompileCommandsDir)) {
+Out.log("Path specified by --compile-commands-dir must be an absolute "
+"path. The argument will be ignored.\n");
+CompileCommandsDir = "";
+  }
+
+  if (!llvm::sys::fs::exists(CompileCommandsDir)) {
+Out.log("Path specified by --compile-commands-dir. The argument will be "
+"ignored.\n");
+CompileCommandsDir = "";
+  }
+  llvm::Optional CompileCommandsDirPath;
+
   // Change stdin to binary to not lose \r\n on windows.
   llvm::sys::ChangeStdinToBinary();
+  if (CompileCommandsDir.empty())
+CompileCommandsDirPath = llvm::None;
+  else
+CompileCommandsDirPath = CompileCommandsDir;
 
-  ClangdLSPServer LSPServer(Out, RunSynchronously);
+  ClangdLSPServer LSPServer(Out, RunSynchronously, CompileCommandsDirPath);
   LSPServer.run(std::cin);
 }
Index: clangd/GlobalCompilationDatabase.h
===
--- clangd/GlobalCompilationDatabase.h
+++ clangd/GlobalCompilationDatabase.h
@@ -45,13 +45,18 @@
 class DirectoryBasedGlobalCompilationDatabase
 : public GlobalCompilationDatabase {
 public:
+  DirectoryBasedGlobalCompilationDatabase(
+  llvm::Optional NewCompileCommandsDir)
+  : CompileCommandsDir(NewCompileCommandsDir.getValue()) {}
   std::vector
   getCompileCommands(PathRef File) override;
 
   void setExtraFlagsForFile(PathRef File, std::vector ExtraFlags);
 
 private:
   tooling::CompilationDatabase *getCompilationDatabase(PathRef File);
+  Path CompileCommandsDir;
+  tooling::CompilationDatabase *tryLoadDatabaseFromPath(PathRef File);
 
   std::mutex Mutex;
   /// Caches compilation databases loaded from directories(keys are
Index: clangd/GlobalCompilationDatabase.cpp
===
--- clangd/GlobalCompilationDatabase.cpp
+++ clangd/GlobalCompilationDatabase.cpp
@@ -62,43 +62,55 @@
 }
 
 tooling::CompilationDatabase *
-DirectoryBasedGlobalCompilationDatabase::getCompilationDatabase(PathRef File) {
-  std::lock_guard Lock(Mutex);
-
+DirectoryBasedGlobalCompilationDatabase::tryLoadDatabaseFromPath(PathRef File) {
   namespace path = llvm::sys::path;
+  auto CachedIt = CompilationDatabases.find(File);
+  std::string Error = "";
 
   assert((path::is_absolute(File, path::Style::posix) ||
   path::is_absolute(File, path::Style::windows)) &&
  "path must be absolute");
 
-  for (auto Path = path::parent_path(File); !Path.empty();
-   Path = path::parent_path(Path)) {
-
-auto CachedIt = CompilationDatabases.find(Path);
-if (CachedIt != CompilationDatabases.end())
-  return CachedIt->second.get();
-std::string Error;
-auto CDB = tooling::CompilationDatabase::loadFromDirectory(Path, Error);
-if (!CDB) {
-  if (!Error.empty()) {
-// FIXME(ibiryukov): logging
-// Output.log("Error when trying to load compilation database from " +
-//Twine(Path) + ": " + Twine(Error) + "\n");
-  }
-  continue;
-}
+  if (CachedIt != CompilationDatabases.end())
+return (CachedIt->second.get());
+  auto CDB = tooling::CompilationDatabase::loadFromDirectory(File, Error);
+  if (CDB && Error.empty()) {
+auto result = CDB.get();
+CompilationDatabases.insert(std::make_pair(File, std::move(CDB)));
 
 // FIXME(ibiryukov): Invalidate cached compilation 

[PATCH] D37150: [clangd] Command line arg to specify compile_commands.json path

2017-09-07 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 114199.
Nebiroth marked 7 inline comments as done.
Nebiroth added a comment.

Modified CompileCommandsDir to only look in the specified path if the value is 
set.
Moved CompileCommandsDir field to DirectoryBasedGlobalCompilationDatabase class.
Minor refactoring.


https://reviews.llvm.org/D37150

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/GlobalCompilationDatabase.cpp
  clangd/GlobalCompilationDatabase.h
  clangd/tool/ClangdMain.cpp

Index: clangd/tool/ClangdMain.cpp
===
--- clangd/tool/ClangdMain.cpp
+++ clangd/tool/ClangdMain.cpp
@@ -12,7 +12,7 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Program.h"
-
+#include "llvm/Support/Path.h"
 #include 
 #include 
 #include 
@@ -25,16 +25,36 @@
  llvm::cl::desc("parse on main thread"),
  llvm::cl::init(false), llvm::cl::Hidden);
 
+static llvm::cl::opt
+CompileCommandsDir("compile-commands-dir",
+ llvm::cl::desc("Specify a path to look for compile_commands.json. If path is invalid, clangd will look in the current directory and parent paths of each source file.")); 
+
+
 int main(int argc, char *argv[]) {
   llvm::cl::ParseCommandLineOptions(argc, argv, "clangd");
 
   llvm::raw_ostream  = llvm::outs();
   llvm::raw_ostream  = llvm::errs();
   JSONOutput Out(Outs, Logs);
 
+  // If --CompileCommandsDir arg was invoked, check value and override default path.
+  namespace path = llvm::sys::path;
+
+  if (!llvm::sys::path::is_absolute(CompileCommandsDir))
+  {
+Logs << "Path specified by --compile-commands-dir must be an absolute path. The argument will be ignored.\n";
+CompileCommandsDir = "";
+  }
+
+  if (!llvm::sys::fs::exists(CompileCommandsDir))
+  {
+Logs << "File does not exist. The argument will be ignored.\n";
+CompileCommandsDir = "";
+  }
+
   // Change stdin to binary to not lose \r\n on windows.
   llvm::sys::ChangeStdinToBinary();
 
-  ClangdLSPServer LSPServer(Out, RunSynchronously);
+  ClangdLSPServer LSPServer(Out, RunSynchronously, CompileCommandsDir);
   LSPServer.run(std::cin);
 }
Index: clangd/GlobalCompilationDatabase.h
===
--- clangd/GlobalCompilationDatabase.h
+++ clangd/GlobalCompilationDatabase.h
@@ -33,9 +33,9 @@
 public:
   virtual ~GlobalCompilationDatabase() = default;
 
-  virtual std::vector
+  virtual std::vector  
   getCompileCommands(PathRef File) = 0;
-
+  
   /// FIXME(ibiryukov): add facilities to track changes to compilation flags of
   /// existing targets.
 };
@@ -45,13 +45,16 @@
 class DirectoryBasedGlobalCompilationDatabase
 : public GlobalCompilationDatabase {
 public:
+  DirectoryBasedGlobalCompilationDatabase(Path NewCompileCommandsDir): CompileCommandsDir(NewCompileCommandsDir){}
   std::vector
   getCompileCommands(PathRef File) override;
 
   void setExtraFlagsForFile(PathRef File, std::vector ExtraFlags);
+  tooling::CompilationDatabase *tryLoadDatabaseFromPath(PathRef File, std::string );
 
 private:
   tooling::CompilationDatabase *getCompilationDatabase(PathRef File);
+  Path CompileCommandsDir;  
 
   std::mutex Mutex;
   /// Caches compilation databases loaded from directories(keys are
Index: clangd/GlobalCompilationDatabase.cpp
===
--- clangd/GlobalCompilationDatabase.cpp
+++ clangd/GlobalCompilationDatabase.cpp
@@ -61,37 +61,47 @@
   ExtraFlagsForFile[File] = std::move(ExtraFlags);
 }
 
+tooling::CompilationDatabase * DirectoryBasedGlobalCompilationDatabase::tryLoadDatabaseFromPath(PathRef File, std::string )
+{
+  auto CachedIt = CompilationDatabases.find(File);
+  if (CachedIt != CompilationDatabases.end())
+return (CachedIt->second.get());
+  auto CDB = tooling::CompilationDatabase::loadFromDirectory(File, Error);
+  if (CDB && Error.empty())
+  {
+auto result = CDB.get();
+CompilationDatabases.insert(std::make_pair(File, std::move(CDB)));
+return result;
+  }
+  return nullptr;
+}
+
 tooling::CompilationDatabase *
 DirectoryBasedGlobalCompilationDatabase::getCompilationDatabase(PathRef File) {
   std::lock_guard Lock(Mutex);
-
+  
   namespace path = llvm::sys::path;
-
-  assert((path::is_absolute(File, path::Style::posix) ||
-  path::is_absolute(File, path::Style::windows)) &&
- "path must be absolute");
+  std::string Error;
+  if (!CompileCommandsDir.empty()) {
+File = CompileCommandsDir;
+File = path::parent_path(File);
+auto CDB = tryLoadDatabaseFromPath(File, Error);
+
+if (CDB && Error.empty())
+  return CDB;
+else
+  return nullptr;
+  }
 
   for (auto Path = path::parent_path(File); !Path.empty();
-   Path = path::parent_path(Path)) {
-
-auto CachedIt = 

[PATCH] D36150: [clangd] LSP extension to switch between source/header file

2017-09-06 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 114054.
Nebiroth added a comment.

Some more code cleanup.


https://reviews.llvm.org/D36150

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h

Index: clangd/ProtocolHandlers.h
===
--- clangd/ProtocolHandlers.h
+++ clangd/ProtocolHandlers.h
@@ -48,6 +48,8 @@
 JSONOutput ) = 0;
   virtual void onGoToDefinition(TextDocumentPositionParams Params, StringRef ID,
 JSONOutput ) = 0;
+  virtual void onSwitchSourceHeader(TextDocumentIdentifier Params, StringRef ID,
+JSONOutput ) = 0;
 };
 
 void regiterCallbackHandlers(JSONRPCDispatcher , JSONOutput ,
Index: clangd/ProtocolHandlers.cpp
===
--- clangd/ProtocolHandlers.cpp
+++ clangd/ProtocolHandlers.cpp
@@ -204,6 +204,23 @@
   ProtocolCallbacks 
 };
 
+struct SwitchSourceHeaderHandler : Handler {
+  SwitchSourceHeaderHandler(JSONOutput , ProtocolCallbacks )
+  : Handler(Output), Callbacks(Callbacks) {}
+
+  void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override {
+auto TDPP = TextDocumentIdentifier::parse(Params);
+if (!TDPP) {
+  return;
+}
+
+Callbacks.onSwitchSourceHeader(*TDPP, ID, Output);
+  }
+
+private:
+  ProtocolCallbacks 
+};
+
 } // namespace
 
 void clangd::regiterCallbackHandlers(JSONRPCDispatcher ,
@@ -239,4 +256,7 @@
   llvm::make_unique(Out, Callbacks));
   Dispatcher.registerHandler("textDocument/definition",
   llvm::make_unique(Out, Callbacks));
+  Dispatcher.registerHandler(
+  "textDocument/switchSourceHeader",
+  llvm::make_unique(Out, Callbacks));
 }
Index: clangd/ClangdServer.h
===
--- clangd/ClangdServer.h
+++ clangd/ClangdServer.h
@@ -182,6 +182,12 @@
   /// Get definition of symbol at a specified \p Line and \p Column in \p File.
   Tagged findDefinitions(PathRef File, Position Pos);
 
+  /// If an extension hasn't been found in the lowercase array, try with uppercase.
+  bool checkUpperCaseExtensions(StringRef BaseArray[], int ArraySize, StringRef PathExt);
+
+  /// Helper function that returns a path to the corresponding source file when given a header file and vice versa.
+  llvm::Optional switchSourceHeader(PathRef Path);
+
   /// Run formatting for \p Rng inside \p File.
   std::vector formatRange(PathRef File, Range Rng);
   /// Run formatting for the whole \p File.
Index: clangd/ClangdServer.cpp
===
--- clangd/ClangdServer.cpp
+++ clangd/ClangdServer.cpp
@@ -15,9 +15,11 @@
 #include "clang/Tooling/CompilationDatabase.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 #include 
 
+using namespace llvm;
 using namespace clang;
 using namespace clang::clangd;
 
@@ -286,3 +288,89 @@
   });
   return make_tagged(std::move(Result), TaggedFS.Tag);
 }
+
+
+bool ClangdServer::checkUpperCaseExtensions(StringRef BaseArray[], int ArraySize, StringRef PathExt)
+{
+  std::string UpperExtensions[ArraySize];
+  for(int i = 0; i < ArraySize; i++)
+  {
+UpperExtensions[i] = BaseArray[i];
+  }
+  // Uppercase the whole array
+  for (std::string & s : UpperExtensions)
+  std::transform(s.begin(), s.end(), s.begin(),
+  [](unsigned char c) { return std::toupper(c); }); 
+
+  bool isUpperCase = false;
+  // Iterator such as std::begin won't work here so we use a standard loop
+  for(int i = 0; i < ArraySize; i++)
+  {
+if (UpperExtensions[i] == PathExt.str())
+{
+  isUpperCase = true;
+}
+  }
+  return isUpperCase;
+}
+
+llvm::Optional ClangdServer::switchSourceHeader(PathRef Path) {
+
+  StringRef SourceExtensions[] = {".cpp", ".c", ".cc", ".cxx", ".c++", ".m", ".mm"};
+  StringRef HeaderExtensions[] = {".h", ".hh", ".hpp", ".hxx", ".inc"};
+
+  StringRef PathExt = llvm::sys::path::extension(Path);
+  
+  // Lookup in a list of known extensions.
+  auto SourceIter = std::find(std::begin(SourceExtensions), std::end(SourceExtensions), PathExt);
+  bool IsSource = SourceIter != std::end(SourceExtensions);
+
+  if (!IsSource)
+  {
+IsSource = checkUpperCaseExtensions(SourceExtensions, llvm::array_lengthof(SourceExtensions), PathExt);
+  }
+  
+  auto HeaderIter = std::find(std::begin(HeaderExtensions), std::end(HeaderExtensions), PathExt);
+  bool IsHeader = HeaderIter != std::end(HeaderExtensions);
+
+  if (!IsHeader)
+  {
+IsHeader = checkUpperCaseExtensions(HeaderExtensions, llvm::array_lengthof(HeaderExtensions), PathExt);
+  }
+
+  // We can only switch between extensions known extensions.
+  if (!IsSource && !IsHeader)
+return llvm::None;
+
+  // Array to lookup extensions for the 

[PATCH] D36150: [clangd] LSP extension to switch between source/header file

2017-09-06 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 114048.
Nebiroth added a comment.

Remove unintentional file addition

Updating D36150: [clangd] LSP extension to switch between source/header file


ll#


https://reviews.llvm.org/D36150

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h

Index: clangd/ProtocolHandlers.h
===
--- clangd/ProtocolHandlers.h
+++ clangd/ProtocolHandlers.h
@@ -48,6 +48,8 @@
 JSONOutput ) = 0;
   virtual void onGoToDefinition(TextDocumentPositionParams Params, StringRef ID,
 JSONOutput ) = 0;
+  virtual void onSwitchSourceHeader(TextDocumentIdentifier Params, StringRef ID,
+JSONOutput ) = 0;
 };
 
 void regiterCallbackHandlers(JSONRPCDispatcher , JSONOutput ,
Index: clangd/ProtocolHandlers.cpp
===
--- clangd/ProtocolHandlers.cpp
+++ clangd/ProtocolHandlers.cpp
@@ -204,6 +204,23 @@
   ProtocolCallbacks 
 };
 
+struct SwitchSourceHeaderHandler : Handler {
+  SwitchSourceHeaderHandler(JSONOutput , ProtocolCallbacks )
+  : Handler(Output), Callbacks(Callbacks) {}
+
+  void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override {
+auto TDPP = TextDocumentIdentifier::parse(Params);
+if (!TDPP) {
+  return;
+}
+
+Callbacks.onSwitchSourceHeader(*TDPP, ID, Output);
+  }
+
+private:
+  ProtocolCallbacks 
+};
+
 } // namespace
 
 void clangd::regiterCallbackHandlers(JSONRPCDispatcher ,
@@ -239,4 +256,7 @@
   llvm::make_unique(Out, Callbacks));
   Dispatcher.registerHandler("textDocument/definition",
   llvm::make_unique(Out, Callbacks));
+  Dispatcher.registerHandler(
+  "textDocument/switchSourceHeader",
+  llvm::make_unique(Out, Callbacks));
 }
Index: clangd/ClangdServer.h
===
--- clangd/ClangdServer.h
+++ clangd/ClangdServer.h
@@ -182,6 +182,12 @@
   /// Get definition of symbol at a specified \p Line and \p Column in \p File.
   Tagged findDefinitions(PathRef File, Position Pos);
 
+  /// If an extension hasn't been found in the lowercase array, try with uppercase.
+  bool checkUpperCaseExtensions(StringRef BaseArray[], int ArraySize, StringRef PathExt);
+
+  /// Helper function that returns a path to the corresponding source file when given a header file and vice versa.
+  llvm::Optional switchSourceHeader(PathRef Path);
+
   /// Run formatting for \p Rng inside \p File.
   std::vector formatRange(PathRef File, Range Rng);
   /// Run formatting for the whole \p File.
Index: clangd/ClangdServer.cpp
===
--- clangd/ClangdServer.cpp
+++ clangd/ClangdServer.cpp
@@ -15,9 +15,11 @@
 #include "clang/Tooling/CompilationDatabase.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 #include 
 
+using namespace llvm;
 using namespace clang;
 using namespace clang::clangd;
 
@@ -286,3 +288,84 @@
   });
   return make_tagged(std::move(Result), TaggedFS.Tag);
 }
+
+
+bool ClangdServer::checkUpperCaseExtensions(StringRef BaseArray[], int ArraySize, StringRef PathExt)
+{
+  std::string UpperExtensions[ArraySize];
+  for(int i = 0; i < ArraySize; i++)
+  {
+UpperExtensions[i] = BaseArray[i];
+  }
+  // Uppercase the whole array
+  for (std::string & s : UpperExtensions)
+  std::transform(s.begin(), s.end(), s.begin(),
+  [](unsigned char c) { return std::toupper(c); }); 
+
+  bool isUpperCase = false;
+  // Iterator such as std::begin won't work here so we use a standard loop
+  for(int i = 0; i < ArraySize; i++)
+  {
+if (UpperExtensions[i] == PathExt.str())
+{
+  isUpperCase = true;
+}
+  }
+  return isUpperCase;
+}
+
+llvm::Optional ClangdServer::switchSourceHeader(PathRef Path) {
+
+  StringRef SourceExtensions[] = {".cpp", ".c", ".cc", ".cxx", ".c++", ".m", ".mm"};
+  StringRef HeaderExtensions[] = {".h", ".hh", ".hpp", ".hxx", ".inc"};
+
+  StringRef PathExt = llvm::sys::path::extension(Path);
+  
+  // Lookup in a list of known extensions.
+  auto SourceIter = std::find(std::begin(SourceExtensions), std::end(SourceExtensions), PathExt);
+  bool IsSource = SourceIter != std::end(SourceExtensions);
+
+  if (!IsSource)
+  {
+IsSource = checkUpperCaseExtensions(SourceExtensions, llvm::array_lengthof(SourceExtensions), PathExt);
+  }
+  
+  auto HeaderIter = std::find(std::begin(HeaderExtensions), std::end(HeaderExtensions), PathExt);
+  bool IsHeader = HeaderIter != std::end(HeaderExtensions);
+
+  if (!IsHeader)
+  {
+IsHeader = checkUpperCaseExtensions(HeaderExtensions, llvm::array_lengthof(HeaderExtensions), PathExt);
+ 

[PATCH] D36150: [clangd] LSP extension to switch between source/header file

2017-09-06 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 114046.
Nebiroth added a comment.

Refactored switchSourceHeader function help from ilya
Added helper function to check for uppercase on current file.


https://reviews.llvm.org/D36150

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/hover.test

Index: test/clangd/hover.test
===
--- /dev/null
+++ test/clangd/hover.test
@@ -0,0 +1,26 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 172
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"int main() {\nint a;\na;\n}\n"}}}
+
+Content-Length: 143
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":0,"character":5}}}
+# Go to local variable
+# CHECK: {"jsonrpc":"2.0","id":1,"result":{"contents": {"language": "C++", "value": "int main() {\nint a;\na;\n}"}, "range": {"start": {"line": 0, "character": 0}, "end": {"line": 3, "character": 1
+
+Content-Length: 143
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":1,"character":5}}}
+# Go to local variable
+# CHECK: {"jsonrpc":"2.0","id":1,"result":{"contents": {"language": "C++", "value": "int a"}, "range": {"start": {"line": 1, "character": 0}, "end": {"line": 1, "character": 5
+
+Content-Length: 44
+
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
Index: clangd/ProtocolHandlers.h
===
--- clangd/ProtocolHandlers.h
+++ clangd/ProtocolHandlers.h
@@ -48,6 +48,8 @@
 JSONOutput ) = 0;
   virtual void onGoToDefinition(TextDocumentPositionParams Params, StringRef ID,
 JSONOutput ) = 0;
+  virtual void onSwitchSourceHeader(TextDocumentIdentifier Params, StringRef ID,
+JSONOutput ) = 0;
 };
 
 void regiterCallbackHandlers(JSONRPCDispatcher , JSONOutput ,
Index: clangd/ProtocolHandlers.cpp
===
--- clangd/ProtocolHandlers.cpp
+++ clangd/ProtocolHandlers.cpp
@@ -204,6 +204,23 @@
   ProtocolCallbacks 
 };
 
+struct SwitchSourceHeaderHandler : Handler {
+  SwitchSourceHeaderHandler(JSONOutput , ProtocolCallbacks )
+  : Handler(Output), Callbacks(Callbacks) {}
+
+  void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override {
+auto TDPP = TextDocumentIdentifier::parse(Params);
+if (!TDPP) {
+  return;
+}
+
+Callbacks.onSwitchSourceHeader(*TDPP, ID, Output);
+  }
+
+private:
+  ProtocolCallbacks 
+};
+
 } // namespace
 
 void clangd::regiterCallbackHandlers(JSONRPCDispatcher ,
@@ -239,4 +256,7 @@
   llvm::make_unique(Out, Callbacks));
   Dispatcher.registerHandler("textDocument/definition",
   llvm::make_unique(Out, Callbacks));
+  Dispatcher.registerHandler(
+  "textDocument/switchSourceHeader",
+  llvm::make_unique(Out, Callbacks));
 }
Index: clangd/ClangdServer.h
===
--- clangd/ClangdServer.h
+++ clangd/ClangdServer.h
@@ -182,6 +182,12 @@
   /// Get definition of symbol at a specified \p Line and \p Column in \p File.
   Tagged findDefinitions(PathRef File, Position Pos);
 
+  /// If an extension hasn't been found in the lowercase array, try with uppercase.
+  bool checkUpperCaseExtensions(StringRef BaseArray[], int ArraySize, StringRef PathExt);
+
+  /// Helper function that returns a path to the corresponding source file when given a header file and vice versa.
+  llvm::Optional switchSourceHeader(PathRef Path);
+
   /// Run formatting for \p Rng inside \p File.
   std::vector formatRange(PathRef File, Range Rng);
   /// Run formatting for the whole \p File.
Index: clangd/ClangdServer.cpp
===
--- clangd/ClangdServer.cpp
+++ clangd/ClangdServer.cpp
@@ -15,9 +15,11 @@
 #include "clang/Tooling/CompilationDatabase.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 #include 
 
+using namespace llvm;
 using namespace clang;
 using namespace clang::clangd;
 
@@ -286,3 +288,84 @@
   });
   return make_tagged(std::move(Result), TaggedFS.Tag);
 }
+
+
+bool ClangdServer::checkUpperCaseExtensions(StringRef BaseArray[], int ArraySize, StringRef PathExt)
+{
+  std::string UpperExtensions[ArraySize];
+  for(int i = 0; i < ArraySize; i++)
+  {
+

[PATCH] D37150: [clangd] Command line arg to specify compile_commands.json path

2017-09-05 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 113895.
Nebiroth added a comment.

Added function to avoid code reuse and extra nesting.


https://reviews.llvm.org/D37150

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/GlobalCompilationDatabase.cpp
  clangd/GlobalCompilationDatabase.h
  clangd/tool/ClangdMain.cpp
  test/clangd/hover.test

Index: test/clangd/hover.test
===
--- /dev/null
+++ test/clangd/hover.test
@@ -0,0 +1,26 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 172
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"int main() {\nint a;\na;\n}\n"}}}
+
+Content-Length: 143
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":0,"character":5}}}
+# Go to local variable
+# CHECK: {"jsonrpc":"2.0","id":1,"result":{"contents": {"language": "C++", "value": "int main() {\nint a;\na;\n}"}, "range": {"start": {"line": 0, "character": 0}, "end": {"line": 3, "character": 1
+
+Content-Length: 143
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":1,"character":5}}}
+# Go to local variable
+# CHECK: {"jsonrpc":"2.0","id":1,"result":{"contents": {"language": "C++", "value": "int a"}, "range": {"start": {"line": 1, "character": 0}, "end": {"line": 1, "character": 5
+
+Content-Length: 44
+
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
Index: clangd/tool/ClangdMain.cpp
===
--- clangd/tool/ClangdMain.cpp
+++ clangd/tool/ClangdMain.cpp
@@ -12,6 +12,7 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Program.h"
+#include "llvm/Support/Path.h"
 
 #include 
 #include 
@@ -25,16 +26,29 @@
  llvm::cl::desc("parse on main thread"),
  llvm::cl::init(false), llvm::cl::Hidden);
 
+static llvm::cl::opt
+CompileCommands("compile-commands-dir",
+ llvm::cl::desc("Specify a path to look for compile_commands.json. If path is invalid, clangd will look in the current directory and parent paths of each source file.")); 
+
+
 int main(int argc, char *argv[]) {
   llvm::cl::ParseCommandLineOptions(argc, argv, "clangd");
 
   llvm::raw_ostream  = llvm::outs();
   llvm::raw_ostream  = llvm::errs();
   JSONOutput Out(Outs, Logs);
 
+  // If --compileCommands arg was invoked, check value and override default path.
+  namespace path = llvm::sys::path;
+  if (!llvm::sys::path::is_absolute(CompileCommands) || CompileCommands.empty())
+Logs << "Path specified for compilation database must be absolute. Verifying current folder instead.";
+
+  if (!llvm::sys::fs::exists(CompileCommands))
+Logs << "File does not exist. Verifying current folder instead.";
+
   // Change stdin to binary to not lose \r\n on windows.
   llvm::sys::ChangeStdinToBinary();
 
-  ClangdLSPServer LSPServer(Out, RunSynchronously);
+  ClangdLSPServer LSPServer(Out, RunSynchronously, CompileCommands);
   LSPServer.run(std::cin);
 }
Index: clangd/GlobalCompilationDatabase.h
===
--- clangd/GlobalCompilationDatabase.h
+++ clangd/GlobalCompilationDatabase.h
@@ -33,8 +33,9 @@
 public:
   virtual ~GlobalCompilationDatabase() = default;
 
-  virtual std::vector
+  virtual std::vector  
   getCompileCommands(PathRef File) = 0;
+  std::string CompileCommands;  
 
   /// FIXME(ibiryukov): add facilities to track changes to compilation flags of
   /// existing targets.
@@ -49,6 +50,7 @@
   getCompileCommands(PathRef File) override;
 
   void setExtraFlagsForFile(PathRef File, std::vector ExtraFlags);
+  tooling::CompilationDatabase *tryLoadDatabaseFromPath(PathRef File, std::string );
 
 private:
   tooling::CompilationDatabase *getCompilationDatabase(PathRef File);
Index: clangd/GlobalCompilationDatabase.cpp
===
--- clangd/GlobalCompilationDatabase.cpp
+++ clangd/GlobalCompilationDatabase.cpp
@@ -11,6 +11,16 @@
 #include "clang/Tooling/CompilationDatabase.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/Timer.h"
+#include 

[PATCH] D37150: [clangd] Command line arg to specify compile_commands.json path

2017-08-25 Thread William Enright via Phabricator via cfe-commits
Nebiroth created this revision.

Adds compileCommands command line argument to specify an absolute path directly 
to the requested compile_commands.json for flags.


https://reviews.llvm.org/D37150

Files:
  clangd/GlobalCompilationDatabase.cpp

Index: clangd/GlobalCompilationDatabase.cpp
===
--- clangd/GlobalCompilationDatabase.cpp
+++ clangd/GlobalCompilationDatabase.cpp
@@ -11,6 +11,24 @@
 #include "clang/Tooling/CompilationDatabase.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/Timer.h"
+#include "llvm/Support/YAMLTraits.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+namespace {
+
+static cl::opt CompileCommands("compileCommands",
+ cl::desc("Start with absolute path to compile_commands.json"));  
+}
 
 namespace clang {
 namespace clangd {
@@ -36,6 +54,8 @@
  /*Output=*/"");
 }
 
+
+
 std::vector
 DirectoryBasedGlobalCompilationDatabase::getCompileCommands(PathRef File) {
   std::vector Commands;
@@ -64,35 +84,62 @@
 tooling::CompilationDatabase *
 DirectoryBasedGlobalCompilationDatabase::getCompilationDatabase(PathRef File) {
   std::lock_guard Lock(Mutex);
-
   namespace path = llvm::sys::path;
+  // if --compileCommands arg was invoked, check value and override default path
+  std::size_t found = CompileCommands.find_first_of("/");
+  std::string TempString = CompileCommands;
+  if (found != std::string::npos)
+  {
+ File = TempString;
+  }
+
+  std::string Error;
+  bool badPath = false;
+  File = path::parent_path(File);
+  auto CachedIt = CompilationDatabases.find(File);
+  if (CachedIt != CompilationDatabases.end())
+return CachedIt->second.get();
+  auto CDB = tooling::CompilationDatabase::loadFromDirectory(File, Error);
+  if (!CDB) {
+  if (!Error.empty()) {
+badPath = true;
+  }  
+  }
 
   assert((path::is_absolute(File, path::Style::posix) ||
   path::is_absolute(File, path::Style::windows)) &&
  "path must be absolute");
 
-  for (auto Path = path::parent_path(File); !Path.empty();
+  if (badPath)
+  {
+for (auto Path = path::parent_path(File); !Path.empty();
Path = path::parent_path(Path)) {
 
 auto CachedIt = CompilationDatabases.find(Path);
 if (CachedIt != CompilationDatabases.end())
   return CachedIt->second.get();
-std::string Error;
 auto CDB = tooling::CompilationDatabase::loadFromDirectory(Path, Error);
 if (!CDB) {
   if (!Error.empty()) {
 // FIXME(ibiryukov): logging
 // Output.log("Error when trying to load compilation database from " +
 //Twine(Path) + ": " + Twine(Error) + "\n");
-  }
-  continue;
+  }  
 }
 
 // FIXME(ibiryukov): Invalidate cached compilation databases on changes
 auto result = CDB.get();
 CompilationDatabases.insert(std::make_pair(Path, std::move(CDB)));
 return result;
+}
   }
+  else
+  {
+auto result = CDB.get();
+CompilationDatabases.insert(std::make_pair(File, std::move(CDB)));
+return result;
+  }
+
 
   // FIXME(ibiryukov): logging
   // Output.log("Failed to find compilation database for " + Twine(File) +
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


  1   2   >