mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into lint_better
This commit is contained in:
@@ -370,8 +370,8 @@ namespace ts.BreakpointResolver {
|
||||
}
|
||||
|
||||
function textSpanFromVariableDeclaration(variableDeclaration: VariableDeclaration): TextSpan {
|
||||
const declarations = variableDeclaration.parent.declarations;
|
||||
if (declarations && declarations[0] === variableDeclaration) {
|
||||
if (variableDeclaration.parent.kind === SyntaxKind.VariableDeclarationList &&
|
||||
variableDeclaration.parent.declarations[0] === variableDeclaration) {
|
||||
// First declaration - include let keyword
|
||||
return textSpan(findPrecedingToken(variableDeclaration.pos, sourceFile, variableDeclaration.parent), variableDeclaration);
|
||||
}
|
||||
@@ -400,8 +400,8 @@ namespace ts.BreakpointResolver {
|
||||
return textSpanFromVariableDeclaration(variableDeclaration);
|
||||
}
|
||||
|
||||
const declarations = variableDeclaration.parent.declarations;
|
||||
if (declarations && declarations[0] !== variableDeclaration) {
|
||||
if (variableDeclaration.parent.kind === SyntaxKind.VariableDeclarationList &&
|
||||
variableDeclaration.parent.declarations[0] !== variableDeclaration) {
|
||||
// If we cannot set breakpoint on this declaration, set it on previous one
|
||||
// Because the variable declaration may be binding pattern and
|
||||
// we would like to set breakpoint in last binding element if that's the case,
|
||||
|
||||
@@ -22,8 +22,8 @@ namespace ts.codefix {
|
||||
const classDecl = token.parent as ClassLikeDeclaration;
|
||||
const startPos = classDecl.members.pos;
|
||||
|
||||
const classType = checker.getTypeAtLocation(classDecl) as InterfaceType;
|
||||
const instantiatedExtendsType = checker.getBaseTypes(classType)[0];
|
||||
const extendsNode = getClassExtendsHeritageClauseElement(classDecl);
|
||||
const instantiatedExtendsType = checker.getTypeAtLocation(extendsNode);
|
||||
|
||||
// Note that this is ultimately derived from a map indexed by symbol names,
|
||||
// so duplicates cannot occur.
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
const startPos: number = classDecl.members.pos;
|
||||
const classType = checker.getTypeAtLocation(classDecl);
|
||||
const classType = checker.getTypeAtLocation(classDecl) as InterfaceType;
|
||||
const implementedTypeNodes = getClassImplementsHeritageClauseElements(classDecl);
|
||||
|
||||
const hasNumericIndexSignature = !!checker.getIndexTypeOfType(classType, IndexKind.Number);
|
||||
@@ -25,9 +25,9 @@ namespace ts.codefix {
|
||||
|
||||
const result: CodeAction[] = [];
|
||||
for (const implementedTypeNode of implementedTypeNodes) {
|
||||
const implementedType = checker.getTypeFromTypeNode(implementedTypeNode) as InterfaceType;
|
||||
// Note that this is ultimately derived from a map indexed by symbol names,
|
||||
// so duplicates cannot occur.
|
||||
const implementedType = checker.getTypeAtLocation(implementedTypeNode) as InterfaceType;
|
||||
const implementedTypeSymbols = checker.getPropertiesOfType(implementedType);
|
||||
const nonPrivateMembers = implementedTypeSymbols.filter(symbol => !(getModifierFlags(symbol.valueDeclaration) & ModifierFlags.Private));
|
||||
|
||||
|
||||
@@ -23,8 +23,6 @@ namespace ts.codefix {
|
||||
* @returns Empty string iff there we can't figure out a representation for `symbol` in `enclosingDeclaration`.
|
||||
*/
|
||||
function getInsertionForMemberSymbol(symbol: Symbol, enclosingDeclaration: ClassLikeDeclaration, checker: TypeChecker, newlineChar: string): string {
|
||||
// const name = symbol.getName();
|
||||
const type = checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration);
|
||||
const declarations = symbol.getDeclarations();
|
||||
if (!(declarations && declarations.length)) {
|
||||
return "";
|
||||
@@ -34,6 +32,8 @@ namespace ts.codefix {
|
||||
const name = declaration.name ? declaration.name.getText() : undefined;
|
||||
const visibility = getVisibilityPrefixWithSpace(getModifierFlags(declaration));
|
||||
|
||||
const type = checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration);
|
||||
|
||||
switch (declaration.kind) {
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
|
||||
@@ -3,8 +3,8 @@ namespace ts.codefix {
|
||||
|
||||
type ImportCodeActionKind = "CodeChange" | "InsertingIntoExistingImport" | "NewImport";
|
||||
interface ImportCodeAction extends CodeAction {
|
||||
kind: ImportCodeActionKind,
|
||||
moduleSpecifier?: string
|
||||
kind: ImportCodeActionKind;
|
||||
moduleSpecifier?: string;
|
||||
}
|
||||
|
||||
enum ModuleSpecifierComparison {
|
||||
@@ -75,7 +75,7 @@ namespace ts.codefix {
|
||||
getAllActions() {
|
||||
let result: ImportCodeAction[] = [];
|
||||
for (const key in this.symbolIdToActionMap) {
|
||||
result = concatenate(result, this.symbolIdToActionMap[key])
|
||||
result = concatenate(result, this.symbolIdToActionMap[key]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
+43
-13
@@ -16,11 +16,16 @@ namespace ts.Completions {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isJsDocTagName } = completionData;
|
||||
const { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, requestJsDocTagName, requestJsDocTag } = completionData;
|
||||
|
||||
if (isJsDocTagName) {
|
||||
if (requestJsDocTagName) {
|
||||
// If the current position is a jsDoc tag name, only tag names should be provided for completion
|
||||
return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: JsDoc.getAllJsDocCompletionEntries() };
|
||||
return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: JsDoc.getJSDocTagNameCompletions() };
|
||||
}
|
||||
|
||||
if (requestJsDocTag) {
|
||||
// If the current position is a jsDoc tag, only tags should be provided for completion
|
||||
return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: JsDoc.getJSDocTagCompletions() };
|
||||
}
|
||||
|
||||
const entries: CompletionEntry[] = [];
|
||||
@@ -54,7 +59,7 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
// Add keywords if this is not a member completion list
|
||||
if (!isMemberCompletion && !isJsDocTagName) {
|
||||
if (!isMemberCompletion && !requestJsDocTag && !requestJsDocTagName) {
|
||||
addRange(entries, keywordCompletions);
|
||||
}
|
||||
|
||||
@@ -814,7 +819,10 @@ namespace ts.Completions {
|
||||
function getCompletionData(typeChecker: TypeChecker, log: (message: string) => void, sourceFile: SourceFile, position: number) {
|
||||
const isJavaScriptFile = isSourceFileJavaScript(sourceFile);
|
||||
|
||||
let isJsDocTagName = false;
|
||||
// JsDoc tag-name is just the name of the JSDoc tagname (exclude "@")
|
||||
let requestJsDocTagName = false;
|
||||
// JsDoc tag includes both "@" and tag-name
|
||||
let requestJsDocTag = false;
|
||||
|
||||
let start = timestamp();
|
||||
const currentToken = getTokenAtPosition(sourceFile, position);
|
||||
@@ -826,10 +834,32 @@ namespace ts.Completions {
|
||||
log("getCompletionData: Is inside comment: " + (timestamp() - start));
|
||||
|
||||
if (insideComment) {
|
||||
// The current position is next to the '@' sign, when no tag name being provided yet.
|
||||
// Provide a full list of tag names
|
||||
if (hasDocComment(sourceFile, position) && sourceFile.text.charCodeAt(position - 1) === CharacterCodes.at) {
|
||||
isJsDocTagName = true;
|
||||
if (hasDocComment(sourceFile, position)) {
|
||||
// The current position is next to the '@' sign, when no tag name being provided yet.
|
||||
// Provide a full list of tag names
|
||||
if (sourceFile.text.charCodeAt(position - 1) === CharacterCodes.at) {
|
||||
requestJsDocTagName = true;
|
||||
}
|
||||
else {
|
||||
// When completion is requested without "@", we will have check to make sure that
|
||||
// there are no comments prefix the request position. We will only allow "*" and space.
|
||||
// e.g
|
||||
// /** |c| /*
|
||||
//
|
||||
// /**
|
||||
// |c|
|
||||
// */
|
||||
//
|
||||
// /**
|
||||
// * |c|
|
||||
// */
|
||||
//
|
||||
// /**
|
||||
// * |c|
|
||||
// */
|
||||
const lineStart = getLineStartPositionForPosition(position, sourceFile);
|
||||
requestJsDocTag = !(sourceFile.text.substring(lineStart, position).match(/[^\*|\s|(/\*\*)]/));
|
||||
}
|
||||
}
|
||||
|
||||
// Completion should work inside certain JsDoc tags. For example:
|
||||
@@ -839,7 +869,7 @@ namespace ts.Completions {
|
||||
const tag = getJsDocTagAtPosition(sourceFile, position);
|
||||
if (tag) {
|
||||
if (tag.tagName.pos <= position && position <= tag.tagName.end) {
|
||||
isJsDocTagName = true;
|
||||
requestJsDocTagName = true;
|
||||
}
|
||||
|
||||
switch (tag.kind) {
|
||||
@@ -854,8 +884,8 @@ namespace ts.Completions {
|
||||
}
|
||||
}
|
||||
|
||||
if (isJsDocTagName) {
|
||||
return { symbols: undefined, isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, isJsDocTagName };
|
||||
if (requestJsDocTagName || requestJsDocTag) {
|
||||
return { symbols: undefined, isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, requestJsDocTagName, requestJsDocTag };
|
||||
}
|
||||
|
||||
if (!insideJsDocTagExpression) {
|
||||
@@ -983,7 +1013,7 @@ namespace ts.Completions {
|
||||
|
||||
log("getCompletionData: Semantic work: " + (timestamp() - semanticStart));
|
||||
|
||||
return { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), isJsDocTagName };
|
||||
return { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), requestJsDocTagName, requestJsDocTag };
|
||||
|
||||
function getTypeScriptMemberSymbols(): void {
|
||||
// Right of dot member completion list
|
||||
|
||||
@@ -133,7 +133,7 @@ namespace ts.FindAllReferences {
|
||||
return { symbol };
|
||||
}
|
||||
|
||||
if (ts.isShorthandAmbientModuleSymbol(aliasedSymbol)) {
|
||||
if (ts.isUntypedOrShorthandAmbientModuleSymbol(aliasedSymbol)) {
|
||||
return { symbol, shorthandModuleSymbol: aliasedSymbol };
|
||||
}
|
||||
|
||||
@@ -422,7 +422,7 @@ namespace ts.FindAllReferences {
|
||||
name,
|
||||
textSpan: references[0].textSpan,
|
||||
displayParts: [{ text: name, kind: ScriptElementKind.keyword }]
|
||||
}
|
||||
};
|
||||
|
||||
return [{ definition, references }];
|
||||
}
|
||||
@@ -613,7 +613,7 @@ namespace ts.FindAllReferences {
|
||||
const result: Node[] = [];
|
||||
|
||||
for (const decl of classSymbol.members.get("__constructor").declarations) {
|
||||
const ctrKeyword = ts.findChildOfKind(decl, ts.SyntaxKind.ConstructorKeyword, sourceFile)!
|
||||
const ctrKeyword = ts.findChildOfKind(decl, ts.SyntaxKind.ConstructorKeyword, sourceFile)!;
|
||||
Debug.assert(decl.kind === SyntaxKind.Constructor && !!ctrKeyword);
|
||||
result.push(ctrKeyword);
|
||||
}
|
||||
|
||||
+15
-3
@@ -42,7 +42,8 @@ namespace ts.JsDoc {
|
||||
"prop",
|
||||
"version"
|
||||
];
|
||||
let jsDocCompletionEntries: CompletionEntry[];
|
||||
let jsDocTagNameCompletionEntries: CompletionEntry[];
|
||||
let jsDocTagCompletionEntries: CompletionEntry[];
|
||||
|
||||
export function getJsDocCommentsFromDeclarations(declarations: Declaration[]) {
|
||||
// Only collect doc comments from duplicate declarations once:
|
||||
@@ -88,8 +89,8 @@ namespace ts.JsDoc {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function getAllJsDocCompletionEntries(): CompletionEntry[] {
|
||||
return jsDocCompletionEntries || (jsDocCompletionEntries = ts.map(jsDocTagNames, tagName => {
|
||||
export function getJSDocTagNameCompletions(): CompletionEntry[] {
|
||||
return jsDocTagNameCompletionEntries || (jsDocTagNameCompletionEntries = ts.map(jsDocTagNames, tagName => {
|
||||
return {
|
||||
name: tagName,
|
||||
kind: ScriptElementKind.keyword,
|
||||
@@ -99,6 +100,17 @@ namespace ts.JsDoc {
|
||||
}));
|
||||
}
|
||||
|
||||
export function getJSDocTagCompletions(): CompletionEntry[] {
|
||||
return jsDocTagCompletionEntries || (jsDocTagCompletionEntries = ts.map(jsDocTagNames, tagName => {
|
||||
return {
|
||||
name: `@${tagName}`,
|
||||
kind: ScriptElementKind.keyword,
|
||||
kindModifiers: "",
|
||||
sortText: "0"
|
||||
};
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if position points to a valid position to add JSDoc comments, and if so,
|
||||
* returns the appropriate template. Otherwise returns an empty string.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
namespace ts.SymbolDisplay {
|
||||
// TODO(drosen): use contextual SemanticMeaning.
|
||||
export function getSymbolKind(typeChecker: TypeChecker, symbol: Symbol, location: Node): string {
|
||||
const flags = symbol.getFlags();
|
||||
const { flags } = symbol;
|
||||
|
||||
if (flags & SymbolFlags.Class) return getDeclarationOfKind(symbol, SyntaxKind.ClassExpression) ?
|
||||
ScriptElementKind.localClassElement : ScriptElementKind.classElement;
|
||||
@@ -11,10 +11,10 @@ namespace ts.SymbolDisplay {
|
||||
if (flags & SymbolFlags.Interface) return ScriptElementKind.interfaceElement;
|
||||
if (flags & SymbolFlags.TypeParameter) return ScriptElementKind.typeParameterElement;
|
||||
|
||||
const result = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker, symbol, flags, location);
|
||||
const result = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker, symbol, location);
|
||||
if (result === ScriptElementKind.unknown) {
|
||||
if (flags & SymbolFlags.TypeParameter) return ScriptElementKind.typeParameterElement;
|
||||
if (flags & SymbolFlags.EnumMember) return ScriptElementKind.variableElement;
|
||||
if (flags & SymbolFlags.EnumMember) return ScriptElementKind.enumMemberElement;
|
||||
if (flags & SymbolFlags.Alias) return ScriptElementKind.alias;
|
||||
if (flags & SymbolFlags.Module) return ScriptElementKind.moduleElement;
|
||||
}
|
||||
@@ -22,7 +22,7 @@ namespace ts.SymbolDisplay {
|
||||
return result;
|
||||
}
|
||||
|
||||
function getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker: TypeChecker, symbol: Symbol, flags: SymbolFlags, location: Node) {
|
||||
function getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker: TypeChecker, symbol: Symbol, location: Node) {
|
||||
if (typeChecker.isUndefinedSymbol(symbol)) {
|
||||
return ScriptElementKind.variableElement;
|
||||
}
|
||||
@@ -32,6 +32,7 @@ namespace ts.SymbolDisplay {
|
||||
if (location.kind === SyntaxKind.ThisKeyword && isExpression(location)) {
|
||||
return ScriptElementKind.parameterElement;
|
||||
}
|
||||
const { flags } = symbol;
|
||||
if (flags & SymbolFlags.Variable) {
|
||||
if (isFirstDeclarationOfSymbolParameter(symbol)) {
|
||||
return ScriptElementKind.parameterElement;
|
||||
@@ -93,7 +94,7 @@ namespace ts.SymbolDisplay {
|
||||
const displayParts: SymbolDisplayPart[] = [];
|
||||
let documentation: SymbolDisplayPart[];
|
||||
const symbolFlags = symbol.flags;
|
||||
let symbolKind = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker, symbol, symbolFlags, location);
|
||||
let symbolKind = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker, symbol, location);
|
||||
let hasAddedSymbolInfo: boolean;
|
||||
const isThisExpression = location.kind === SyntaxKind.ThisKeyword && isExpression(location);
|
||||
let type: Type;
|
||||
@@ -319,6 +320,7 @@ namespace ts.SymbolDisplay {
|
||||
}
|
||||
}
|
||||
if (symbolFlags & SymbolFlags.EnumMember) {
|
||||
symbolKind = ScriptElementKind.enumMemberElement;
|
||||
addPrefixForAnyFunctionOrVar(symbol, "enum member");
|
||||
const declaration = symbol.declarations[0];
|
||||
if (declaration.kind === SyntaxKind.EnumMember) {
|
||||
|
||||
@@ -706,8 +706,7 @@ namespace ts {
|
||||
|
||||
/** enum E */
|
||||
export const enumElement = "enum";
|
||||
// TODO: GH#9983
|
||||
export const enumMemberElement = "const";
|
||||
export const enumMemberElement = "enum member";
|
||||
|
||||
/**
|
||||
* Inside module and script only
|
||||
|
||||
Reference in New Issue
Block a user