mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into baseZero
Conflicts: src/harness/harnessLanguageService.ts
This commit is contained in:
@@ -151,8 +151,9 @@ module ts.BreakpointResolver {
|
||||
return spanInForStatement(<ForStatement>node);
|
||||
|
||||
case SyntaxKind.ForInStatement:
|
||||
case SyntaxKind.ForOfStatement:
|
||||
// span on for (a in ...)
|
||||
return textSpan(node, findNextToken((<ForInStatement>node).expression, node));
|
||||
return textSpan(node, findNextToken((<ForInStatement | ForOfStatement>node).expression, node));
|
||||
|
||||
case SyntaxKind.SwitchStatement:
|
||||
// span on switch(...)
|
||||
@@ -261,7 +262,8 @@ module ts.BreakpointResolver {
|
||||
|
||||
function spanInVariableDeclaration(variableDeclaration: VariableDeclaration): TextSpan {
|
||||
// If declaration of for in statement, just set the span in parent
|
||||
if (variableDeclaration.parent.parent.kind === SyntaxKind.ForInStatement) {
|
||||
if (variableDeclaration.parent.parent.kind === SyntaxKind.ForInStatement ||
|
||||
variableDeclaration.parent.parent.kind === SyntaxKind.ForOfStatement) {
|
||||
return spanInNode(variableDeclaration.parent.parent);
|
||||
}
|
||||
|
||||
@@ -362,6 +364,7 @@ module ts.BreakpointResolver {
|
||||
case SyntaxKind.WhileStatement:
|
||||
case SyntaxKind.IfStatement:
|
||||
case SyntaxKind.ForInStatement:
|
||||
case SyntaxKind.ForOfStatement:
|
||||
return spanInNodeIfStartsOnSameLine(block.parent, block.statements[0]);
|
||||
|
||||
// Set span on previous token if it starts on same line otherwise on the first statement of the block
|
||||
|
||||
@@ -464,6 +464,9 @@ module ts.formatting {
|
||||
// "in" keyword in for (var x in []) { }
|
||||
case SyntaxKind.ForInStatement:
|
||||
return context.currentTokenSpan.kind === SyntaxKind.InKeyword || context.nextTokenSpan.kind === SyntaxKind.InKeyword;
|
||||
// Technically, "of" is not a binary operator, but format it the same way as "in"
|
||||
case SyntaxKind.ForOfStatement:
|
||||
return context.currentTokenSpan.kind === SyntaxKind.OfKeyword || context.nextTokenSpan.kind === SyntaxKind.OfKeyword;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -592,6 +595,7 @@ module ts.formatting {
|
||||
case SyntaxKind.SwitchStatement:
|
||||
case SyntaxKind.ForStatement:
|
||||
case SyntaxKind.ForInStatement:
|
||||
case SyntaxKind.ForOfStatement:
|
||||
case SyntaxKind.WhileStatement:
|
||||
case SyntaxKind.TryStatement:
|
||||
case SyntaxKind.DoStatement:
|
||||
|
||||
@@ -358,6 +358,7 @@ module ts.formatting {
|
||||
case SyntaxKind.DoStatement:
|
||||
case SyntaxKind.WhileStatement:
|
||||
case SyntaxKind.ForInStatement:
|
||||
case SyntaxKind.ForOfStatement:
|
||||
case SyntaxKind.ForStatement:
|
||||
case SyntaxKind.IfStatement:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
|
||||
@@ -126,7 +126,7 @@ module ts.formatting {
|
||||
static AnyIncludingMultilineComments = TokenRange.FromTokens(TokenRange.Any.GetTokens().concat([SyntaxKind.MultiLineCommentTrivia]));
|
||||
static Keywords = TokenRange.FromRange(SyntaxKind.FirstKeyword, SyntaxKind.LastKeyword);
|
||||
static BinaryOperators = TokenRange.FromRange(SyntaxKind.FirstBinaryOperator, SyntaxKind.LastBinaryOperator);
|
||||
static BinaryKeywordOperators = TokenRange.FromTokens([SyntaxKind.InKeyword, SyntaxKind.InstanceOfKeyword]);
|
||||
static BinaryKeywordOperators = TokenRange.FromTokens([SyntaxKind.InKeyword, SyntaxKind.InstanceOfKeyword, SyntaxKind.OfKeyword]);
|
||||
static UnaryPrefixOperators = TokenRange.FromTokens([SyntaxKind.PlusPlusToken, SyntaxKind.MinusMinusToken, SyntaxKind.TildeToken, SyntaxKind.ExclamationToken]);
|
||||
static UnaryPrefixExpressions = TokenRange.FromTokens([SyntaxKind.NumericLiteral, SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.OpenBracketToken, SyntaxKind.OpenBraceToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword]);
|
||||
static UnaryPreincrementExpressions = TokenRange.FromTokens([SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword]);
|
||||
@@ -134,7 +134,7 @@ module ts.formatting {
|
||||
static UnaryPredecrementExpressions = TokenRange.FromTokens([SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword]);
|
||||
static UnaryPostdecrementExpressions = TokenRange.FromTokens([SyntaxKind.Identifier, SyntaxKind.CloseParenToken, SyntaxKind.CloseBracketToken, SyntaxKind.NewKeyword]);
|
||||
static Comments = TokenRange.FromTokens([SyntaxKind.SingleLineCommentTrivia, SyntaxKind.MultiLineCommentTrivia]);
|
||||
static TypeNames = TokenRange.FromTokens([SyntaxKind.Identifier, SyntaxKind.NumberKeyword, SyntaxKind.StringKeyword, SyntaxKind.BooleanKeyword, SyntaxKind.VoidKeyword, SyntaxKind.AnyKeyword]);
|
||||
static TypeNames = TokenRange.FromTokens([SyntaxKind.Identifier, SyntaxKind.NumberKeyword, SyntaxKind.StringKeyword, SyntaxKind.BooleanKeyword, SyntaxKind.SymbolKeyword, SyntaxKind.VoidKeyword, SyntaxKind.AnyKeyword]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
module ts.NavigateTo {
|
||||
type RawNavigateToItem = { name: string; fileName: string; matchKind: MatchKind; declaration: Declaration };
|
||||
|
||||
enum MatchKind {
|
||||
none = 0,
|
||||
exact = 1,
|
||||
substring = 2,
|
||||
prefix = 3
|
||||
}
|
||||
|
||||
export function getNavigateToItems(program: Program, cancellationToken: CancellationTokenObject, searchValue: string, maxResultCount: number): NavigateToItem[]{
|
||||
// Split search value in terms array
|
||||
var terms = searchValue.split(" ");
|
||||
|
||||
// default NavigateTo approach: if search term contains only lower-case chars - use case-insensitive search, otherwise switch to case-sensitive version
|
||||
var searchTerms = map(terms, t => ({ caseSensitive: hasAnyUpperCaseCharacter(t), term: t }));
|
||||
|
||||
var rawItems: RawNavigateToItem[] = [];
|
||||
|
||||
// Search the declarations in all files and output matched NavigateToItem into array of NavigateToItem[]
|
||||
forEach(program.getSourceFiles(), sourceFile => {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
|
||||
var fileName = sourceFile.fileName;
|
||||
var declarations = sourceFile.getNamedDeclarations();
|
||||
for (var i = 0, n = declarations.length; i < n; i++) {
|
||||
var declaration = declarations[i];
|
||||
// TODO(jfreeman): Skip this declaration if it has a computed name
|
||||
var name = (<Identifier>declaration.name).text;
|
||||
var matchKind = getMatchKind(searchTerms, name);
|
||||
if (matchKind !== MatchKind.none) {
|
||||
rawItems.push({ name, fileName, matchKind, declaration });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
rawItems.sort((i1, i2) => i1.matchKind - i2.matchKind);
|
||||
if (maxResultCount !== undefined) {
|
||||
rawItems = rawItems.slice(0, maxResultCount);
|
||||
}
|
||||
|
||||
var items = map(rawItems, createNavigateToItem);
|
||||
|
||||
return items;
|
||||
|
||||
function createNavigateToItem(rawItem: RawNavigateToItem): NavigateToItem {
|
||||
var declaration = rawItem.declaration;
|
||||
var container = <Declaration>getContainerNode(declaration);
|
||||
return {
|
||||
name: rawItem.name,
|
||||
kind: getNodeKind(declaration),
|
||||
kindModifiers: getNodeModifiers(declaration),
|
||||
matchKind: MatchKind[rawItem.matchKind],
|
||||
fileName: rawItem.fileName,
|
||||
textSpan: createTextSpanFromBounds(declaration.getStart(), declaration.getEnd()),
|
||||
// TODO(jfreeman): What should be the containerName when the container has a computed name?
|
||||
containerName: container && container.name ? (<Identifier>container.name).text : "",
|
||||
containerKind: container && container.name ? getNodeKind(container) : ""
|
||||
};
|
||||
}
|
||||
|
||||
function hasAnyUpperCaseCharacter(s: string): boolean {
|
||||
for (var i = 0, n = s.length; i < n; i++) {
|
||||
var c = s.charCodeAt(i);
|
||||
if ((CharacterCodes.A <= c && c <= CharacterCodes.Z) ||
|
||||
(c >= CharacterCodes.maxAsciiCharacter && s.charAt(i).toLocaleLowerCase() !== s.charAt(i))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function getMatchKind(searchTerms: { caseSensitive: boolean; term: string }[], name: string): MatchKind {
|
||||
var matchKind = MatchKind.none;
|
||||
|
||||
if (name) {
|
||||
for (var j = 0, n = searchTerms.length; j < n; j++) {
|
||||
var searchTerm = searchTerms[j];
|
||||
var nameToSearch = searchTerm.caseSensitive ? name : name.toLocaleLowerCase();
|
||||
// in case of case-insensitive search searchTerm.term will already be lower-cased
|
||||
var index = nameToSearch.indexOf(searchTerm.term);
|
||||
if (index < 0) {
|
||||
// Didn't match.
|
||||
return MatchKind.none;
|
||||
}
|
||||
|
||||
var termKind = MatchKind.substring;
|
||||
if (index === 0) {
|
||||
// here we know that match occur at the beginning of the string.
|
||||
// if search term and declName has the same length - we have an exact match, otherwise declName have longer length and this will be prefix match
|
||||
termKind = name.length === searchTerm.term.length ? MatchKind.exact : MatchKind.prefix;
|
||||
}
|
||||
|
||||
// Update our match kind if we don't have one, or if this match is better.
|
||||
if (matchKind === MatchKind.none || termKind < matchKind) {
|
||||
matchKind = termKind;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return matchKind;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -97,8 +97,7 @@ module ts.NavigationBar {
|
||||
function sortNodes(nodes: Node[]): Node[] {
|
||||
return nodes.slice(0).sort((n1: Declaration, n2: Declaration) => {
|
||||
if (n1.name && n2.name) {
|
||||
// TODO(jfreeman): How do we sort declarations with computed names?
|
||||
return (<Identifier>n1.name).text.localeCompare((<Identifier>n2.name).text);
|
||||
return getPropertyNameForPropertyNameNode(n1.name).localeCompare(getPropertyNameForPropertyNameNode(n2.name));
|
||||
}
|
||||
else if (n1.name) {
|
||||
return 1;
|
||||
@@ -426,7 +425,7 @@ module ts.NavigationBar {
|
||||
// Add the constructor parameters in as children of the class (for property parameters).
|
||||
// Note that *all* parameters will be added to the nodes array, but parameters that
|
||||
// are not properties will be filtered out later by createChildItem.
|
||||
var nodes: Node[] = removeComputedProperties(node);
|
||||
var nodes: Node[] = removeDynamicallyNamedProperties(node);
|
||||
if (constructor) {
|
||||
nodes.push.apply(nodes, constructor.parameters);
|
||||
}
|
||||
@@ -455,7 +454,7 @@ module ts.NavigationBar {
|
||||
}
|
||||
|
||||
function createIterfaceItem(node: InterfaceDeclaration): ts.NavigationBarItem {
|
||||
var childItems = getItemsWorker(sortNodes(removeComputedProperties(node)), createChildItem);
|
||||
var childItems = getItemsWorker(sortNodes(removeDynamicallyNamedProperties(node)), createChildItem);
|
||||
return getNavigationBarItem(
|
||||
node.name.text,
|
||||
ts.ScriptElementKind.interfaceElement,
|
||||
@@ -466,10 +465,17 @@ module ts.NavigationBar {
|
||||
}
|
||||
}
|
||||
|
||||
function removeComputedProperties(node: ClassDeclaration | InterfaceDeclaration | EnumDeclaration): Declaration[] {
|
||||
function removeComputedProperties(node: EnumDeclaration): Declaration[] {
|
||||
return filter<Declaration>(node.members, member => member.name === undefined || member.name.kind !== SyntaxKind.ComputedPropertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like removeComputedProperties, but retains the properties with well known symbol names
|
||||
*/
|
||||
function removeDynamicallyNamedProperties(node: ClassDeclaration | InterfaceDeclaration): Declaration[]{
|
||||
return filter<Declaration>(node.members, member => !hasDynamicName(member));
|
||||
}
|
||||
|
||||
function getInnermostModule(node: ModuleDeclaration): ModuleDeclaration {
|
||||
while (node.body.kind === SyntaxKind.ModuleDeclaration) {
|
||||
node = <ModuleDeclaration>node.body;
|
||||
|
||||
@@ -61,6 +61,7 @@ module ts {
|
||||
// to be the entire span of the parent.
|
||||
if (parent.kind === SyntaxKind.DoStatement ||
|
||||
parent.kind === SyntaxKind.ForInStatement ||
|
||||
parent.kind === SyntaxKind.ForOfStatement ||
|
||||
parent.kind === SyntaxKind.ForStatement ||
|
||||
parent.kind === SyntaxKind.IfStatement ||
|
||||
parent.kind === SyntaxKind.WhileStatement ||
|
||||
|
||||
+75
-156
@@ -2,6 +2,7 @@
|
||||
|
||||
/// <reference path='breakpoints.ts' />
|
||||
/// <reference path='outliningElementsCollector.ts' />
|
||||
/// <reference path='navigateTo.ts' />
|
||||
/// <reference path='navigationBar.ts' />
|
||||
/// <reference path='signatureHelp.ts' />
|
||||
/// <reference path='utilities.ts' />
|
||||
@@ -900,7 +901,7 @@ module ts {
|
||||
getReferencesAtPosition(fileName: string, position: number): ReferenceEntry[];
|
||||
getOccurrencesAtPosition(fileName: string, position: number): ReferenceEntry[];
|
||||
|
||||
getNavigateToItems(searchValue: string): NavigateToItem[];
|
||||
getNavigateToItems(searchValue: string, maxResultCount?: number): NavigateToItem[];
|
||||
getNavigationBarItems(fileName: string): NavigationBarItem[];
|
||||
|
||||
getOutliningSpans(fileName: string): OutliningSpan[];
|
||||
@@ -991,6 +992,7 @@ module ts {
|
||||
InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: boolean;
|
||||
PlaceOpenBraceOnNewLineForFunctions: boolean;
|
||||
PlaceOpenBraceOnNewLineForControlBlocks: boolean;
|
||||
[s: string]: boolean | number| string;
|
||||
}
|
||||
|
||||
export interface DefinitionInfo {
|
||||
@@ -1377,13 +1379,6 @@ module ts {
|
||||
public static typeAlias = "type alias name";
|
||||
}
|
||||
|
||||
enum MatchKind {
|
||||
none = 0,
|
||||
exact = 1,
|
||||
substring = 2,
|
||||
prefix = 3
|
||||
}
|
||||
|
||||
/// Language Service
|
||||
|
||||
interface CompletionSession {
|
||||
@@ -1991,6 +1986,62 @@ module ts {
|
||||
});
|
||||
}
|
||||
|
||||
/* @internal */ export function getContainerNode(node: Node): Node {
|
||||
while (true) {
|
||||
node = node.parent;
|
||||
if (!node) {
|
||||
return undefined;
|
||||
}
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.SourceFile:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.MethodSignature:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */ export function getNodeKind(node: Node): string {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ModuleDeclaration: return ScriptElementKind.moduleElement;
|
||||
case SyntaxKind.ClassDeclaration: return ScriptElementKind.classElement;
|
||||
case SyntaxKind.InterfaceDeclaration: return ScriptElementKind.interfaceElement;
|
||||
case SyntaxKind.TypeAliasDeclaration: return ScriptElementKind.typeElement;
|
||||
case SyntaxKind.EnumDeclaration: return ScriptElementKind.enumElement;
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
return isConst(node)
|
||||
? ScriptElementKind.constElement
|
||||
: isLet(node)
|
||||
? ScriptElementKind.letElement
|
||||
: ScriptElementKind.variableElement;
|
||||
case SyntaxKind.FunctionDeclaration: return ScriptElementKind.functionElement;
|
||||
case SyntaxKind.GetAccessor: return ScriptElementKind.memberGetAccessorElement;
|
||||
case SyntaxKind.SetAccessor: return ScriptElementKind.memberSetAccessorElement;
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.MethodSignature:
|
||||
return ScriptElementKind.memberFunctionElement;
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.PropertySignature:
|
||||
return ScriptElementKind.memberVariableElement;
|
||||
case SyntaxKind.IndexSignature: return ScriptElementKind.indexSignatureElement;
|
||||
case SyntaxKind.ConstructSignature: return ScriptElementKind.constructSignatureElement;
|
||||
case SyntaxKind.CallSignature: return ScriptElementKind.callSignatureElement;
|
||||
case SyntaxKind.Constructor: return ScriptElementKind.constructorImplementationElement;
|
||||
case SyntaxKind.TypeParameter: return ScriptElementKind.typeParameterElement;
|
||||
case SyntaxKind.EnumMember: return ScriptElementKind.variableElement;
|
||||
case SyntaxKind.Parameter: return (node.flags & NodeFlags.AccessibilityModifier) ? ScriptElementKind.memberVariableElement : ScriptElementKind.parameterElement;
|
||||
}
|
||||
return ScriptElementKind.unknown;
|
||||
}
|
||||
|
||||
export function createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry = createDocumentRegistry()): LanguageService {
|
||||
var syntaxTreeCache: SyntaxTreeCache = new SyntaxTreeCache(host);
|
||||
var ruleProvider: formatting.RulesProvider;
|
||||
@@ -2721,29 +2772,6 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getContainerNode(node: Node): Node {
|
||||
while (true) {
|
||||
node = node.parent;
|
||||
if (!node) {
|
||||
return undefined;
|
||||
}
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.SourceFile:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.MethodSignature:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(drosen): use contextual SemanticMeaning.
|
||||
function getSymbolKind(symbol: Symbol, typeResolver: TypeChecker, location: Node): string {
|
||||
var flags = symbol.getFlags();
|
||||
@@ -2830,39 +2858,6 @@ module ts {
|
||||
return ScriptElementKind.unknown;
|
||||
}
|
||||
|
||||
function getNodeKind(node: Node): string {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ModuleDeclaration: return ScriptElementKind.moduleElement;
|
||||
case SyntaxKind.ClassDeclaration: return ScriptElementKind.classElement;
|
||||
case SyntaxKind.InterfaceDeclaration: return ScriptElementKind.interfaceElement;
|
||||
case SyntaxKind.TypeAliasDeclaration: return ScriptElementKind.typeElement;
|
||||
case SyntaxKind.EnumDeclaration: return ScriptElementKind.enumElement;
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
return isConst(node)
|
||||
? ScriptElementKind.constElement
|
||||
: isLet(node)
|
||||
? ScriptElementKind.letElement
|
||||
: ScriptElementKind.variableElement;
|
||||
case SyntaxKind.FunctionDeclaration: return ScriptElementKind.functionElement;
|
||||
case SyntaxKind.GetAccessor: return ScriptElementKind.memberGetAccessorElement;
|
||||
case SyntaxKind.SetAccessor: return ScriptElementKind.memberSetAccessorElement;
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.MethodSignature:
|
||||
return ScriptElementKind.memberFunctionElement;
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.PropertySignature:
|
||||
return ScriptElementKind.memberVariableElement;
|
||||
case SyntaxKind.IndexSignature: return ScriptElementKind.indexSignatureElement;
|
||||
case SyntaxKind.ConstructSignature: return ScriptElementKind.constructSignatureElement;
|
||||
case SyntaxKind.CallSignature: return ScriptElementKind.callSignatureElement;
|
||||
case SyntaxKind.Constructor: return ScriptElementKind.constructorImplementationElement;
|
||||
case SyntaxKind.TypeParameter: return ScriptElementKind.typeParameterElement;
|
||||
case SyntaxKind.EnumMember: return ScriptElementKind.variableElement;
|
||||
case SyntaxKind.Parameter: return (node.flags & NodeFlags.AccessibilityModifier) ? ScriptElementKind.memberVariableElement : ScriptElementKind.parameterElement;
|
||||
}
|
||||
return ScriptElementKind.unknown;
|
||||
}
|
||||
|
||||
function getSymbolModifiers(symbol: Symbol): string {
|
||||
return symbol && symbol.declarations && symbol.declarations.length > 0
|
||||
? getNodeModifiers(symbol.declarations[0])
|
||||
@@ -3441,7 +3436,9 @@ module ts {
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.ForKeyword:
|
||||
if (hasKind(node.parent, SyntaxKind.ForStatement) || hasKind(node.parent, SyntaxKind.ForInStatement)) {
|
||||
if (hasKind(node.parent, SyntaxKind.ForStatement) ||
|
||||
hasKind(node.parent, SyntaxKind.ForInStatement) ||
|
||||
hasKind(node.parent, SyntaxKind.ForOfStatement)) {
|
||||
return getLoopBreakContinueOccurrences(<IterationStatement>node.parent);
|
||||
}
|
||||
break;
|
||||
@@ -3718,6 +3715,7 @@ module ts {
|
||||
switch (owner.kind) {
|
||||
case SyntaxKind.ForStatement:
|
||||
case SyntaxKind.ForInStatement:
|
||||
case SyntaxKind.ForOfStatement:
|
||||
case SyntaxKind.DoStatement:
|
||||
case SyntaxKind.WhileStatement:
|
||||
return getLoopBreakContinueOccurrences(<IterationStatement>owner)
|
||||
@@ -3762,6 +3760,7 @@ module ts {
|
||||
// Fall through.
|
||||
case SyntaxKind.ForStatement:
|
||||
case SyntaxKind.ForInStatement:
|
||||
case SyntaxKind.ForOfStatement:
|
||||
case SyntaxKind.WhileStatement:
|
||||
case SyntaxKind.DoStatement:
|
||||
if (!statement.label || isLabeledBy(node, statement.label.text)) {
|
||||
@@ -4658,89 +4657,10 @@ module ts {
|
||||
}
|
||||
|
||||
/// NavigateTo
|
||||
function getNavigateToItems(searchValue: string): NavigateToItem[] {
|
||||
function getNavigateToItems(searchValue: string, maxResultCount?: number): NavigateToItem[] {
|
||||
synchronizeHostData();
|
||||
|
||||
// Split search value in terms array
|
||||
var terms = searchValue.split(" ");
|
||||
|
||||
// default NavigateTo approach: if search term contains only lower-case chars - use case-insensitive search, otherwise switch to case-sensitive version
|
||||
var searchTerms = map(terms, t => ({ caseSensitive: hasAnyUpperCaseCharacter(t), term: t }));
|
||||
|
||||
var items: NavigateToItem[] = [];
|
||||
|
||||
// Search the declarations in all files and output matched NavigateToItem into array of NavigateToItem[]
|
||||
forEach(program.getSourceFiles(), sourceFile => {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
|
||||
var fileName = sourceFile.fileName;
|
||||
var declarations = sourceFile.getNamedDeclarations();
|
||||
for (var i = 0, n = declarations.length; i < n; i++) {
|
||||
var declaration = declarations[i];
|
||||
// TODO(jfreeman): Skip this declaration if it has a computed name
|
||||
var name = (<Identifier>declaration.name).text;
|
||||
var matchKind = getMatchKind(searchTerms, name);
|
||||
if (matchKind !== MatchKind.none) {
|
||||
var container = <Declaration>getContainerNode(declaration);
|
||||
items.push({
|
||||
name: name,
|
||||
kind: getNodeKind(declaration),
|
||||
kindModifiers: getNodeModifiers(declaration),
|
||||
matchKind: MatchKind[matchKind],
|
||||
fileName: fileName,
|
||||
textSpan: createTextSpanFromBounds(declaration.getStart(), declaration.getEnd()),
|
||||
// TODO(jfreeman): What should be the containerName when the container has a computed name?
|
||||
containerName: container && container.name ? (<Identifier>container.name).text : "",
|
||||
containerKind: container && container.name ? getNodeKind(container) : ""
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return items;
|
||||
|
||||
function hasAnyUpperCaseCharacter(s: string): boolean {
|
||||
for (var i = 0, n = s.length; i < n; i++) {
|
||||
var c = s.charCodeAt(i);
|
||||
if ((CharacterCodes.A <= c && c <= CharacterCodes.Z) ||
|
||||
(c >= CharacterCodes.maxAsciiCharacter && s.charAt(i).toLocaleLowerCase() !== s.charAt(i))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function getMatchKind(searchTerms: { caseSensitive: boolean; term: string }[], name: string): MatchKind {
|
||||
var matchKind = MatchKind.none;
|
||||
|
||||
if (name) {
|
||||
for (var j = 0, n = searchTerms.length; j < n; j++) {
|
||||
var searchTerm = searchTerms[j];
|
||||
var nameToSearch = searchTerm.caseSensitive ? name : name.toLocaleLowerCase();
|
||||
// in case of case-insensitive search searchTerm.term will already be lower-cased
|
||||
var index = nameToSearch.indexOf(searchTerm.term);
|
||||
if (index < 0) {
|
||||
// Didn't match.
|
||||
return MatchKind.none;
|
||||
}
|
||||
|
||||
var termKind = MatchKind.substring;
|
||||
if (index === 0) {
|
||||
// here we know that match occur at the beginning of the string.
|
||||
// if search term and declName has the same length - we have an exact match, otherwise declName have longer length and this will be prefix match
|
||||
termKind = name.length === searchTerm.term.length ? MatchKind.exact : MatchKind.prefix;
|
||||
}
|
||||
|
||||
// Update our match kind if we don't have one, or if this match is better.
|
||||
if (matchKind === MatchKind.none || termKind < matchKind) {
|
||||
matchKind = termKind;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return matchKind;
|
||||
}
|
||||
return ts.NavigateTo.getNavigateToItems(program, cancellationToken, searchValue, maxResultCount);
|
||||
}
|
||||
|
||||
function containErrors(diagnostics: Diagnostic[]): boolean {
|
||||
@@ -5540,11 +5460,13 @@ module ts {
|
||||
var declarations = symbol.getDeclarations();
|
||||
if (declarations && declarations.length > 0) {
|
||||
// Disallow rename for elements that are defined in the standard TypeScript library.
|
||||
var defaultLibFile = getDefaultLibFileName(host.getCompilationSettings());
|
||||
for (var i = 0; i < declarations.length; i++) {
|
||||
var sourceFile = declarations[i].getSourceFile();
|
||||
if (sourceFile && endsWith(sourceFile.fileName, defaultLibFile)) {
|
||||
return getRenameInfoError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library.key));
|
||||
var defaultLibFileName = host.getDefaultLibFileName(host.getCompilationSettings());
|
||||
if (defaultLibFileName) {
|
||||
for (var i = 0; i < declarations.length; i++) {
|
||||
var sourceFile = declarations[i].getSourceFile();
|
||||
if (sourceFile && getCanonicalFileName(ts.normalizePath(sourceFile.fileName)) === getCanonicalFileName(ts.normalizePath(defaultLibFileName))) {
|
||||
return getRenameInfoError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library.key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5566,10 +5488,6 @@ module ts {
|
||||
|
||||
return getRenameInfoError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_this_element.key));
|
||||
|
||||
function endsWith(string: string, value: string): boolean {
|
||||
return string.lastIndexOf(value) + value.length === string.length;
|
||||
}
|
||||
|
||||
function getRenameInfoError(localizedErrorMessage: string): RenameInfo {
|
||||
return {
|
||||
canRename: false,
|
||||
@@ -5799,7 +5717,8 @@ module ts {
|
||||
else if (token === SyntaxKind.AnyKeyword ||
|
||||
token === SyntaxKind.StringKeyword ||
|
||||
token === SyntaxKind.NumberKeyword ||
|
||||
token === SyntaxKind.BooleanKeyword) {
|
||||
token === SyntaxKind.BooleanKeyword ||
|
||||
token === SyntaxKind.SymbolKeyword) {
|
||||
if (angleBracketStack > 0 && !syntacticClassifierAbsent) {
|
||||
// If it looks like we're could be in something generic, don't classify this
|
||||
// as a keyword. We may just get overwritten by the syntactic classifier,
|
||||
|
||||
@@ -138,7 +138,7 @@ module ts {
|
||||
* Returns a JSON-encoded value of the type:
|
||||
* { name: string; kind: string; kindModifiers: string; containerName: string; containerKind: string; matchKind: string; fileName: string; textSpan: { start: number; length: number}; } [] = [];
|
||||
*/
|
||||
getNavigateToItems(searchValue: string): string;
|
||||
getNavigateToItems(searchValue: string, maxResultCount?: number): string;
|
||||
|
||||
/**
|
||||
* Returns a JSON-encoded value of the type:
|
||||
@@ -274,10 +274,7 @@ module ts {
|
||||
}
|
||||
|
||||
public getDefaultLibFileName(options: CompilerOptions): string {
|
||||
// Shim the API changes for 1.5 release. This should be removed once
|
||||
// TypeScript 1.5 has shipped.
|
||||
return "";
|
||||
//return this.shimHost.getDefaultLibFileName(JSON.stringify(options));
|
||||
return this.shimHost.getDefaultLibFileName(JSON.stringify(options));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -631,11 +628,11 @@ module ts {
|
||||
/// NAVIGATE TO
|
||||
|
||||
/** Return a list of symbols that are interesting to navigate to */
|
||||
public getNavigateToItems(searchValue: string): string {
|
||||
public getNavigateToItems(searchValue: string, maxResultCount?: number): string {
|
||||
return this.forwardJSONCall(
|
||||
"getNavigateToItems('" + searchValue + "')",
|
||||
"getNavigateToItems('" + searchValue + "', " + maxResultCount+ ")",
|
||||
() => {
|
||||
var items = this.languageService.getNavigateToItems(searchValue);
|
||||
var items = this.languageService.getNavigateToItems(searchValue, maxResultCount);
|
||||
return items;
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user