Skip to content

Code fix for accidental accessor calls #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
cd15560
add code fix
jtbandes Apr 19, 2020
a4322d1
fix forEachChild and update some baselines
jtbandes Apr 19, 2020
6227224
excluding them from forEachChild is easier!
jtbandes Apr 19, 2020
1c72da6
fix(38463): show completions for index access properties
a-tarasyuk May 11, 2020
528d82a
Merge branch 'master' of https://github.com/microsoft/TypeScript into…
a-tarasyuk May 20, 2020
a7364bf
Merge branch 'master' of https://github.com/microsoft/TypeScript into…
a-tarasyuk May 20, 2020
45cf20c
Merge pull request #37800 from jtbandes/diagnose-accidental-accessor-…
sandersn May 21, 2020
e40a2bc
Merge branch 'master' of https://github.com/microsoft/TypeScript into…
a-tarasyuk May 21, 2020
c00aeb5
fix(33286): add outlining for arrow function with one parameter (#38631)
a-tarasyuk May 21, 2020
59d0cee
Fix recently added test so it is cross-plat
weswigham May 21, 2020
62675a5
Merge pull request #38481 from a-tarasyuk/bug/38463
DanielRosenwasser May 21, 2020
0018b8f
Preserve module marker in es2015+ module emit for tool compatability …
weswigham May 21, 2020
79f1ec3
Revert "Wrap classes with decorators or static properties in an IIFE,…
sandersn May 21, 2020
3eaa7c6
Merge pull request #38719 from microsoft/revert-32011
sandersn May 21, 2020
076c3e0
LEGO: check in for master to temporary branch.
csigs May 23, 2020
3e0d58f
LEGO: Merge pull request 38741
csigs May 23, 2020
e354703
Merge remote-tracking branch 'upstream/master' into fix-accidental-ac…
jtbandes May 23, 2020
ac9d57c
cleanup
jtbandes May 23, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -5705,6 +5705,10 @@
"category": "Message",
"code": 95118
},
"Remove parentheses": {
"category": "Message",
"code": 95119
},

"No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer.": {
"category": "Error",
Expand Down
23 changes: 16 additions & 7 deletions src/compiler/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4926,7 +4926,10 @@ namespace ts {
callExpr.expression = expression;
callExpr.questionDotToken = questionDotToken;
callExpr.typeArguments = typeArguments;
callExpr.arguments = parseArgumentList();
const { openParen, argumentList, closeParen } = parseArgumentList();
callExpr.openParenToken = openParen;
callExpr.arguments = argumentList;
callExpr.closeParenToken = closeParen;
if (questionDotToken || tryReparseOptionalChain(expression)) {
callExpr.flags |= NodeFlags.OptionalChain;
}
Expand All @@ -4938,7 +4941,10 @@ namespace ts {
const callExpr = <CallExpression>createNode(SyntaxKind.CallExpression, expression.pos);
callExpr.expression = expression;
callExpr.questionDotToken = questionDotToken;
callExpr.arguments = parseArgumentList();
const { openParen, argumentList, closeParen } = parseArgumentList();
callExpr.openParenToken = openParen;
callExpr.closeParenToken = closeParen;
callExpr.arguments = argumentList;
if (questionDotToken || tryReparseOptionalChain(expression)) {
callExpr.flags |= NodeFlags.OptionalChain;
}
Expand All @@ -4960,10 +4966,10 @@ namespace ts {
}

function parseArgumentList() {
parseExpected(SyntaxKind.OpenParenToken);
const result = parseDelimitedList(ParsingContext.ArgumentExpressions, parseArgumentExpression);
parseExpected(SyntaxKind.CloseParenToken);
return result;
const openParen = parseExpectedToken(SyntaxKind.OpenParenToken);
const argumentList = parseDelimitedList(ParsingContext.ArgumentExpressions, parseArgumentExpression);
const closeParen = parseExpectedToken(SyntaxKind.CloseParenToken);
return { openParen, argumentList, closeParen };
}

function parseTypeArgumentsInExpression() {
Expand Down Expand Up @@ -5250,7 +5256,10 @@ namespace ts {
node.expression = expression;
node.typeArguments = typeArguments;
if (token() === SyntaxKind.OpenParenToken) {
node.arguments = parseArgumentList();
const { openParen, argumentList, closeParen } = parseArgumentList();
node.openParenToken = openParen;
node.arguments = argumentList;
node.closeParenToken = closeParen;
}
else if (node.typeArguments) {
parseErrorAt(fullStart, scanner.getStartPos(), Diagnostics.A_new_expression_with_type_arguments_must_always_be_followed_by_a_parenthesized_argument_list);
Expand Down
37 changes: 24 additions & 13 deletions src/compiler/transformers/module/esnextAnd2015.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,36 @@ namespace ts {
}

if (isExternalModule(node) || compilerOptions.isolatedModules) {
const externalHelpersImportDeclaration = createExternalHelpersImportDeclarationIfNeeded(node, compilerOptions);
if (externalHelpersImportDeclaration) {
const statements: Statement[] = [];
const statementOffset = addPrologue(statements, node.statements);
append(statements, externalHelpersImportDeclaration);

addRange(statements, visitNodes(node.statements, visitor, isStatement, statementOffset));
return updateSourceFileNode(
node,
setTextRange(createNodeArray(statements), node.statements));
}
else {
return visitEachChild(node, visitor, context);
const result = updateExternalModule(node);
if (!isExternalModule(node) || some(result.statements, isExternalModuleIndicator)) {
return result;
}
return updateSourceFileNode(
result,
setTextRange(createNodeArray([...result.statements, createEmptyExports()]), result.statements),
);
}

return node;
}

function updateExternalModule(node: SourceFile) {
const externalHelpersImportDeclaration = createExternalHelpersImportDeclarationIfNeeded(node, compilerOptions);
if (externalHelpersImportDeclaration) {
const statements: Statement[] = [];
const statementOffset = addPrologue(statements, node.statements);
append(statements, externalHelpersImportDeclaration);

addRange(statements, visitNodes(node.statements, visitor, isStatement, statementOffset));
return updateSourceFileNode(
node,
setTextRange(createNodeArray(statements), node.statements));
}
else {
return visitEachChild(node, visitor, context);
}
}

function visitor(node: Node): VisitResult<Node> {
switch (node.kind) {
case SyntaxKind.ImportEqualsDeclaration:
Expand Down
12 changes: 4 additions & 8 deletions src/compiler/transformers/ts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ namespace ts {
IsNamedExternalExport = 1 << 4,
IsDefaultExternalExport = 1 << 5,
IsDerivedClass = 1 << 6,
UseImmediatelyInvokedFunctionExpression = 1 << 7,

HasAnyDecorators = HasConstructorDecorators | HasMemberDecorators,
NeedsName = HasStaticInitializedProperties | HasMemberDecorators,
UseImmediatelyInvokedFunctionExpression = HasAnyDecorators | HasStaticInitializedProperties,
MayNeedImmediatelyInvokedFunctionExpression = HasAnyDecorators | HasStaticInitializedProperties,
IsExported = IsExportOfNamespace | IsDefaultExternalExport | IsNamedExternalExport,
}

Expand Down Expand Up @@ -595,6 +596,7 @@ namespace ts {
if (isExportOfNamespace(node)) facts |= ClassFacts.IsExportOfNamespace;
else if (isDefaultExternalModuleExport(node)) facts |= ClassFacts.IsDefaultExternalExport;
else if (isNamedExternalModuleExport(node)) facts |= ClassFacts.IsNamedExternalExport;
if (languageVersion <= ScriptTarget.ES5 && (facts & ClassFacts.MayNeedImmediatelyInvokedFunctionExpression)) facts |= ClassFacts.UseImmediatelyInvokedFunctionExpression;
return facts;
}

Expand Down Expand Up @@ -665,12 +667,6 @@ namespace ts {
const iife = createImmediatelyInvokedArrowFunction(statements);
setEmitFlags(iife, EmitFlags.TypeScriptClassWrapper);

// Class comment is already added by the ES2015 transform when targeting ES5 or below.
// Only add if targetting ES2015+ to prevent duplicates
if (languageVersion > ScriptTarget.ES5) {
addSyntheticLeadingComment(iife, SyntaxKind.MultiLineCommentTrivia, "* @class ");
}

const varStatement = createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList([
Expand All @@ -679,7 +675,7 @@ namespace ts {
/*type*/ undefined,
iife
)
], languageVersion > ScriptTarget.ES5 ? NodeFlags.Let : undefined)
])
);

setOriginalNode(varStatement, node);
Expand Down
6 changes: 6 additions & 0 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,8 @@ namespace ts {
export type PlusToken = Token<SyntaxKind.PlusToken>;
export type MinusToken = Token<SyntaxKind.MinusToken>;
export type AssertsToken = Token<SyntaxKind.AssertsKeyword>;
export type OpenParenToken = Token<SyntaxKind.OpenParenToken>;
export type CloseParenToken = Token<SyntaxKind.CloseParenToken>;

export type Modifier
= Token<SyntaxKind.AbstractKeyword>
Expand Down Expand Up @@ -1929,7 +1931,9 @@ namespace ts {
expression: LeftHandSideExpression;
questionDotToken?: QuestionDotToken;
typeArguments?: NodeArray<TypeNode>;
openParenToken: OpenParenToken;
arguments: NodeArray<Expression>;
closeParenToken: CloseParenToken;
}

export interface CallChain extends CallExpression {
Expand Down Expand Up @@ -2008,7 +2012,9 @@ namespace ts {
kind: SyntaxKind.NewExpression;
expression: LeftHandSideExpression;
typeArguments?: NodeArray<TypeNode>;
openParenToken?: OpenParenToken;
arguments?: NodeArray<Expression>;
closeParenToken?: CloseParenToken;
}

export interface TaggedTemplateExpression extends MemberExpression {
Expand Down
3 changes: 2 additions & 1 deletion src/harness/harnessUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ namespace Utils {
for (const childName in node) {
if (childName === "parent" || childName === "nextContainer" || childName === "modifiers" || childName === "externalModuleIndicator" ||
// for now ignore jsdoc comments
childName === "jsDocComment" || childName === "checkJsDirective" || childName === "commonJsModuleIndicator") {
childName === "jsDocComment" || childName === "checkJsDirective" || childName === "commonJsModuleIndicator" ||
childName === "openParenToken" || childName === "closeParenToken") {
continue;
}
const child = (<any>node)[childName];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,18 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";A_labeled_tuple_element_is_declared_as_optional_with_a_question_mark_after_the_name_and_before_the_c_5086" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[A labeled tuple element is declared as optional with a question mark after the name and before the colon, rather than after the type.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";A_labeled_tuple_element_is_declared_as_rest_with_a_before_the_name_rather_than_before_the_type_5087" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[A labeled tuple element is declared as rest with a `...` before the name, rather than before the type.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_memb_2651" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums.]]></Val>
Expand Down Expand Up @@ -867,6 +879,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";A_tuple_member_cannot_be_both_optional_and_rest_5085" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[A tuple member cannot be both optional and rest.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Con_17007" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[A type assertion expression is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses.]]></Val>
Expand Down Expand Up @@ -3522,6 +3540,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_overload_list_to_single_signature_95118" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert overload list to single signature]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_parameters_to_destructured_object_95075" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert parameters to destructured object]]></Val>
Expand Down Expand Up @@ -3655,7 +3679,7 @@
<Str Cat="Text">
<Val><![CDATA[Declaration augments declaration in another file. This cannot be serialized.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[La dichiarazione causa un aumento della dichiarazione in un altro file. Questa condizione non è serializzabile.]]></Val>
<Val><![CDATA[La dichiarazione causa un aumento di una dichiarazione in un altro file. Questa operazione non è serializzabile.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
Expand Down Expand Up @@ -6807,6 +6831,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Move_labeled_tuple_element_modifiers_to_labels_95117" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Move labeled tuple element modifiers to labels]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Move_to_a_new_file_95049" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Move to a new file]]></Val>
Expand Down Expand Up @@ -10599,6 +10629,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";This_expression_is_not_callable_because_it_is_a_get_accessor_Did_you_mean_to_use_it_without_6234" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[This expression is not callable because it is a 'get' accessor. Did you mean to use it without '()'?]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";This_expression_is_not_constructable_2351" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[This expression is not constructable.]]></Val>
Expand Down Expand Up @@ -10764,6 +10800,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Tuple_members_must_all_have_names_or_all_not_have_names_5084" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Tuple members must all have names or all not have names.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Tuple_type_0_of_length_1_has_no_element_at_index_2_2493" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Tuple type '{0}' of length '{1}' has no element at index '{2}'.]]></Val>
Expand Down Expand Up @@ -12685,7 +12727,7 @@
<Str Cat="Text">
<Val><![CDATA['export *' does not re-export a default.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA['export *' non consente di riesportare un'impostazione predefinita.]]></Val>
<Val><![CDATA['export *' non consente di riesportare esportazioni predefinite.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
Expand Down
21 changes: 21 additions & 0 deletions src/services/codefixes/removeAccidentalCallParentheses.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/* @internal */
namespace ts.codefix {
const fixId = "removeAccidentalCallParentheses";
const errorCodes = [
Diagnostics.This_expression_is_not_callable_because_it_is_a_get_accessor_Did_you_mean_to_use_it_without.code,
];
registerCodeFix({
errorCodes,
getCodeActions(context) {
const callExpression = findAncestor(getTokenAtPosition(context.sourceFile, context.span.start), isCallExpression);
if (!callExpression) {
return undefined;
}
const changes = textChanges.ChangeTracker.with(context, t => {
t.deleteNodeRange(context.sourceFile, callExpression.openParenToken, callExpression.closeParenToken);
});
return [createCodeFixActionWithoutFixAll(fixId, changes, Diagnostics.Remove_parentheses)];
},
fixIds: [fixId],
});
}
14 changes: 11 additions & 3 deletions src/services/outliningElementsCollector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,9 +276,7 @@ namespace ts.OutliningElementsCollector {
}

function functionSpan(node: FunctionLike, body: Block, sourceFile: SourceFile): OutliningSpan | undefined {
const openToken = isNodeArrayMultiLine(node.parameters, sourceFile)
? findChildOfKind(node, SyntaxKind.OpenParenToken, sourceFile)
: findChildOfKind(body, SyntaxKind.OpenBraceToken, sourceFile);
const openToken = tryGetFunctionOpenToken(node, body, sourceFile);
const closeToken = findChildOfKind(body, SyntaxKind.CloseBraceToken, sourceFile);
return openToken && closeToken && spanBetweenTokens(openToken, closeToken, node, sourceFile, /*autoCollapse*/ node.kind !== SyntaxKind.ArrowFunction);
}
Expand All @@ -291,4 +289,14 @@ namespace ts.OutliningElementsCollector {
function createOutliningSpan(textSpan: TextSpan, kind: OutliningSpanKind, hintSpan: TextSpan = textSpan, autoCollapse = false, bannerText = "..."): OutliningSpan {
return { textSpan, kind, hintSpan, bannerText, autoCollapse };
}

function tryGetFunctionOpenToken(node: FunctionLike, body: Block, sourceFile: SourceFile): Node | undefined {
if (isNodeArrayMultiLine(node.parameters, sourceFile)) {
const openParenToken = findChildOfKind(node, SyntaxKind.OpenParenToken, sourceFile);
if (openParenToken) {
return openParenToken;
}
}
return findChildOfKind(body, SyntaxKind.OpenBraceToken, sourceFile);
}
}
4 changes: 1 addition & 3 deletions src/services/stringCompletions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,9 +223,7 @@ namespace ts.Completions.StringCompletions {
function stringLiteralCompletionsFromProperties(type: Type | undefined): StringLiteralCompletionsFromProperties | undefined {
return type && {
kind: StringLiteralCompletionKind.Properties,
symbols: type.getApparentProperties().filter(prop =>
!isPrivateIdentifierPropertyDeclaration(
isTransientSymbol(prop) && prop.syntheticOrigin ? prop.syntheticOrigin.valueDeclaration : prop.valueDeclaration)),
symbols: filter(type.getApparentProperties(), prop => !(prop.valueDeclaration && isPrivateIdentifierPropertyDeclaration(prop.valueDeclaration))),
hasIndexSignature: hasIndexSignature(type)
};
}
Expand Down
1 change: 1 addition & 0 deletions src/services/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
"codefixes/useBigintLiteral.ts",
"codefixes/fixAddModuleReferTypeMissingTypeof.ts",
"codefixes/convertToMappedObjectType.ts",
"codefixes/removeAccidentalCallParentheses.ts",
"codefixes/removeUnnecessaryAwait.ts",
"codefixes/splitTypeOnlyImport.ts",
"codefixes/convertConstToLet.ts",
Expand Down
3 changes: 2 additions & 1 deletion src/testRunner/unittests/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@ namespace ts {
before: [createTaggedTemplateLiteral],
},
compilerOptions: {
target: ScriptTarget.ES5
target: ScriptTarget.ES5,
newLine: NewLineKind.CarriageReturnLineFeed
}
}).outputText;
});
Expand Down
Loading