Skip to content

Commit ea15225

Browse files
committed
Merge pull request #2399 from Microsoft/decorators_min
2 parents 4f0dc28 + f531193 commit ea15225

File tree

162 files changed

+6112
-1710
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

162 files changed

+6112
-1710
lines changed

src/compiler/checker.ts

+150-17
Large diffs are not rendered by default.

src/compiler/core.ts

+33
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,39 @@ module ts {
162162
return ~low;
163163
}
164164

165+
export function foldLeft<T>(array: T[], f: (a: T, x: T) => T): T;
166+
export function foldLeft<T, U>(array: T[], f: (a: U, x: T) => U, initial: U): U;
167+
export function foldLeft<T, U>(array: T[], f: (a: U, x: T) => U, initial?: U): U {
168+
if (array) {
169+
var count = array.length;
170+
if (count > 0) {
171+
var pos = 0;
172+
var result = arguments.length <= 2 ? array[pos++] : initial;
173+
while (pos < count) {
174+
result = f(<U>result, array[pos++]);
175+
}
176+
return <U>result;
177+
}
178+
}
179+
return initial;
180+
}
181+
182+
export function foldRight<T>(array: T[], f: (a: T, x: T) => T): T;
183+
export function foldRight<T, U>(array: T[], f: (a: U, x: T) => U, initial: U): U;
184+
export function foldRight<T, U>(array: T[], f: (a: U, x: T) => U, initial?: U): U {
185+
if (array) {
186+
var pos = array.length - 1;
187+
if (pos >= 0) {
188+
var result = arguments.length <= 2 ? array[pos--] : initial;
189+
while (pos >= 0) {
190+
result = f(<U>result, array[pos--]);
191+
}
192+
return <U>result;
193+
}
194+
}
195+
return initial;
196+
}
197+
165198
let hasOwnProperty = Object.prototype.hasOwnProperty;
166199

167200
export function hasProperty<T>(map: Map<T>, key: string): boolean {

src/compiler/diagnosticInformationMap.generated.ts

+3
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,9 @@ module ts {
162162
Import_assignment_cannot_be_used_when_targeting_ECMAScript_6_or_higher_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_or_import_d_from_mod_instead: { code: 1202, category: DiagnosticCategory.Error, key: "Import assignment cannot be used when targeting ECMAScript 6 or higher. Consider using 'import * as ns from \"mod\"', 'import {a} from \"mod\"' or 'import d from \"mod\"' instead." },
163163
Export_assignment_cannot_be_used_when_targeting_ECMAScript_6_or_higher_Consider_using_export_default_instead: { code: 1203, category: DiagnosticCategory.Error, key: "Export assignment cannot be used when targeting ECMAScript 6 or higher. Consider using 'export default' instead." },
164164
Cannot_compile_external_modules_into_amd_or_commonjs_when_targeting_es6_or_higher: { code: 1204, category: DiagnosticCategory.Error, key: "Cannot compile external modules into amd or commonjs when targeting es6 or higher." },
165+
Decorators_are_only_available_when_targeting_ECMAScript_5_and_higher: { code: 1205, category: DiagnosticCategory.Error, key: "Decorators are only available when targeting ECMAScript 5 and higher." },
166+
Decorators_are_not_valid_here: { code: 1206, category: DiagnosticCategory.Error, key: "Decorators are not valid here." },
167+
Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name: { code: 1207, category: DiagnosticCategory.Error, key: "Decorators cannot be applied to multiple get/set accessors of the same name." },
165168
Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." },
166169
Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." },
167170
Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." },

src/compiler/diagnosticMessages.json

+12
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,18 @@
639639
"category": "Error",
640640
"code": 1204
641641
},
642+
"Decorators are only available when targeting ECMAScript 5 and higher.": {
643+
"category": "Error",
644+
"code": 1205
645+
},
646+
"Decorators are not valid here.": {
647+
"category": "Error",
648+
"code": 1206
649+
},
650+
"Decorators cannot be applied to multiple get/set accessors of the same name.": {
651+
"category": "Error",
652+
"code": 1207
653+
},
642654

643655
"Duplicate identifier '{0}'.": {
644656
"category": "Error",

src/compiler/emitter.ts

+414-21
Large diffs are not rendered by default.

src/compiler/parser.ts

+241-86
Large diffs are not rendered by default.

src/compiler/scanner.ts

+3
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ module ts {
148148
"&=": SyntaxKind.AmpersandEqualsToken,
149149
"|=": SyntaxKind.BarEqualsToken,
150150
"^=": SyntaxKind.CaretEqualsToken,
151+
"@": SyntaxKind.AtToken,
151152
};
152153

153154
/*
@@ -1284,6 +1285,8 @@ module ts {
12841285
return pos++, token = SyntaxKind.CloseBraceToken;
12851286
case CharacterCodes.tilde:
12861287
return pos++, token = SyntaxKind.TildeToken;
1288+
case CharacterCodes.at:
1289+
return pos++, token = SyntaxKind.AtToken;
12871290
case CharacterCodes.backslash:
12881291
let cookedChar = peekUnicodeEscape();
12891292
if (cookedChar >= 0 && isIdentifierStart(cookedChar)) {

src/compiler/types.ts

+40-20
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ module ts {
6767
BarBarToken,
6868
QuestionToken,
6969
ColonToken,
70+
AtToken,
7071
// Assignments
7172
EqualsToken,
7273
PlusEqualsToken,
@@ -154,6 +155,7 @@ module ts {
154155
// Signature elements
155156
TypeParameter,
156157
Parameter,
158+
Decorator,
157159
// TypeMember
158160
PropertySignature,
159161
PropertyDeclaration,
@@ -244,6 +246,7 @@ module ts {
244246
ExportDeclaration,
245247
NamedExports,
246248
ExportSpecifier,
249+
MissingDeclaration,
247250

248251
// Module references
249252
ExternalModuleReference,
@@ -327,22 +330,25 @@ module ts {
327330
// If this node was parsed in the parameters of a generator.
328331
GeneratorParameter = 1 << 3,
329332

333+
// If this node was parsed as part of a decorator
334+
Decorator = 1 << 4,
335+
330336
// If the parser encountered an error when parsing the code that created this node. Note
331337
// the parser only sets this directly on the node it creates right after encountering the
332338
// error.
333-
ThisNodeHasError = 1 << 4,
339+
ThisNodeHasError = 1 << 5,
334340

335341
// Context flags set directly by the parser.
336-
ParserGeneratedFlags = StrictMode | DisallowIn | Yield | GeneratorParameter | ThisNodeHasError,
342+
ParserGeneratedFlags = StrictMode | DisallowIn | Yield | GeneratorParameter | Decorator | ThisNodeHasError,
337343

338344
// Context flags computed by aggregating child flags upwards.
339345

340346
// Used during incremental parsing to determine if this node or any of its children had an
341347
// error. Computed only once and then cached.
342-
ThisNodeOrAnySubNodesHasError = 1 << 5,
348+
ThisNodeOrAnySubNodesHasError = 1 << 6,
343349

344350
// Used to know if we've computed data from children and cached it in this node.
345-
HasAggregatedChildData = 1 << 6
351+
HasAggregatedChildData = 1 << 7
346352
}
347353

348354
export const enum RelationComparisonResult {
@@ -357,13 +363,14 @@ module ts {
357363
// Specific context the parser was in when this node was created. Normally undefined.
358364
// Only set when the parser was in some interesting context (like async/yield).
359365
parserContextFlags?: ParserContextFlags;
360-
modifiers?: ModifiersArray; // Array of modifiers
361-
id?: number; // Unique id (used to look up NodeLinks)
362-
parent?: Node; // Parent node (initialized by binding)
363-
symbol?: Symbol; // Symbol declared by node (initialized by binding)
364-
locals?: SymbolTable; // Locals associated with node (initialized by binding)
365-
nextContainer?: Node; // Next container in declaration order (initialized by binding)
366-
localSymbol?: Symbol; // Local symbol declared by node (initialized by binding only for exported nodes)
366+
decorators?: NodeArray<Decorator>; // Array of decorators (in document order)
367+
modifiers?: ModifiersArray; // Array of modifiers
368+
id?: number; // Unique id (used to look up NodeLinks)
369+
parent?: Node; // Parent node (initialized by binding)
370+
symbol?: Symbol; // Symbol declared by node (initialized by binding)
371+
locals?: SymbolTable; // Locals associated with node (initialized by binding)
372+
nextContainer?: Node; // Next container in declaration order (initialized by binding)
373+
localSymbol?: Symbol; // Local symbol declared by node (initialized by binding only for exported nodes)
367374
}
368375

369376
export interface NodeArray<T> extends Array<T>, TextRange {
@@ -397,6 +404,10 @@ module ts {
397404
expression: Expression;
398405
}
399406

407+
export interface Decorator extends Node {
408+
expression: LeftHandSideExpression;
409+
}
410+
400411
export interface TypeParameterDeclaration extends Declaration {
401412
name: Identifier;
402413
constraint?: TypeNode;
@@ -531,6 +542,14 @@ module ts {
531542
body: Block;
532543
}
533544

545+
// A merged view of get/set accessors
546+
export interface MergedAccessorDeclarations {
547+
getAccessor: AccessorDeclaration;
548+
setAccessor: AccessorDeclaration;
549+
firstAccessor: AccessorDeclaration;
550+
secondAccessor: AccessorDeclaration;
551+
}
552+
534553
export interface IndexSignatureDeclaration extends SignatureDeclaration, ClassElement {
535554
_indexSignatureDeclarationBrand: any;
536555
}
@@ -1337,17 +1356,18 @@ module ts {
13371356
}
13381357

13391358
export const enum NodeCheckFlags {
1340-
TypeChecked = 0x00000001, // Node has been type checked
1341-
LexicalThis = 0x00000002, // Lexical 'this' reference
1342-
CaptureThis = 0x00000004, // Lexical 'this' used in body
1343-
EmitExtends = 0x00000008, // Emit __extends
1344-
SuperInstance = 0x00000010, // Instance 'super' reference
1345-
SuperStatic = 0x00000020, // Static 'super' reference
1346-
ContextChecked = 0x00000040, // Contextual types have been assigned
1359+
TypeChecked = 0x00000001, // Node has been type checked
1360+
LexicalThis = 0x00000002, // Lexical 'this' reference
1361+
CaptureThis = 0x00000004, // Lexical 'this' used in body
1362+
EmitExtends = 0x00000008, // Emit __extends
1363+
SuperInstance = 0x00000010, // Instance 'super' reference
1364+
SuperStatic = 0x00000020, // Static 'super' reference
1365+
ContextChecked = 0x00000040, // Contextual types have been assigned
13471366

13481367
// Values for enum members have been computed, and any errors have been reported for them.
1349-
EnumValuesComputed = 0x00000080,
1350-
BlockScopedBindingInLoop = 0x00000100,
1368+
EnumValuesComputed = 0x00000080,
1369+
BlockScopedBindingInLoop = 0x00000100,
1370+
EmitDecorate = 0x00000200, // Emit __decorate
13511371
}
13521372

13531373
export interface NodeLinks {

src/compiler/utilities.ts

+142-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/// <reference path="types.ts" />
1+
/// <reference path="binder.ts" />
22

33
module ts {
44
export interface ReferencePathMatchResult {
@@ -575,6 +575,133 @@ module ts {
575575
return (<CallExpression>node).expression;
576576
}
577577

578+
export function mergeAccessorDeclarations(declarations: NodeArray<Declaration>, accessor: AccessorDeclaration): MergedAccessorDeclarations {
579+
let firstAccessor: AccessorDeclaration;
580+
let secondAccessor: AccessorDeclaration;
581+
let getAccessor: AccessorDeclaration;
582+
let setAccessor: AccessorDeclaration;
583+
if (hasDynamicName(accessor)) {
584+
firstAccessor = accessor;
585+
if (accessor.kind === SyntaxKind.GetAccessor) {
586+
getAccessor = accessor;
587+
}
588+
else if (accessor.kind === SyntaxKind.SetAccessor) {
589+
setAccessor = accessor;
590+
}
591+
else {
592+
Debug.fail("Accessor has wrong kind");
593+
}
594+
}
595+
else {
596+
forEach(declarations, (member: Declaration) => {
597+
if ((member.kind === SyntaxKind.GetAccessor || member.kind === SyntaxKind.SetAccessor)
598+
&& (member.flags & NodeFlags.Static) === (accessor.flags & NodeFlags.Static)) {
599+
let memberName = getPropertyNameForPropertyNameNode(member.name);
600+
let accessorName = getPropertyNameForPropertyNameNode(accessor.name);
601+
if (memberName === accessorName) {
602+
if (!firstAccessor) {
603+
firstAccessor = <AccessorDeclaration>member;
604+
}
605+
else if (!secondAccessor) {
606+
secondAccessor = <AccessorDeclaration>member;
607+
}
608+
609+
if (member.kind === SyntaxKind.GetAccessor && !getAccessor) {
610+
getAccessor = <AccessorDeclaration>member;
611+
}
612+
613+
if (member.kind === SyntaxKind.SetAccessor && !setAccessor) {
614+
setAccessor = <AccessorDeclaration>member;
615+
}
616+
}
617+
}
618+
});
619+
}
620+
return {
621+
firstAccessor,
622+
secondAccessor,
623+
getAccessor,
624+
setAccessor
625+
};
626+
}
627+
628+
export function nodeCanBeDecorated(node: Node): boolean {
629+
switch (node.kind) {
630+
case SyntaxKind.ClassDeclaration:
631+
// classes are valid targets
632+
return true;
633+
634+
case SyntaxKind.PropertyDeclaration:
635+
// property declarations are valid if their parent is a class declaration.
636+
return node.parent.kind === SyntaxKind.ClassDeclaration;
637+
638+
case SyntaxKind.Parameter:
639+
// if the parameter's parent has a body and its grandparent is a class declaration, this is a valid target;
640+
return (<FunctionLikeDeclaration>node.parent).body && node.parent.parent.kind === SyntaxKind.ClassDeclaration;
641+
642+
case SyntaxKind.GetAccessor:
643+
case SyntaxKind.SetAccessor:
644+
case SyntaxKind.MethodDeclaration:
645+
// if this method has a body and its parent is a class declaration, this is a valid target.
646+
return (<FunctionLikeDeclaration>node).body && node.parent.kind === SyntaxKind.ClassDeclaration;
647+
}
648+
649+
return false;
650+
}
651+
652+
export function nodeIsDecorated(node: Node): boolean {
653+
switch (node.kind) {
654+
case SyntaxKind.ClassDeclaration:
655+
if (node.decorators) {
656+
return true;
657+
}
658+
659+
return false;
660+
661+
case SyntaxKind.PropertyDeclaration:
662+
case SyntaxKind.Parameter:
663+
if (node.decorators) {
664+
return true;
665+
}
666+
667+
return false;
668+
669+
case SyntaxKind.GetAccessor:
670+
if ((<FunctionLikeDeclaration>node).body && node.decorators) {
671+
return true;
672+
}
673+
674+
return false;
675+
676+
case SyntaxKind.MethodDeclaration:
677+
case SyntaxKind.SetAccessor:
678+
if ((<FunctionLikeDeclaration>node).body && node.decorators) {
679+
return true;
680+
}
681+
682+
return false;
683+
}
684+
685+
return false;
686+
}
687+
688+
export function childIsDecorated(node: Node): boolean {
689+
switch (node.kind) {
690+
case SyntaxKind.ClassDeclaration:
691+
return forEach((<ClassDeclaration>node).members, nodeOrChildIsDecorated);
692+
693+
case SyntaxKind.MethodDeclaration:
694+
case SyntaxKind.SetAccessor:
695+
return forEach((<FunctionLikeDeclaration>node).parameters, nodeIsDecorated);
696+
}
697+
698+
return false;
699+
}
700+
701+
export function nodeOrChildIsDecorated(node: Node): boolean {
702+
return nodeIsDecorated(node) || childIsDecorated(node);
703+
}
704+
578705
export function isExpression(node: Node): boolean {
579706
switch (node.kind) {
580707
case SyntaxKind.ThisKeyword:
@@ -814,6 +941,20 @@ module ts {
814941
}
815942
}
816943

944+
export function isClassElement(n: Node): boolean {
945+
switch (n.kind) {
946+
case SyntaxKind.Constructor:
947+
case SyntaxKind.PropertyDeclaration:
948+
case SyntaxKind.MethodDeclaration:
949+
case SyntaxKind.GetAccessor:
950+
case SyntaxKind.SetAccessor:
951+
case SyntaxKind.IndexSignature:
952+
return true;
953+
default:
954+
return false;
955+
}
956+
}
957+
817958
// True if the given identifier, string literal, or number literal is the name of a declaration node
818959
export function isDeclarationName(name: Node): boolean {
819960
if (name.kind !== SyntaxKind.Identifier && name.kind !== SyntaxKind.StringLiteral && name.kind !== SyntaxKind.NumericLiteral) {

src/lib/core.d.ts

+14
Original file line numberDiff line numberDiff line change
@@ -1155,3 +1155,17 @@ interface ArrayConstructor {
11551155
}
11561156

11571157
declare var Array: ArrayConstructor;
1158+
1159+
interface TypedPropertyDescriptor<T> {
1160+
enumerable?: boolean;
1161+
configurable?: boolean;
1162+
writable?: boolean;
1163+
value?: T;
1164+
get?: () => T;
1165+
set?: (value: T) => void;
1166+
}
1167+
1168+
declare type ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction | void;
1169+
declare type PropertyDecorator = (target: Object, propertyKey: string | symbol) => void;
1170+
declare type MethodDecorator = <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void;
1171+
declare type ParameterDecorator = (target: Function, propertyKey: string | symbol, parameterIndex: number) => void;

0 commit comments

Comments
 (0)