Skip to content
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

Additional Types cleanup #5719

Merged
merged 4 commits into from
Nov 19, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 5 additions & 5 deletions src/compiler/binder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ namespace ts {
}
if (node.name.kind === SyntaxKind.ComputedPropertyName) {
const nameExpression = (<ComputedPropertyName>node.name).expression;
// treat computed property names where expression is string/numeric literal as just string/numeric literal
// treat computed property names where expression is string/numeric literal as just string/numeric literal
if (isStringOrNumericLiteral(nameExpression.kind)) {
return (<LiteralExpression>nameExpression).text;
}
Expand Down Expand Up @@ -450,7 +450,7 @@ namespace ts {

/**
* Returns true if node and its subnodes were successfully traversed.
* Returning false means that node was not examined and caller needs to dive into the node himself.
* Returning false means that node was not examined and caller needs to dive into the node himself.
*/
function bindReachableStatement(node: Node): void {
if (checkUnreachable(node)) {
Expand Down Expand Up @@ -560,7 +560,7 @@ namespace ts {
}

function bindIfStatement(n: IfStatement): void {
// denotes reachability state when entering 'thenStatement' part of the if statement:
// denotes reachability state when entering 'thenStatement' part of the if statement:
// i.e. if condition is false then thenStatement is unreachable
const ifTrueState = n.expression.kind === SyntaxKind.FalseKeyword ? Reachability.Unreachable : currentReachabilityState;
// denotes reachability state when entering 'elseStatement':
Expand Down Expand Up @@ -1179,7 +1179,7 @@ namespace ts {
return checkStrictModePrefixUnaryExpression(<PrefixUnaryExpression>node);
case SyntaxKind.WithStatement:
return checkStrictModeWithStatement(<WithStatement>node);
case SyntaxKind.ThisKeyword:
case SyntaxKind.ThisType:
seenThisKeyword = true;
return;

Expand Down Expand Up @@ -1528,7 +1528,7 @@ namespace ts {

// unreachable code is reported if
// - user has explicitly asked about it AND
// - statement is in not ambient context (statements in ambient context is already an error
// - statement is in not ambient context (statements in ambient context is already an error
// so we should not report extras) AND
// - node is not variable statement OR
// - node is block scoped variable statement OR
Expand Down
7 changes: 5 additions & 2 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4541,7 +4541,7 @@ namespace ts {
return esSymbolType;
case SyntaxKind.VoidKeyword:
return voidType;
case SyntaxKind.ThisKeyword:
case SyntaxKind.ThisType:
return getTypeFromThisTypeNode(node);
case SyntaxKind.StringLiteral:
return getTypeFromStringLiteral(<StringLiteral>node);
Expand Down Expand Up @@ -10157,7 +10157,7 @@ namespace ts {
checkDestructuringAssignment(<ShorthandPropertyAssignment>p, type);
}
else {
// non-shorthand property assignments should always have initializers
// non-shorthand property assignments should always have initializers
checkDestructuringAssignment((<PropertyAssignment>p).initializer, type);
}
}
Expand Down Expand Up @@ -14620,6 +14620,9 @@ namespace ts {
const type = isExpression(node) ? checkExpression(<Expression>node) : getTypeFromTypeNode(<TypeNode>node);
return type.symbol;

case SyntaxKind.ThisType:
return getTypeFromTypeNode(<TypeNode>node).symbol;

case SyntaxKind.ConstructorKeyword:
// constructor keyword for an overload, should take us to the definition if it exist
const constructorDeclaration = node.parent;
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/declarationEmitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ namespace ts {
case SyntaxKind.BooleanKeyword:
case SyntaxKind.SymbolKeyword:
case SyntaxKind.VoidKeyword:
case SyntaxKind.ThisKeyword:
case SyntaxKind.ThisType:
case SyntaxKind.StringLiteral:
return writeTextOfNode(currentText, type);
case SyntaxKind.ExpressionWithTypeArguments:
Expand Down
11 changes: 6 additions & 5 deletions src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -428,18 +428,18 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
* var loop = function(x) { <code where 'arguments' is replaced witg 'arguments_1'> }
* var arguments_1 = arguments
* for (var x;;) loop(x);
* otherwise semantics of the code will be different since 'arguments' inside converted loop body
* otherwise semantics of the code will be different since 'arguments' inside converted loop body
* will refer to function that holds converted loop.
* This value is set on demand.
*/
argumentsName?: string;

/*
* list of non-block scoped variable declarations that appear inside converted loop
* such variable declarations should be moved outside the loop body
* such variable declarations should be moved outside the loop body
* for (let x;;) {
* var y = 1;
* ...
* ...
* }
* should be converted to
* var loop = function(x) {
Expand Down Expand Up @@ -3226,7 +3226,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
}

if (convertedLoopState && (getCombinedNodeFlags(decl) & NodeFlags.BlockScoped) === 0) {
// we are inside a converted loop - this can only happen in downlevel scenarios
// we are inside a converted loop - this can only happen in downlevel scenarios
// record names for all variable declarations
for (const varDecl of decl.declarations) {
hoistVariableDeclarationFromLoop(convertedLoopState, varDecl);
Expand Down Expand Up @@ -3551,7 +3551,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
write(`case "${labelMarker}": `);
// if there are no outer converted loop or outer label in question is located inside outer converted loop
// then emit labeled break\continue
// otherwise propagate pair 'label -> marker' to outer converted loop and emit 'return labelMarker' so outer loop can later decide what to do
// otherwise propagate pair 'label -> marker' to outer converted loop and emit 'return labelMarker' so outer loop can later decide what to do
if (!outerLoop || (outerLoop.labels && outerLoop.labels[labelText])) {
if (isBreak) {
write("break ");
Expand Down Expand Up @@ -6006,6 +6006,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
case SyntaxKind.UnionType:
case SyntaxKind.IntersectionType:
case SyntaxKind.AnyKeyword:
case SyntaxKind.ThisType:
break;

default:
Expand Down
9 changes: 8 additions & 1 deletion src/compiler/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1956,6 +1956,12 @@ namespace ts {
return finishNode(node);
}

function parseThisTypeNode(): TypeNode {
const node = <TypeNode>createNode(SyntaxKind.ThisType);
nextToken();
return finishNode(node);
}

function parseTypeQuery(): TypeQueryNode {
const node = <TypeQueryNode>createNode(SyntaxKind.TypeQuery);
parseExpected(SyntaxKind.TypeOfKeyword);
Expand Down Expand Up @@ -2388,8 +2394,9 @@ namespace ts {
case SyntaxKind.StringLiteral:
return <StringLiteral>parseLiteralNode(/*internName*/ true);
case SyntaxKind.VoidKeyword:
case SyntaxKind.ThisKeyword:
return parseTokenNode<TypeNode>();
case SyntaxKind.ThisKeyword:
return parseThisTypeNode();
case SyntaxKind.TypeOfKeyword:
return parseTypeQuery();
case SyntaxKind.OpenBraceToken:
Expand Down
6 changes: 3 additions & 3 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ namespace ts {
UnionType,
IntersectionType,
ParenthesizedType,
ThisType,
// Binding patterns
ObjectBindingPattern,
ArrayBindingPattern,
Expand Down Expand Up @@ -349,7 +350,7 @@ namespace ts {
FirstFutureReservedWord = ImplementsKeyword,
LastFutureReservedWord = YieldKeyword,
FirstTypeNode = TypePredicate,
LastTypeNode = ParenthesizedType,
LastTypeNode = ThisType,
FirstPunctuation = OpenBraceToken,
LastPunctuation = CaretEqualsToken,
FirstToken = Unknown,
Expand Down Expand Up @@ -726,6 +727,7 @@ namespace ts {
// @kind(SyntaxKind.StringKeyword)
// @kind(SyntaxKind.SymbolKeyword)
// @kind(SyntaxKind.VoidKeyword)
// @kind(SyntaxKind.ThisType)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about string literal types?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there would need to be a StringLiteralType kind and a StringLiteral kind, just like how there's ThisType and ThisKeyword. So maybe a followup PR?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DanielRosenwasser, @weswigham: I primarily need this to disambiguate this during tree transformations. I have no such need for disambiguation for string literal types. I may have a follow-up PR for this at some point to achieve consistency, but its not as high of a priority.

export interface TypeNode extends Node {
_typeNodeBrand: any;
}
Expand Down Expand Up @@ -1075,7 +1077,6 @@ namespace ts {
export interface DebuggerStatement extends Statement { }

// @kind(SyntaxKind.MissingDeclaration)
// @factoryhidden("name", true)
export interface MissingDeclaration extends DeclarationStatement, ClassElement, ObjectLiteralElement, TypeElement {
name?: Identifier;
}
Expand Down Expand Up @@ -1232,7 +1233,6 @@ namespace ts {
export interface TypeElement extends Declaration {
_typeElementBrand: any;
name?: PropertyName;
// @factoryparam
questionToken?: Node;
}

Expand Down
20 changes: 12 additions & 8 deletions src/services/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2314,7 +2314,7 @@ namespace ts {

return true;
}

return false;
}

Expand All @@ -2333,7 +2333,7 @@ namespace ts {
}
return false;
}

function tryConsumeDefine(): boolean {
let token = scanner.getToken();
if (token === SyntaxKind.Identifier && scanner.getTokenValue() === "define") {
Expand All @@ -2359,7 +2359,7 @@ namespace ts {
if (token !== SyntaxKind.OpenBracketToken) {
return true;
}

// skip open bracket
token = scanner.scan();
let i = 0;
Expand All @@ -2374,7 +2374,7 @@ namespace ts {
token = scanner.scan();
}
return true;

}
return false;
}
Expand Down Expand Up @@ -3976,7 +3976,7 @@ namespace ts {
let sourceFile = getValidSourceFile(fileName);

let entries: CompletionEntry[] = [];

if (isRightOfDot && isSourceFileJavaScript(sourceFile)) {
const uniqueNames = getCompletionEntriesFromSymbols(symbols, entries);
addRange(entries, getJavaScriptCompletionEntries(sourceFile, uniqueNames));
Expand Down Expand Up @@ -4595,6 +4595,7 @@ namespace ts {
case SyntaxKind.PropertyAccessExpression:
case SyntaxKind.QualifiedName:
case SyntaxKind.ThisKeyword:
case SyntaxKind.ThisType:
case SyntaxKind.SuperKeyword:
// For the identifiers/this/super etc get the type at position
let type = typeChecker.getTypeAtLocation(node);
Expand Down Expand Up @@ -4866,6 +4867,7 @@ namespace ts {
function getSemanticDocumentHighlights(node: Node): DocumentHighlights[] {
if (node.kind === SyntaxKind.Identifier ||
node.kind === SyntaxKind.ThisKeyword ||
node.kind === SyntaxKind.ThisType ||
node.kind === SyntaxKind.SuperKeyword ||
isLiteralNameOfPropertyDeclarationOrIndexAccess(node) ||
isNameOfExternalModuleImportOrDeclaration(node)) {
Expand Down Expand Up @@ -5561,7 +5563,7 @@ namespace ts {
}
}

if (node.kind === SyntaxKind.ThisKeyword) {
if (node.kind === SyntaxKind.ThisKeyword || node.kind === SyntaxKind.ThisType) {
return getReferencesForThisKeyword(node, sourceFiles);
}

Expand Down Expand Up @@ -6043,7 +6045,7 @@ namespace ts {
cancellationToken.throwIfCancellationRequested();

let node = getTouchingWord(sourceFile, position);
if (!node || node.kind !== SyntaxKind.ThisKeyword) {
if (!node || (node.kind !== SyntaxKind.ThisKeyword && node.kind !== SyntaxKind.ThisType)) {
return;
}

Expand Down Expand Up @@ -6405,7 +6407,8 @@ namespace ts {

return node.parent.kind === SyntaxKind.TypeReference ||
(node.parent.kind === SyntaxKind.ExpressionWithTypeArguments && !isExpressionWithTypeArgumentsInClassExtendsClause(<ExpressionWithTypeArguments>node.parent)) ||
node.kind === SyntaxKind.ThisKeyword && !isExpression(node);
(node.kind === SyntaxKind.ThisKeyword && !isExpression(node)) ||
node.kind === SyntaxKind.ThisType;
}

function isNamespaceReference(node: Node): boolean {
Expand Down Expand Up @@ -6525,6 +6528,7 @@ namespace ts {
case SyntaxKind.NullKeyword:
case SyntaxKind.SuperKeyword:
case SyntaxKind.ThisKeyword:
case SyntaxKind.ThisType:
case SyntaxKind.Identifier:
break;

Expand Down
12 changes: 12 additions & 0 deletions tests/baselines/reference/decoratorMetadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ declare var decorator: any;
class MyComponent {
constructor(public Service: Service) {
}

@decorator
method(x: this) {
}
}

//// [service.js]
Expand All @@ -37,6 +41,14 @@ var MyComponent = (function () {
function MyComponent(Service) {
this.Service = Service;
}
MyComponent.prototype.method = function (x) {
};
__decorate([
decorator,
__metadata('design:type', Function),
__metadata('design:paramtypes', [Object]),
__metadata('design:returntype', void 0)
], MyComponent.prototype, "method", null);
MyComponent = __decorate([
decorator,
__metadata('design:paramtypes', [service_1.default])
Expand Down
8 changes: 8 additions & 0 deletions tests/baselines/reference/decoratorMetadata.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,12 @@ class MyComponent {
>Service : Symbol(Service, Decl(component.ts, 6, 16))
>Service : Symbol(Service, Decl(component.ts, 0, 6))
}

@decorator
>decorator : Symbol(decorator, Decl(component.ts, 2, 11))

method(x: this) {
>method : Symbol(method, Decl(component.ts, 7, 5))
>x : Symbol(x, Decl(component.ts, 10, 11))
}
}
8 changes: 8 additions & 0 deletions tests/baselines/reference/decoratorMetadata.types
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,12 @@ class MyComponent {
>Service : Service
>Service : Service
}

@decorator
>decorator : any

method(x: this) {
>method : (x: this) => void
>x : this
}
}
1 change: 0 additions & 1 deletion tests/baselines/reference/thisTypeInClasses.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ class C5 {
let f1 = (x: this): this => this;
>f1 : Symbol(f1, Decl(thisTypeInClasses.ts, 34, 11))
>x : Symbol(x, Decl(thisTypeInClasses.ts, 34, 18))
>this : Symbol(C5, Decl(thisTypeInClasses.ts, 30, 1))
>this : Symbol(C5, Decl(thisTypeInClasses.ts, 30, 1))

let f2 = (x: this) => this;
Expand Down
1 change: 0 additions & 1 deletion tests/baselines/reference/thisTypeInClasses.types
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ class C5 {
>f1 : (x: this) => this
>(x: this): this => this : (x: this) => this
>x : this
>this : this
>this : this

let f2 = (x: this) => this;
Expand Down
4 changes: 4 additions & 0 deletions tests/cases/conformance/decorators/decoratorMetadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,8 @@ declare var decorator: any;
class MyComponent {
constructor(public Service: Service) {
}

@decorator
method(x: this) {
}
}