Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
* upstream/master:
  Support naming tuple members (microsoft#38234)
  LEGO: check in for master to temporary branch.
  fix: extract const in jsx (microsoft#37912)
  No contextual types from circular mapped type properties (microsoft#38653)
  Ensure formatter can always get a newline character (microsoft#38579)
  Fix debug command for Node debugging
  Remove mentions of runtests-browser in CONTRIBUTING.md
  fix(33233): add outlining for comments before property access expression
  regression(38485): allow using rawText property in processing a tagged template
  • Loading branch information
cangSDARM committed May 20, 2020
2 parents 2f9f51b + 5f597e6 commit 60ee5e8
Show file tree
Hide file tree
Showing 90 changed files with 2,756 additions and 741 deletions.
419 changes: 203 additions & 216 deletions CONTRIBUTING.md

Large diffs are not rendered by default.

260 changes: 195 additions & 65 deletions src/compiler/checker.ts

Large diffs are not rendered by default.

24 changes: 24 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -3517,6 +3517,22 @@
"category": "Error",
"code": 5083
},
"Tuple members must all have names or all not have names.": {
"category": "Error",
"code": 5084
},
"A tuple member cannot be both optional and rest.": {
"category": "Error",
"code": 5085
},
"A labeled tuple element is declared as optional with a question mark after the name and before the colon, rather than after the type.": {
"category": "Error",
"code": 5086
},
"A labeled tuple element is declared as rest with a `...` before the name, rather than before the type.": {
"category": "Error",
"code": 5087
},

"Generates a sourcemap for each corresponding '.d.ts' file.": {
"category": "Message",
Expand Down Expand Up @@ -5677,6 +5693,14 @@
"category": "Message",
"code": 95116
},
"Move labeled tuple element modifiers to labels": {
"category": "Message",
"code": 95117
},
"Convert overload list to single signature": {
"category": "Message",
"code": 95118
},

"No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer.": {
"category": "Error",
Expand Down
20 changes: 16 additions & 4 deletions src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1370,6 +1370,8 @@ namespace ts {
case SyntaxKind.RestType:
case SyntaxKind.JSDocVariadicType:
return emitRestOrJSDocVariadicType(node as RestTypeNode | JSDocVariadicType);
case SyntaxKind.NamedTupleMember:
return emitNamedTupleMember(node as NamedTupleMember);

// Binding patterns
case SyntaxKind.ObjectBindingPattern:
Expand Down Expand Up @@ -2099,9 +2101,19 @@ namespace ts {
}

function emitTupleType(node: TupleTypeNode) {
writePunctuation("[");
emitList(node, node.elementTypes, ListFormat.TupleTypeElements);
writePunctuation("]");
emitTokenWithComment(SyntaxKind.OpenBracketToken, node.pos, writePunctuation, node);
const flags = getEmitFlags(node) & EmitFlags.SingleLine ? ListFormat.SingleLineTupleTypeElements : ListFormat.MultiLineTupleTypeElements;
emitList(node, node.elements, flags | ListFormat.NoSpaceIfEmpty);
emitTokenWithComment(SyntaxKind.CloseBracketToken, node.elements.end, writePunctuation, node);
}

function emitNamedTupleMember(node: NamedTupleMember) {
emit(node.dotDotDotToken);
emit(node.name);
emit(node.questionToken);
emitTokenWithComment(SyntaxKind.ColonToken, node.name.end, writePunctuation, node);
writeSpace();
emit(node.type);
}

function emitOptionalType(node: OptionalTypeNode) {
Expand Down Expand Up @@ -4968,7 +4980,7 @@ namespace ts {
}

function emitLeadingSynthesizedComment(comment: SynthesizedComment) {
if (comment.kind === SyntaxKind.SingleLineCommentTrivia) {
if (comment.hasLeadingNewline || comment.kind === SyntaxKind.SingleLineCommentTrivia) {
writer.writeLine();
}
writeSynthesizedComment(comment);
Expand Down
43 changes: 38 additions & 5 deletions src/compiler/factoryPublic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -810,15 +810,15 @@ namespace ts {
: node;
}

export function createTupleTypeNode(elementTypes: readonly TypeNode[]) {
export function createTupleTypeNode(elements: readonly (TypeNode | NamedTupleMember)[]) {
const node = createSynthesizedNode(SyntaxKind.TupleType) as TupleTypeNode;
node.elementTypes = createNodeArray(elementTypes);
node.elements = createNodeArray(elements);
return node;
}

export function updateTupleTypeNode(node: TupleTypeNode, elementTypes: readonly TypeNode[]) {
return node.elementTypes !== elementTypes
? updateNode(createTupleTypeNode(elementTypes), node)
export function updateTupleTypeNode(node: TupleTypeNode, elements: readonly (TypeNode | NamedTupleMember)[]) {
return node.elements !== elements
? updateNode(createTupleTypeNode(elements), node)
: node;
}

Expand Down Expand Up @@ -934,6 +934,24 @@ namespace ts {
: node;
}

export function createNamedTupleMember(dotDotDotToken: Token<SyntaxKind.DotDotDotToken> | undefined, name: Identifier, questionToken: Token<SyntaxKind.QuestionToken> | undefined, type: TypeNode) {
const node = <NamedTupleMember>createSynthesizedNode(SyntaxKind.NamedTupleMember);
node.dotDotDotToken = dotDotDotToken;
node.name = name;
node.questionToken = questionToken;
node.type = type;
return node;
}

export function updateNamedTupleMember(node: NamedTupleMember, dotDotDotToken: Token<SyntaxKind.DotDotDotToken> | undefined, name: Identifier, questionToken: Token<SyntaxKind.QuestionToken> | undefined, type: TypeNode) {
return node.dotDotDotToken !== dotDotDotToken
|| node.name !== name
|| node.questionToken !== questionToken
|| node.type !== type
? updateNode(createNamedTupleMember(dotDotDotToken, name, questionToken, type), node)
: node;
}

export function createThisTypeNode() {
return <ThisTypeNode>createSynthesizedNode(SyntaxKind.ThisType);
}
Expand Down Expand Up @@ -2616,6 +2634,21 @@ namespace ts {
return node;
}


/* @internal */
export function createJSDocVariadicType(type: TypeNode): JSDocVariadicType {
const node = createSynthesizedNode(SyntaxKind.JSDocVariadicType) as JSDocVariadicType;
node.type = type;
return node;
}

/* @internal */
export function updateJSDocVariadicType(node: JSDocVariadicType, type: TypeNode): JSDocVariadicType {
return node.type !== type
? updateNode(createJSDocVariadicType(type), node)
: node;
}

// JSX

export function createJsxElement(openingElement: JsxOpeningElement, children: readonly JsxChild[], closingElement: JsxClosingElement) {
Expand Down
33 changes: 31 additions & 2 deletions src/compiler/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ namespace ts {
case SyntaxKind.ArrayType:
return visitNode(cbNode, (<ArrayTypeNode>node).elementType);
case SyntaxKind.TupleType:
return visitNodes(cbNode, cbNodes, (<TupleTypeNode>node).elementTypes);
return visitNodes(cbNode, cbNodes, (<TupleTypeNode>node).elements);
case SyntaxKind.UnionType:
case SyntaxKind.IntersectionType:
return visitNodes(cbNode, cbNodes, (<UnionOrIntersectionTypeNode>node).types);
Expand Down Expand Up @@ -207,6 +207,11 @@ namespace ts {
visitNode(cbNode, (<MappedTypeNode>node).type);
case SyntaxKind.LiteralType:
return visitNode(cbNode, (<LiteralTypeNode>node).literal);
case SyntaxKind.NamedTupleMember:
return visitNode(cbNode, (<NamedTupleMember>node).dotDotDotToken) ||
visitNode(cbNode, (<NamedTupleMember>node).name) ||
visitNode(cbNode, (<NamedTupleMember>node).questionToken) ||
visitNode(cbNode, (<NamedTupleMember>node).type);
case SyntaxKind.ObjectBindingPattern:
case SyntaxKind.ArrayBindingPattern:
return visitNodes(cbNode, cbNodes, (<BindingPattern>node).elements);
Expand Down Expand Up @@ -3066,9 +3071,33 @@ namespace ts {
return type;
}

function isNextTokenColonOrQuestionColon() {
return nextToken() === SyntaxKind.ColonToken || (token() === SyntaxKind.QuestionToken && nextToken() === SyntaxKind.ColonToken);
}

function isTupleElementName() {
if (token() === SyntaxKind.DotDotDotToken) {
return tokenIsIdentifierOrKeyword(nextToken()) && isNextTokenColonOrQuestionColon();
}
return tokenIsIdentifierOrKeyword(token()) && isNextTokenColonOrQuestionColon();
}

function parseTupleElementNameOrTupleElementType() {
if (lookAhead(isTupleElementName)) {
const node = <NamedTupleMember>createNode(SyntaxKind.NamedTupleMember);
node.dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken);
node.name = parseIdentifierName();
node.questionToken = parseOptionalToken(SyntaxKind.QuestionToken);
parseExpected(SyntaxKind.ColonToken);
node.type = parseTupleElementType();
return addJSDocComment(finishNode(node));
}
return parseTupleElementType();
}

function parseTupleType(): TupleTypeNode {
const node = <TupleTypeNode>createNode(SyntaxKind.TupleType);
node.elementTypes = parseBracketedList(ParsingContext.TupleElementTypes, parseTupleElementType, SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken);
node.elements = parseBracketedList(ParsingContext.TupleElementTypes, parseTupleElementNameOrTupleElementType, SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken);
return finishNode(node);
}

Expand Down
4 changes: 4 additions & 0 deletions src/compiler/transformers/declarations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1018,6 +1018,10 @@ namespace ts {
}
}

if (isTupleTypeNode(input) && (getLineAndCharacterOfPosition(currentSourceFile, input.pos).line === getLineAndCharacterOfPosition(currentSourceFile, input.end).line)) {
setEmitFlags(input, EmitFlags.SingleLine);
}

return cleanup(visitEachChild(input, visitDeclarationSubtree, context));

function cleanup<T extends Node>(returnValue: T | undefined): T | undefined {
Expand Down
19 changes: 11 additions & 8 deletions src/compiler/transformers/taggedTemplate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,18 +73,21 @@ namespace ts {
*
* @param node The ES6 template literal.
*/
function getRawLiteral(node: LiteralLikeNode, currentSourceFile: SourceFile) {
function getRawLiteral(node: TemplateLiteralLikeNode, currentSourceFile: SourceFile) {
// Find original source text, since we need to emit the raw strings of the tagged template.
// The raw strings contain the (escaped) strings of what the user wrote.
// Examples: `\n` is converted to "\\n", a template string with a newline to "\n".
let text = getSourceTextOfNodeFromSourceFile(currentSourceFile, node);
let text = node.rawText;
if (text === undefined) {
text = getSourceTextOfNodeFromSourceFile(currentSourceFile, node);

// text contains the original source, it will also contain quotes ("`"), dolar signs and braces ("${" and "}"),
// thus we need to remove those characters.
// First template piece starts with "`", others with "}"
// Last template piece ends with "`", others with "${"
const isLast = node.kind === SyntaxKind.NoSubstitutionTemplateLiteral || node.kind === SyntaxKind.TemplateTail;
text = text.substring(1, text.length - (isLast ? 1 : 2));
// text contains the original source, it will also contain quotes ("`"), dolar signs and braces ("${" and "}"),
// thus we need to remove those characters.
// First template piece starts with "`", others with "}"
// Last template piece ends with "`", others with "${"
const isLast = node.kind === SyntaxKind.NoSubstitutionTemplateLiteral || node.kind === SyntaxKind.TemplateTail;
text = text.substring(1, text.length - (isLast ? 1 : 2));
}

// Newline normalization:
// ES6 Spec 11.8.6.1 - Static Semantics of TV's and TRV's
Expand Down
22 changes: 18 additions & 4 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ namespace ts {
IndexedAccessType,
MappedType,
LiteralType,
NamedTupleMember,
ImportType,
// Binding patterns
ObjectBindingPattern,
Expand Down Expand Up @@ -708,6 +709,7 @@ namespace ts {
| ConstructorTypeNode
| JSDocFunctionType
| ExportDeclaration
| NamedTupleMember
| EndOfFileToken;

export type HasType =
Expand Down Expand Up @@ -1282,7 +1284,15 @@ namespace ts {

export interface TupleTypeNode extends TypeNode {
kind: SyntaxKind.TupleType;
elementTypes: NodeArray<TypeNode>;
elements: NodeArray<TypeNode | NamedTupleMember>;
}

export interface NamedTupleMember extends TypeNode, JSDocContainer, Declaration {
kind: SyntaxKind.NamedTupleMember;
dotDotDotToken?: Token<SyntaxKind.DotDotDotToken>;
name: Identifier;
questionToken?: Token<SyntaxKind.QuestionToken>;
type: TypeNode;
}

export interface OptionalTypeNode extends TypeNode {
Expand Down Expand Up @@ -1486,6 +1496,7 @@ namespace ts {
kind: SyntaxKind.SyntheticExpression;
isSpread: boolean;
type: Type;
tupleNameSource?: ParameterDeclaration | NamedTupleMember;
}

// see: https://tc39.github.io/ecma262/#prod-ExponentiationExpression
Expand Down Expand Up @@ -2598,6 +2609,7 @@ namespace ts {
text: string;
pos: -1;
end: -1;
hasLeadingNewline?: boolean;
}

// represents a top level: { type } expression in a JSDoc comment.
Expand Down Expand Up @@ -3506,7 +3518,7 @@ namespace ts {
*/
getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[], argumentCount?: number): Signature | undefined;
/* @internal */ getResolvedSignatureForSignatureHelp(node: CallLikeExpression, candidatesOutArray?: Signature[], argumentCount?: number): Signature | undefined;
/* @internal */ getExpandedParameters(sig: Signature): readonly Symbol[];
/* @internal */ getExpandedParameters(sig: Signature): readonly (readonly Symbol[])[];
/* @internal */ hasEffectiveRestParameter(sig: Signature): boolean;
getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature | undefined;
isImplementationOfOverload(node: SignatureDeclaration): boolean | undefined;
Expand Down Expand Up @@ -4161,6 +4173,7 @@ namespace ts {
cjsExportMerged?: Symbol; // Version of the symbol with all non export= exports merged with the export= target
typeOnlyDeclaration?: TypeOnlyCompatibleAliasDeclaration | false; // First resolved alias declaration that makes the symbol only usable in type constructs
isConstructorDeclaredProperty?: boolean; // Property declared through 'this.x = ...' assignment in constructor
tupleLabelDeclaration?: NamedTupleMember | ParameterDeclaration; // Declaration associated with the tuple's label
}

/* @internal */
Expand Down Expand Up @@ -4631,7 +4644,7 @@ namespace ts {
minLength: number;
hasRestElement: boolean;
readonly: boolean;
associatedNames?: __String[];
labeledElementDeclarations?: readonly (NamedTupleMember | ParameterDeclaration)[];
}

export interface TupleTypeReference extends TypeReference {
Expand Down Expand Up @@ -6580,7 +6593,8 @@ namespace ts {
SingleLineTypeLiteralMembers = SingleLine | SpaceBetweenBraces | SpaceBetweenSiblings,
MultiLineTypeLiteralMembers = MultiLine | Indented | OptionalIfEmpty,

TupleTypeElements = CommaDelimited | SpaceBetweenSiblings | SingleLine,
SingleLineTupleTypeElements = CommaDelimited | SpaceBetweenSiblings | SingleLine,
MultiLineTupleTypeElements = CommaDelimited | Indented | SpaceBetweenSiblings | MultiLine,
UnionTypeConstituents = BarDelimited | SpaceBetweenSiblings | SingleLine,
IntersectionTypeConstituents = AmpersandDelimited | SpaceBetweenSiblings | SingleLine,
ObjectBindingPatternElements = SingleLine | AllowTrailingComma | SpaceBetweenBraces | CommaDelimited | SpaceBetweenSiblings | NoSpaceIfEmpty,
Expand Down
10 changes: 9 additions & 1 deletion src/compiler/visitorPublic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ namespace ts {

case SyntaxKind.TupleType:
return updateTupleTypeNode((<TupleTypeNode>node),
nodesVisitor((<TupleTypeNode>node).elementTypes, visitor, isTypeNode));
nodesVisitor((<TupleTypeNode>node).elements, visitor, isTypeNode));

case SyntaxKind.OptionalType:
return updateOptionalTypeNode((<OptionalTypeNode>node),
Expand Down Expand Up @@ -517,6 +517,14 @@ namespace ts {
(<ImportTypeNode>node).isTypeOf
);

case SyntaxKind.NamedTupleMember:
return updateNamedTupleMember(<NamedTupleMember>node,
visitNode((<NamedTupleMember>node).dotDotDotToken, visitor, isToken),
visitNode((<NamedTupleMember>node).name, visitor, isIdentifier),
visitNode((<NamedTupleMember>node).questionToken, visitor, isToken),
visitNode((<NamedTupleMember>node).type, visitor, isTypeNode),
);

case SyntaxKind.ParenthesizedType:
return updateParenthesizedType(<ParenthesizedTypeNode>node,
visitNode((<ParenthesizedTypeNode>node).type, visitor, isTypeNode));
Expand Down
6 changes: 6 additions & 0 deletions src/harness/fourslashImpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,12 @@ namespace FourSlash {
}
}

public verifyOrganizeImports(newContent: string) {
const changes = this.languageService.organizeImports({ fileName: this.activeFile.fileName, type: "file" }, this.formatCodeSettings, ts.emptyOptions);
this.applyChanges(changes);
this.verifyFileContent(this.activeFile.fileName, newContent);
}

private raiseError(message: string): never {
throw new Error(this.messageAtLastKnownMarker(message));
}
Expand Down
4 changes: 4 additions & 0 deletions src/harness/fourslashInterfaceImpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,10 @@ namespace FourSlashInterface {
public noMoveToNewFile(): void {
this.state.noMoveToNewFile();
}

public organizeImports(newContent: string) {
this.state.verifyOrganizeImports(newContent);
}
}

export class Edit {
Expand Down

0 comments on commit 60ee5e8

Please sign in to comment.