Skip to content
This repository has been archived by the owner on Sep 6, 2021. It is now read-only.

Lsp symbols #15317

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
3 changes: 3 additions & 0 deletions src/base-config/keyboard.json
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,9 @@
"navigate.gotoDefinition": [
"Ctrl-T"
],
"navigate.gotoDefinitionInProject": [
"Ctrl-Shift-T"
],
"navigate.jumptoDefinition": [
"Ctrl-J"
],
Expand Down
1 change: 1 addition & 0 deletions src/command/Commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ define(function (require, exports, module) {
exports.NAVIGATE_QUICK_OPEN = "navigate.quickOpen"; // QuickOpen.js doFileSearch()
exports.NAVIGATE_JUMPTO_DEFINITION = "navigate.jumptoDefinition"; // JumpToDefManager.js _doJumpToDef()
exports.NAVIGATE_GOTO_DEFINITION = "navigate.gotoDefinition"; // QuickOpen.js doDefinitionSearch()
exports.NAVIGATE_GOTO_DEFINITION_PROJECT = "navigate.gotoDefinitionInProject"; // QuickOpen.js doDefinitionSearchInProject()
exports.NAVIGATE_GOTO_LINE = "navigate.gotoLine"; // QuickOpen.js doGotoLine()
exports.NAVIGATE_GOTO_FIRST_PROBLEM = "navigate.gotoFirstProblem"; // CodeInspection.js handleGotoFirstProblem()
exports.TOGGLE_QUICK_EDIT = "navigate.toggleQuickEdit"; // EditorManager.js _toggleInlineWidget()
Expand Down
1 change: 1 addition & 0 deletions src/command/DefaultMenus.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ define(function (require, exports, module) {
menu.addMenuItem(Commands.NAVIGATE_QUICK_OPEN);
menu.addMenuItem(Commands.NAVIGATE_GOTO_LINE);
menu.addMenuItem(Commands.NAVIGATE_GOTO_DEFINITION);
menu.addMenuItem(Commands.NAVIGATE_GOTO_DEFINITION_PROJECT);
menu.addMenuItem(Commands.NAVIGATE_JUMPTO_DEFINITION);
menu.addMenuItem(Commands.NAVIGATE_GOTO_FIRST_PROBLEM);
menu.addMenuDivider();
Expand Down
238 changes: 238 additions & 0 deletions src/extensions/default/PhpTooling/PHPSymbolProviders.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
/*
* Copyright (c) 2019 - present Adobe. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/

/*jslint regexp: true */

define(function (require, exports, module) {
"use strict";

var EditorManager = brackets.getModule("editor/EditorManager"),
QuickOpen = brackets.getModule("search/QuickOpen"),
Commands = brackets.getModule("command/Commands"),
CommandManager = brackets.getModule("command/CommandManager"),
PathConverters = brackets.getModule("languageTools/PathConverters");

var SymbolKind = QuickOpen.SymbolKind;

function convertRangePosToEditorPos(rangePos) {
return {
line: rangePos.line,
ch: rangePos.character
};
}

function SymbolInformation(label, fullPath, selectionRange, type, scope, isDocumentSymbolRequest) {
this.label = label;
this.fullPath = fullPath;
this.selectionRange = selectionRange;
this.type = type;
this.scope = scope;
this.isDocumentSymbolRequest = isDocumentSymbolRequest;
}

function createList(list, isDocumentSymbolRequest) {
var newlist = [];
for (var i = 0; i < list.length; i++) {
var symbolInfo = list[i],
label = symbolInfo.name,
type = SymbolKind[symbolInfo.kind.toString()],
fullPath = null,
selectionRange = null,
scope = symbolInfo.containerName,
range = null;

if (!isDocumentSymbolRequest) {
fullPath = PathConverters.uriToPath(symbolInfo.location.uri);
} else {
if (symbolInfo.selectionRange) {
range = symbolInfo.selectionRange;
selectionRange = {
from: convertRangePosToEditorPos(range.start),
to: convertRangePosToEditorPos(range.end)
};
}
}

if (!selectionRange) {
range = symbolInfo.location.range;
selectionRange = {
from: convertRangePosToEditorPos(range.start),
to: convertRangePosToEditorPos(range.end)
};
}

newlist.push(new SymbolInformation(label, fullPath, selectionRange, type, scope, isDocumentSymbolRequest));
}

return newlist;
}

function transFormToSymbolList(query, matcher, results, isDocumentSymbolRequest) {
var list = createList(results, isDocumentSymbolRequest);

// Filter and rank how good each match is
var filteredList = $.map(list, function (symbolInfo) {
var searchResult = matcher.match(symbolInfo.label, query);
if (searchResult) {
searchResult.symbolInfo = symbolInfo;
}
return searchResult;
});

// Sort based on ranking & basic alphabetical order
QuickOpen.basicMatchSort(filteredList);

return filteredList;
}

/**
* Provider for Document Symbols
*/
function DocumentSymbolsProvider(client) {
this.client = client;
}

DocumentSymbolsProvider.prototype.match = function (query) {
return query.startsWith("@");
};

DocumentSymbolsProvider.prototype.search = function (query, matcher) {
if (!this.client) {
return $.Deferred().reject();
}

var serverCapabilities = this.client.getServerCapabilities();
if (!serverCapabilities || !serverCapabilities.documentSymbolProvider) {
return $.Deferred().reject();
}

var editor = EditorManager.getActiveEditor(),
docPath = editor.document.file._path,
retval = $.Deferred();
query = query.slice(1);

this.client.requestSymbolsForDocument({
filePath: docPath
}).done(function (results) {
var resultList = transFormToSymbolList(query, matcher, results, true);
retval.resolve(resultList);
});

return retval;
};

DocumentSymbolsProvider.prototype.itemFocus = function (selectedItem, query, explicit) {
if (!selectedItem || (query.length < 2 && !explicit)) {
return;
}

var range = selectedItem.symbolInfo.selectionRange;
EditorManager.getCurrentFullEditor().setSelection(range.from, range.to, true);
};

DocumentSymbolsProvider.prototype.itemSelect = function (selectedItem, query) {
this.itemFocus(selectedItem, query, true);
};

DocumentSymbolsProvider.prototype.resultsFormatter = function (item, query) {
var displayName = QuickOpen.highlightMatch(item);
query = query.slice(1);

if (item.symbolInfo.scope) {
return "<li>" + displayName + " (" + item.symbolInfo.type + ")" + "<br /><span class='quick-open-path'>" + item.symbolInfo.scope + "</span></li>";
}
return "<li>" + displayName + " (" + item.symbolInfo.type + ")" + "</li>";
};

/**
* Provider for Project Symbols
*/
function ProjectSymbolsProvider(client) {
this.client = client;
}

ProjectSymbolsProvider.prototype.match = function (query) {
return query.startsWith("#");
};

ProjectSymbolsProvider.prototype.search = function (query, matcher) {
if (!this.client) {
return $.Deferred().reject();
}

var serverCapabilities = this.client.getServerCapabilities();
if (!serverCapabilities || !serverCapabilities.workspaceSymbolProvider) {
return $.Deferred().reject();
}

var retval = $.Deferred();
query = query.slice(1);

this.client.requestSymbolsForWorkspace({
query: query
}).done(function (results) {
var resultList = transFormToSymbolList(query, matcher, results);
retval.resolve(resultList);
});

return retval;
};

ProjectSymbolsProvider.prototype.itemFocus = function (selectedItem, query, explicit) {
if (!selectedItem || (query.length < 2 && !explicit)) {
return;
}
};

ProjectSymbolsProvider.prototype.itemSelect = function (selectedItem, query) {
var fullPath = selectedItem.symbolInfo.fullPath,
range = selectedItem.symbolInfo.selectionRange;

if (fullPath) {
CommandManager.execute(Commands.CMD_ADD_TO_WORKINGSET_AND_OPEN, {
fullPath: fullPath
})
.done(function () {
if (range.from) {
var editor = EditorManager.getCurrentFullEditor();
editor.setCursorPos(range.from.line, range.from.ch, true);
}
});
}
};

ProjectSymbolsProvider.prototype.resultsFormatter = function (item, query) {
var displayName = QuickOpen.highlightMatch(item);
query = query.slice(1);

if (item.symbolInfo.scope) {
return "<li>" + displayName + " (" + item.symbolInfo.type + ")" + "<br /><span class='quick-open-path'>" + item.symbolInfo.scope + "</span><br /><br /><span class='quick-open-path'>" + item.symbolInfo.fullPath + "</span></li>";
}
return "<li>" + displayName + " (" + item.symbolInfo.type + ")" + "<br /><br /><span class='quick-open-path'>" + item.symbolInfo.fullPath + "</span></li>";
};

exports.SymbolProviders = {
DocumentSymbolsProvider: DocumentSymbolsProvider,
ProjectSymbolsProvider: ProjectSymbolsProvider
};
});
32 changes: 31 additions & 1 deletion src/extensions/default/PhpTooling/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@ define(function (require, exports, module) {
EditorManager = brackets.getModule("editor/EditorManager"),
LanguageManager = brackets.getModule("language/LanguageManager"),
CodeHintManager = brackets.getModule("editor/CodeHintManager"),
QuickOpen = brackets.getModule("search/QuickOpen"),
ParameterHintManager = brackets.getModule("features/ParameterHintsManager"),
JumpToDefManager = brackets.getModule("features/JumpToDefManager"),
CodeInspection = brackets.getModule("language/CodeInspection"),
DefaultProviders = brackets.getModule("languageTools/DefaultProviders"),
CodeHintsProvider = require("CodeHintsProvider").CodeHintsProvider,
SymbolProviders = require("PHPSymbolProviders").SymbolProviders,
DefaultEventHandlers = brackets.getModule("languageTools/DefaultEventHandlers"),
PreferencesManager = brackets.getModule("preferences/PreferencesManager"),
Strings = brackets.getModule("strings"),
Expand All @@ -61,7 +63,9 @@ define(function (require, exports, module) {
chProvider,
phProvider,
lProvider,
jdProvider;
jdProvider,
dSymProvider,
pSymProvider;

PreferencesManager.definePreference("php", "object", phpConfig, {
description: Strings.DESCRIPTION_PHP_TOOLING_CONFIGURATION
Expand Down Expand Up @@ -102,6 +106,8 @@ define(function (require, exports, module) {
phProvider = new DefaultProviders.ParameterHintsProvider(_client),
lProvider = new DefaultProviders.LintingProvider(_client),
jdProvider = new DefaultProviders.JumpToDefProvider(_client);
dSymProvider = new SymbolProviders.DocumentSymbolsProvider(_client);
pSymProvider = new SymbolProviders.ProjectSymbolsProvider(_client);

JumpToDefManager.registerJumpToDefProvider(jdProvider, ["php"], 0);
CodeHintManager.registerHintProvider(chProvider, ["php"], 0);
Expand All @@ -110,6 +116,30 @@ define(function (require, exports, module) {
name: "",
scanFileAsync: lProvider.getInspectionResultsAsync.bind(lProvider)
});
//Attach plugin for Document Symbols
QuickOpen.addQuickOpenPlugin({
name: "PHP Document Symbols",
label: Strings.CMD_FIND_DOCUMENT_SYMBOLS + "\u2026",
languageIds: ["php"],
search: dSymProvider.search.bind(dSymProvider),
match: dSymProvider.match.bind(dSymProvider),
itemFocus: dSymProvider.itemFocus.bind(dSymProvider),
itemSelect: dSymProvider.itemSelect.bind(dSymProvider),
resultsFormatter: dSymProvider.resultsFormatter.bind(dSymProvider)
});
CommandManager.get(Commands.NAVIGATE_GOTO_DEFINITION).setEnabled(true);
//Attach plugin for Project Symbols
QuickOpen.addQuickOpenPlugin({
name: "PHP Project Symbols",
label: Strings.CMD_FIND_PROJECT_SYMBOLS + "\u2026",
languageIds: ["php"],
search: pSymProvider.search.bind(pSymProvider),
match: pSymProvider.match.bind(pSymProvider),
itemFocus: pSymProvider.itemFocus.bind(pSymProvider),
itemSelect: pSymProvider.itemSelect.bind(pSymProvider),
resultsFormatter: pSymProvider.resultsFormatter.bind(pSymProvider)
});
CommandManager.get(Commands.NAVIGATE_GOTO_DEFINITION_PROJECT).setEnabled(true);

_client.addOnCodeInspection(lProvider.setInspectionResults.bind(lProvider));
}
Expand Down
13 changes: 13 additions & 0 deletions src/extensions/default/PhpTooling/unittest-files/test/test4.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

class MyClass{
public static $staticValue = 'static';
const constantValue = 'const';
public $publicValue = 'public';
public static function staticMethod(){}
public function publicFunction(){}
}

$myclass = new MyClass();

?>