[Mlir-commits] [mlir] 3bcc63e - [mlir][lsp] Add LSP support for attribute and type aliases
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Thu Aug 24 22:50:48 PDT 2023
Author: Mogball
Date: 2023-08-25T05:50:25Z
New Revision: 3bcc63e36ad4afc653ba2e2e92a553452252f92f
URL: https://github.com/llvm/llvm-project/commit/3bcc63e36ad4afc653ba2e2e92a553452252f92f
DIFF: https://github.com/llvm/llvm-project/commit/3bcc63e36ad4afc653ba2e2e92a553452252f92f.diff
LOG: [mlir][lsp] Add LSP support for attribute and type aliases
This wires in attribute and type aliases into the MLIR LSP server. This
will allow goto definition and find references on attribute and type
references, which should make debugging locations and other metadata
easier.
Depends on D158781
Reviewed By: rriddle
Differential Revision: https://reviews.llvm.org/D158782
Added:
Modified:
mlir/include/mlir/AsmParser/AsmParserState.h
mlir/lib/AsmParser/AsmParserState.cpp
mlir/lib/AsmParser/Parser.cpp
mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp
mlir/test/mlir-lsp-server/definition.test
mlir/test/mlir-lsp-server/references.test
Removed:
################################################################################
diff --git a/mlir/include/mlir/AsmParser/AsmParserState.h b/mlir/include/mlir/AsmParser/AsmParserState.h
index 3d22e2a34b5b4a..98bdc4696b846b 100644
--- a/mlir/include/mlir/AsmParser/AsmParserState.h
+++ b/mlir/include/mlir/AsmParser/AsmParserState.h
@@ -9,10 +9,8 @@
#ifndef MLIR_ASMPARSER_ASMPARSERSTATE_H
#define MLIR_ASMPARSER_ASMPARSERSTATE_H
-#include "mlir/Support/LLVM.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
+#include "mlir/IR/Attributes.h"
+#include "mlir/IR/Types.h"
#include "llvm/Support/SMLoc.h"
#include <cstddef>
@@ -98,27 +96,34 @@ class AsmParserState {
/// This class represents the information for an attribute alias definition
/// within the input file.
struct AttributeAliasDefinition {
- AttributeAliasDefinition(StringRef name, SMRange loc = {})
- : name(name), definition(loc) {}
+ AttributeAliasDefinition(StringRef name, SMRange loc = {},
+ Attribute value = {})
+ : name(name), definition(loc), value(value) {}
/// The name of the attribute alias.
StringRef name;
/// The source location for the alias.
SMDefinition definition;
+
+ /// The value of the alias.
+ Attribute value;
};
/// This class represents the information for type definition within the input
/// file.
struct TypeAliasDefinition {
- TypeAliasDefinition(StringRef name, SMRange loc)
- : name(name), definition(loc) {}
+ TypeAliasDefinition(StringRef name, SMRange loc, Type value)
+ : name(name), definition(loc), value(value) {}
/// The name of the attribute alias.
StringRef name;
/// The source location for the alias.
SMDefinition definition;
+
+ /// The value of the alias.
+ Type value;
};
AsmParserState();
@@ -133,6 +138,10 @@ class AsmParserState {
ArrayRef<std::unique_ptr<BlockDefinition>>::iterator>;
using OperationDefIterator = llvm::pointee_iterator<
ArrayRef<std::unique_ptr<OperationDefinition>>::iterator>;
+ using AttributeDefIterator = llvm::pointee_iterator<
+ ArrayRef<std::unique_ptr<AttributeAliasDefinition>>::iterator>;
+ using TypeDefIterator = llvm::pointee_iterator<
+ ArrayRef<std::unique_ptr<TypeAliasDefinition>>::iterator>;
/// Return a range of the BlockDefinitions held by the current parser state.
iterator_range<BlockDefIterator> getBlockDefs() const;
@@ -149,6 +158,22 @@ class AsmParserState {
/// operation does not have a definition.
const OperationDefinition *getOpDef(Operation *op) const;
+ /// Return a range of the AttributeAliasDefinitions held by the current parser
+ /// state.
+ iterator_range<AttributeDefIterator> getAttributeAliasDefs() const;
+
+ /// Return the definition for the given attribute alias, or nullptr if the
+ /// given alias does not have a definition.
+ const AttributeAliasDefinition *getAttributeAliasDef(StringRef name) const;
+
+ /// Return a range of the TypeAliasDefinitions held by the current parser
+ /// state.
+ iterator_range<TypeDefIterator> getTypeAliasDefs() const;
+
+ /// Return the definition for the given type alias, or nullptr if the given
+ /// alias does not have a definition.
+ const TypeAliasDefinition *getTypeAliasDef(StringRef name) const;
+
/// Returns (heuristically) the range of an identifier given a SMLoc
/// corresponding to the start of an identifier location.
static SMRange convertIdLocToRange(SMLoc loc);
@@ -181,8 +206,9 @@ class AsmParserState {
/// Add a definition of the given entity.
void addDefinition(Block *block, SMLoc location);
void addDefinition(BlockArgument blockArg, SMLoc location);
- void addAttrAliasDefinition(StringRef name, SMRange location);
- void addTypeAliasDefinition(StringRef name, SMRange location);
+ void addAttrAliasDefinition(StringRef name, SMRange location,
+ Attribute value);
+ void addTypeAliasDefinition(StringRef name, SMRange location, Type value);
/// Add a source uses of the given value.
void addUses(Value value, ArrayRef<SMLoc> locations);
diff --git a/mlir/lib/AsmParser/AsmParserState.cpp b/mlir/lib/AsmParser/AsmParserState.cpp
index 672f1ce860cb17..0b71bec00ddbb8 100644
--- a/mlir/lib/AsmParser/AsmParserState.cpp
+++ b/mlir/lib/AsmParser/AsmParserState.cpp
@@ -128,6 +128,30 @@ auto AsmParserState::getOpDef(Operation *op) const
: &*impl->operations[it->second];
}
+auto AsmParserState::getAttributeAliasDefs() const
+ -> iterator_range<AttributeDefIterator> {
+ return llvm::make_pointee_range(ArrayRef(impl->attrAliases));
+}
+
+auto AsmParserState::getAttributeAliasDef(StringRef name) const
+ -> const AttributeAliasDefinition * {
+ auto it = impl->attrAliasToIdx.find(name);
+ return it == impl->attrAliasToIdx.end() ? nullptr
+ : &*impl->attrAliases[it->second];
+}
+
+auto AsmParserState::getTypeAliasDefs() const
+ -> iterator_range<TypeDefIterator> {
+ return llvm::make_pointee_range(ArrayRef(impl->typeAliases));
+}
+
+auto AsmParserState::getTypeAliasDef(StringRef name) const
+ -> const TypeAliasDefinition * {
+ auto it = impl->typeAliasToIdx.find(name);
+ return it == impl->typeAliasToIdx.end() ? nullptr
+ : &*impl->typeAliases[it->second];
+}
+
/// Lex a string token whose contents start at the given `curPtr`. Returns the
/// position at the end of the string, after a terminal or invalid character
/// (e.g. `"` or `\0`).
@@ -277,24 +301,28 @@ void AsmParserState::addDefinition(BlockArgument blockArg, SMLoc location) {
def.arguments[argIdx] = SMDefinition(convertIdLocToRange(location));
}
-void AsmParserState::addAttrAliasDefinition(StringRef name, SMRange location) {
+void AsmParserState::addAttrAliasDefinition(StringRef name, SMRange location,
+ Attribute value) {
auto [it, inserted] =
impl->attrAliasToIdx.try_emplace(name, impl->attrAliases.size());
// Location aliases may be referenced before they are defined.
if (inserted) {
impl->attrAliases.push_back(
- std::make_unique<AttributeAliasDefinition>(name, location));
+ std::make_unique<AttributeAliasDefinition>(name, location, value));
} else {
- impl->attrAliases[it->second]->definition.loc = location;
+ AttributeAliasDefinition &attr = *impl->attrAliases[it->second];
+ attr.definition.loc = location;
+ attr.value = value;
}
}
-void AsmParserState::addTypeAliasDefinition(StringRef name, SMRange location) {
+void AsmParserState::addTypeAliasDefinition(StringRef name, SMRange location,
+ Type value) {
[[maybe_unused]] auto [it, inserted] =
impl->typeAliasToIdx.try_emplace(name, impl->typeAliases.size());
assert(inserted && "unexpected attribute alias redefinition");
impl->typeAliases.push_back(
- std::make_unique<TypeAliasDefinition>(name, location));
+ std::make_unique<TypeAliasDefinition>(name, location, value));
}
void AsmParserState::addUses(Value value, ArrayRef<SMLoc> locations) {
diff --git a/mlir/lib/AsmParser/Parser.cpp b/mlir/lib/AsmParser/Parser.cpp
index 6b075c05c4d529..02bf9a41806399 100644
--- a/mlir/lib/AsmParser/Parser.cpp
+++ b/mlir/lib/AsmParser/Parser.cpp
@@ -2543,7 +2543,7 @@ ParseResult TopLevelOperationParser::parseAttributeAliasDef() {
// Register this alias with the parser state.
if (state.asmState)
- state.asmState->addAttrAliasDefinition(aliasName, location);
+ state.asmState->addAttrAliasDefinition(aliasName, location, attr);
state.symbols.attributeAliasDefinitions[aliasName] = attr;
return success();
}
@@ -2575,7 +2575,7 @@ ParseResult TopLevelOperationParser::parseTypeAliasDef() {
// Register this alias with the parser state.
if (state.asmState)
- state.asmState->addTypeAliasDefinition(aliasName, location);
+ state.asmState->addTypeAliasDefinition(aliasName, location, aliasedType);
state.symbols.typeAliasDefinitions.try_emplace(aliasName, aliasedType);
return success();
}
diff --git a/mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp b/mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp
index 4a8f74ff550f38..6fe0c67d01ca01 100644
--- a/mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp
+++ b/mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp
@@ -287,6 +287,12 @@ struct MLIRDocument {
buildHoverForBlockArgument(SMRange hoverRange, BlockArgument arg,
const AsmParserState::BlockDefinition &block);
+ lsp::Hover buildHoverForAttributeAlias(
+ SMRange hoverRange, const AsmParserState::AttributeAliasDefinition &attr);
+ lsp::Hover
+ buildHoverForTypeAlias(SMRange hoverRange,
+ const AsmParserState::TypeAliasDefinition &type);
+
//===--------------------------------------------------------------------===//
// Document Symbols
//===--------------------------------------------------------------------===//
@@ -404,6 +410,18 @@ void MLIRDocument::getLocationsOf(const lsp::URIForFile &uri,
if (containsPosition(arg))
return;
}
+
+ // Check all alias definitions.
+ for (const AsmParserState::AttributeAliasDefinition &attr :
+ asmState.getAttributeAliasDefs()) {
+ if (containsPosition(attr.definition))
+ return;
+ }
+ for (const AsmParserState::TypeAliasDefinition &type :
+ asmState.getTypeAliasDefs()) {
+ if (containsPosition(type.definition))
+ return;
+ }
}
void MLIRDocument::findReferencesOf(const lsp::URIForFile &uri,
@@ -450,6 +468,18 @@ void MLIRDocument::findReferencesOf(const lsp::URIForFile &uri,
if (isDefOrUse(arg, posLoc))
return appendSMDef(arg);
}
+
+ // Check all alias definitions.
+ for (const AsmParserState::AttributeAliasDefinition &attr :
+ asmState.getAttributeAliasDefs()) {
+ if (isDefOrUse(attr.definition, posLoc))
+ return appendSMDef(attr.definition);
+ }
+ for (const AsmParserState::TypeAliasDefinition &type :
+ asmState.getTypeAliasDefs()) {
+ if (isDefOrUse(type.definition, posLoc))
+ return appendSMDef(type.definition);
+ }
}
//===----------------------------------------------------------------------===//
@@ -501,6 +531,19 @@ MLIRDocument::findHover(const lsp::URIForFile &uri,
hoverRange, block.block->getArgument(arg.index()), block);
}
}
+
+ // Check to see if the hover is over an alias.
+ for (const AsmParserState::AttributeAliasDefinition &attr :
+ asmState.getAttributeAliasDefs()) {
+ if (isDefOrUse(attr.definition, posLoc, &hoverRange))
+ return buildHoverForAttributeAlias(hoverRange, attr);
+ }
+ for (const AsmParserState::TypeAliasDefinition &type :
+ asmState.getTypeAliasDefs()) {
+ if (isDefOrUse(type.definition, posLoc, &hoverRange))
+ return buildHoverForTypeAlias(hoverRange, type);
+ }
+
return std::nullopt;
}
@@ -609,6 +652,28 @@ lsp::Hover MLIRDocument::buildHoverForBlockArgument(
return hover;
}
+lsp::Hover MLIRDocument::buildHoverForAttributeAlias(
+ SMRange hoverRange, const AsmParserState::AttributeAliasDefinition &attr) {
+ lsp::Hover hover(lsp::Range(sourceMgr, hoverRange));
+ llvm::raw_string_ostream os(hover.contents.value);
+
+ os << "Attribute Alias: \"" << attr.name << "\n\n";
+ os << "Value: ```mlir\n" << attr.value << "\n```\n\n";
+
+ return hover;
+}
+
+lsp::Hover MLIRDocument::buildHoverForTypeAlias(
+ SMRange hoverRange, const AsmParserState::TypeAliasDefinition &type) {
+ lsp::Hover hover(lsp::Range(sourceMgr, hoverRange));
+ llvm::raw_string_ostream os(hover.contents.value);
+
+ os << "Type Alias: \"" << type.name << "\n\n";
+ os << "Value: ```mlir\n" << type.value << "\n```\n\n";
+
+ return hover;
+}
+
//===----------------------------------------------------------------------===//
// MLIRDocument: Document Symbols
//===----------------------------------------------------------------------===//
diff --git a/mlir/test/mlir-lsp-server/definition.test b/mlir/test/mlir-lsp-server/definition.test
index 7aa60be71865ea..99f7c2b2c39537 100644
--- a/mlir/test/mlir-lsp-server/definition.test
+++ b/mlir/test/mlir-lsp-server/definition.test
@@ -5,12 +5,12 @@
"uri":"test:///foo.mlir",
"languageId":"mlir",
"version":1,
- "text":"func.func @foo() -> i1 {\n%value = arith.constant true\nreturn %value : i1\n}"
+ "text":"#attr = 1 : index\n!type = index\nfunc.func @foo(%arg0: !type) -> i1 attributes {attr = #attr} {\n%value = arith.constant true loc(#loc)\nreturn %value : i1\n}\n#loc = loc(\"foo.mlir\":1:2)"
}}}
// -----
{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{
"textDocument":{"uri":"test:///foo.mlir"},
- "position":{"line":2,"character":12}
+ "position":{"line":4,"character":12}
}}
// CHECK: "id": 1
// CHECK-NEXT: "jsonrpc": "2.0",
@@ -19,6 +19,48 @@
// CHECK-NEXT: "range": {
// CHECK-NEXT: "end": {
// CHECK-NEXT: "character": 6,
+// CHECK-NEXT: "line": 3
+// CHECK-NEXT: },
+// CHECK-NEXT: "start": {
+// CHECK-NEXT: "character": 0,
+// CHECK-NEXT: "line": 3
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "uri": "{{.*}}/foo.mlir"
+// CHECK-NEXT: }
+// -----
+{"jsonrpc":"2.0","id":2,"method":"textDocument/definition","params":{
+ "textDocument":{"uri":"test:///foo.mlir"},
+ "position":{"line":2,"character":12}
+}}
+// CHECK: "id": 2
+// CHECK-NEXT: "jsonrpc": "2.0",
+// CHECK-NEXT: "result": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "character": 9,
+// CHECK-NEXT: "line": 2
+// CHECK-NEXT: },
+// CHECK-NEXT: "start": {
+// CHECK-NEXT: "character": 0,
+// CHECK-NEXT: "line": 2
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "uri": "{{.*}}/foo.mlir"
+// CHECK-NEXT: }
+// -----
+{"jsonrpc":"2.0","id":2,"method":"textDocument/definition","params":{
+ "textDocument":{"uri":"test:///foo.mlir"},
+ "position":{"line":2,"character":25}
+}}
+// CHECK: "id": 2
+// CHECK-NEXT: "jsonrpc": "2.0",
+// CHECK-NEXT: "result": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "character": 5,
// CHECK-NEXT: "line": 1
// CHECK-NEXT: },
// CHECK-NEXT: "start": {
@@ -31,7 +73,7 @@
// -----
{"jsonrpc":"2.0","id":2,"method":"textDocument/definition","params":{
"textDocument":{"uri":"test:///foo.mlir"},
- "position":{"line":0,"character":12}
+ "position":{"line":2,"character":57}
}}
// CHECK: "id": 2
// CHECK-NEXT: "jsonrpc": "2.0",
@@ -39,7 +81,7 @@
// CHECK-NEXT: {
// CHECK-NEXT: "range": {
// CHECK-NEXT: "end": {
-// CHECK-NEXT: "character": 9,
+// CHECK-NEXT: "character": 5,
// CHECK-NEXT: "line": 0
// CHECK-NEXT: },
// CHECK-NEXT: "start": {
@@ -50,6 +92,27 @@
// CHECK-NEXT: "uri": "{{.*}}/foo.mlir"
// CHECK-NEXT: }
// -----
+{"jsonrpc":"2.0","id":2,"method":"textDocument/definition","params":{
+ "textDocument":{"uri":"test:///foo.mlir"},
+ "position":{"line":3,"character":37}
+}}
+// CHECK: "id": 2
+// CHECK-NEXT: "jsonrpc": "2.0",
+// CHECK-NEXT: "result": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "character": 4,
+// CHECK-NEXT: "line": 6
+// CHECK-NEXT: },
+// CHECK-NEXT: "start": {
+// CHECK-NEXT: "character": 0,
+// CHECK-NEXT: "line": 6
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "uri": "{{.*}}/foo.mlir"
+// CHECK-NEXT: }
+// -----
{"jsonrpc":"2.0","id":3,"method":"shutdown"}
// -----
{"jsonrpc":"2.0","method":"exit"}
diff --git a/mlir/test/mlir-lsp-server/references.test b/mlir/test/mlir-lsp-server/references.test
index 60fd48296e5e5c..a94d752ab9d2a6 100644
--- a/mlir/test/mlir-lsp-server/references.test
+++ b/mlir/test/mlir-lsp-server/references.test
@@ -5,12 +5,12 @@
"uri":"test:///foo.mlir",
"languageId":"mlir",
"version":1,
- "text":"func.func @foo() -> i1 {\n%value = arith.constant true\n%result = call @foo() : () -> i1\nreturn %value : i1\n}"
+ "text":"#attr = 1 : index\n!type = index\nfunc.func @foo(%arg0: !type) -> i1 attributes {attr = #attr} {\n%value = arith.constant true\n%result = call @foo(%arg0) : (!type) -> i1\nreturn %value : i1 loc(#loc)\n}\n#loc = loc(\"foo.mlir\":1:2)"
}}}
// -----
{"jsonrpc":"2.0","id":1,"method":"textDocument/references","params":{
"textDocument":{"uri":"test:///foo.mlir"},
- "position":{"line":1,"character":2},
+ "position":{"line":3,"character":2},
"context":{"includeDeclaration": false}
}}
// CHECK: "id": 1
@@ -20,11 +20,11 @@
// CHECK-NEXT: "range": {
// CHECK-NEXT: "end": {
// CHECK-NEXT: "character": 6,
-// CHECK-NEXT: "line": 1
+// CHECK-NEXT: "line": 3
// CHECK-NEXT: },
// CHECK-NEXT: "start": {
// CHECK-NEXT: "character": 0,
-// CHECK-NEXT: "line": 1
+// CHECK-NEXT: "line": 3
// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "uri": "{{.*}}/foo.mlir"
@@ -33,11 +33,11 @@
// CHECK-NEXT: "range": {
// CHECK-NEXT: "end": {
// CHECK-NEXT: "character": 13,
-// CHECK-NEXT: "line": 3
+// CHECK-NEXT: "line": 5
// CHECK-NEXT: },
// CHECK-NEXT: "start": {
// CHECK-NEXT: "character": 7,
-// CHECK-NEXT: "line": 3
+// CHECK-NEXT: "line": 5
// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "uri": "{{.*}}/foo.mlir"
@@ -46,7 +46,7 @@
// -----
{"jsonrpc":"2.0","id":2,"method":"textDocument/references","params":{
"textDocument":{"uri":"test:///foo.mlir"},
- "position":{"line":0,"character":12},
+ "position":{"line":2,"character":12},
"context":{"includeDeclaration": false}
}}
// CHECK: "id": 2
@@ -56,11 +56,11 @@
// CHECK-NEXT: "range": {
// CHECK-NEXT: "end": {
// CHECK-NEXT: "character": 14,
-// CHECK-NEXT: "line": 0
+// CHECK-NEXT: "line": 2
// CHECK-NEXT: },
// CHECK-NEXT: "start": {
// CHECK-NEXT: "character": 10,
-// CHECK-NEXT: "line": 0
+// CHECK-NEXT: "line": 2
// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "uri": "{{.*}}/foo.mlir"
@@ -69,10 +69,46 @@
// CHECK-NEXT: "range": {
// CHECK-NEXT: "end": {
// CHECK-NEXT: "character": 19,
-// CHECK-NEXT: "line": 2
+// CHECK-NEXT: "line": 4
// CHECK-NEXT: },
// CHECK-NEXT: "start": {
// CHECK-NEXT: "character": 15,
+// CHECK-NEXT: "line": 4
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "uri": "{{.*}}/foo.mlir"
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
+// -----
+{"jsonrpc":"2.0","id":2,"method":"textDocument/references","params":{
+ "textDocument":{"uri":"test:///foo.mlir"},
+ "position":{"line":0,"character":3},
+ "context":{"includeDeclaration": false}
+}}
+// CHECK: "id": 2
+// CHECK-NEXT: "jsonrpc": "2.0",
+// CHECK-NEXT: "result": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "character": 5,
+// CHECK-NEXT: "line": 0
+// CHECK-NEXT: },
+// CHECK-NEXT: "start": {
+// CHECK-NEXT: "character": 0,
+// CHECK-NEXT: "line": 0
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "uri": "{{.*}}/foo.mlir"
+// CHECK-NEXT: },
+// CHECK-NEXT: {
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "character": 59,
+// CHECK-NEXT: "line": 2
+// CHECK-NEXT: },
+// CHECK-NEXT: "start": {
+// CHECK-NEXT: "character": 54,
// CHECK-NEXT: "line": 2
// CHECK-NEXT: }
// CHECK-NEXT: },
@@ -80,6 +116,91 @@
// CHECK-NEXT: }
// CHECK-NEXT: ]
// -----
+{"jsonrpc":"2.0","id":2,"method":"textDocument/references","params":{
+ "textDocument":{"uri":"test:///foo.mlir"},
+ "position":{"line":1,"character":3},
+ "context":{"includeDeclaration": false}
+}}
+// CHECK: "id": 2
+// CHECK-NEXT: "jsonrpc": "2.0",
+// CHECK-NEXT: "result": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "character": 5,
+// CHECK-NEXT: "line": 1
+// CHECK-NEXT: },
+// CHECK-NEXT: "start": {
+// CHECK-NEXT: "character": 0,
+// CHECK-NEXT: "line": 1
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "uri": "{{.*}}/foo.mlir"
+// CHECK-NEXT: },
+// CHECK-NEXT: {
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "character": 27,
+// CHECK-NEXT: "line": 2
+// CHECK-NEXT: },
+// CHECK-NEXT: "start": {
+// CHECK-NEXT: "character": 22,
+// CHECK-NEXT: "line": 2
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "uri": "{{.*}}/foo.mlir"
+// CHECK-NEXT: },
+// CHECK-NEXT: {
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "character": 35,
+// CHECK-NEXT: "line": 4
+// CHECK-NEXT: },
+// CHECK-NEXT: "start": {
+// CHECK-NEXT: "character": 30,
+// CHECK-NEXT: "line": 4
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "uri": "{{.*}}/foo.mlir"
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
+// -----
+{"jsonrpc":"2.0","id":2,"method":"textDocument/references","params":{
+ "textDocument":{"uri":"test:///foo.mlir"},
+ "position":{"line":7,"character":3},
+ "context":{"includeDeclaration": false}
+}}
+// CHECK: "id": 2
+// CHECK-NEXT: "jsonrpc": "2.0",
+// CHECK-NEXT: "result": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "character": 4,
+// CHECK-NEXT: "line": 7
+// CHECK-NEXT: },
+// CHECK-NEXT: "start": {
+// CHECK-NEXT: "character": 0,
+// CHECK-NEXT: "line": 7
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "uri": "{{.*}}/foo.mlir"
+// CHECK-NEXT: },
+// CHECK-NEXT: {
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "character": 27,
+// CHECK-NEXT: "line": 5
+// CHECK-NEXT: },
+// CHECK-NEXT: "start": {
+// CHECK-NEXT: "character": 23,
+// CHECK-NEXT: "line": 5
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "uri": "{{.*}}/foo.mlir"
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
+// -----
{"jsonrpc":"2.0","id":3,"method":"shutdown"}
// -----
{"jsonrpc":"2.0","method":"exit"}
More information about the Mlir-commits
mailing list