@@ -3941,3 +3941,242 @@ func IsPotentiallyExecutableNode(node *Node) bool {
39413941 }
39423942 return IsClassDeclaration (node ) || IsEnumDeclaration (node ) || IsModuleDeclaration (node )
39433943}
3944+
3945+ func HasAbstractModifier (node * Node ) bool {
3946+ return HasSyntacticModifier (node , ModifierFlagsAbstract )
3947+ }
3948+
3949+ func HasAmbientModifier (node * Node ) bool {
3950+ return HasSyntacticModifier (node , ModifierFlagsAmbient )
3951+ }
3952+
3953+ func NodeCanBeDecorated (useLegacyDecorators bool , node * Node , parent * Node , grandparent * Node ) bool {
3954+ // private names cannot be used with decorators yet
3955+ if useLegacyDecorators && node .Name () != nil && IsPrivateIdentifier (node .Name ()) {
3956+ return false
3957+ }
3958+ switch node .Kind {
3959+ case KindClassDeclaration :
3960+ // class declarations are valid targets
3961+ return true
3962+ case KindClassExpression :
3963+ // class expressions are valid targets for native decorators
3964+ return ! useLegacyDecorators
3965+ case KindPropertyDeclaration :
3966+ // property declarations are valid if their parent is a class declaration.
3967+ return parent != nil && (useLegacyDecorators && IsClassDeclaration (parent ) ||
3968+ ! useLegacyDecorators && IsClassLike (parent ) && ! HasAbstractModifier (node ) && ! HasAmbientModifier (node ))
3969+ case KindGetAccessor , KindSetAccessor , KindMethodDeclaration :
3970+ // if this method has a body and its parent is a class declaration, this is a valid target.
3971+ return parent != nil && node .Body () != nil && (useLegacyDecorators && IsClassDeclaration (parent ) ||
3972+ ! useLegacyDecorators && IsClassLike (parent ))
3973+ case KindParameter :
3974+ // TODO(rbuckton): Parameter decorator support for ES decorators must wait until it is standardized
3975+ if ! useLegacyDecorators {
3976+ return false
3977+ }
3978+ // if the parameter's parent has a body and its grandparent is a class declaration, this is a valid target.
3979+ return parent != nil && parent .Body () != nil &&
3980+ (parent .Kind == KindConstructor || parent .Kind == KindMethodDeclaration || parent .Kind == KindSetAccessor ) &&
3981+ GetThisParameter (parent ) != node && grandparent != nil && grandparent .Kind == KindClassDeclaration
3982+ }
3983+
3984+ return false
3985+ }
3986+
3987+ func ClassOrConstructorParameterIsDecorated (useLegacyDecorators bool , node * Node ) bool {
3988+ if nodeIsDecorated (useLegacyDecorators , node , nil , nil ) {
3989+ return true
3990+ }
3991+ constructor := GetFirstConstructorWithBody (node )
3992+ return constructor != nil && ChildIsDecorated (useLegacyDecorators , constructor , node )
3993+ }
3994+
3995+ func ClassElementOrClassElementParameterIsDecorated (useLegacyDecorators bool , node * Node , parent * Node ) bool {
3996+ var parameters * NodeList
3997+ if IsAccessor (node ) {
3998+ decls := GetAllAccessorDeclarations (parent .Members (), node )
3999+ var firstAccessorWithDecorators * Node
4000+ if HasDecorators (decls .FirstAccessor ) {
4001+ firstAccessorWithDecorators = decls .FirstAccessor
4002+ } else if HasDecorators (decls .SecondAccessor ) {
4003+ firstAccessorWithDecorators = decls .SecondAccessor
4004+ }
4005+ if firstAccessorWithDecorators == nil || node != firstAccessorWithDecorators {
4006+ return false
4007+ }
4008+ if decls .SetAccessor != nil {
4009+ parameters = decls .SetAccessor .Parameters
4010+ }
4011+ } else if IsMethodDeclaration (node ) {
4012+ parameters = node .ParameterList ()
4013+ }
4014+ if nodeIsDecorated (useLegacyDecorators , node , parent , nil ) {
4015+ return true
4016+ }
4017+ if parameters != nil && len (parameters .Nodes ) > 0 {
4018+ for _ , parameter := range parameters .Nodes {
4019+ if IsThisParameter (parameter ) {
4020+ continue
4021+ }
4022+ if nodeIsDecorated (useLegacyDecorators , parameter , node , parent ) {
4023+ return true
4024+ }
4025+ }
4026+ }
4027+ return false
4028+ }
4029+
4030+ func nodeIsDecorated (useLegacyDecorators bool , node * Node , parent * Node , grandparent * Node ) bool {
4031+ return HasDecorators (node ) && NodeCanBeDecorated (useLegacyDecorators , node , parent , grandparent )
4032+ }
4033+
4034+ func NodeOrChildIsDecorated (useLegacyDecorators bool , node * Node , parent * Node , grandparent * Node ) bool {
4035+ return nodeIsDecorated (useLegacyDecorators , node , parent , grandparent ) || ChildIsDecorated (useLegacyDecorators , node , parent )
4036+ }
4037+
4038+ func ChildIsDecorated (useLegacyDecorators bool , node * Node , parent * Node ) bool {
4039+ switch node .Kind {
4040+ case KindClassDeclaration , KindClassExpression :
4041+ return core .Some (node .Members (), func (m * Node ) bool {
4042+ return NodeOrChildIsDecorated (useLegacyDecorators , m , node , parent )
4043+ })
4044+ case KindMethodDeclaration ,
4045+ KindSetAccessor ,
4046+ KindConstructor :
4047+ return core .Some (node .Parameters (), func (p * Node ) bool {
4048+ return nodeIsDecorated (useLegacyDecorators , p , node , parent )
4049+ })
4050+ default :
4051+ return false
4052+ }
4053+ }
4054+
4055+ type AllAccessorDeclarations struct {
4056+ FirstAccessor * AccessorDeclaration
4057+ SecondAccessor * AccessorDeclaration
4058+ SetAccessor * SetAccessorDeclaration
4059+ GetAccessor * GetAccessorDeclaration
4060+ }
4061+
4062+ func GetAllAccessorDeclarationsForDeclaration (accessor * AccessorDeclaration , declarationsOfSymbol []* Node ) AllAccessorDeclarations {
4063+ var otherKind Kind
4064+ if accessor .Kind == KindSetAccessor {
4065+ otherKind = KindGetAccessor
4066+ } else if accessor .Kind == KindGetAccessor {
4067+ otherKind = KindSetAccessor
4068+ } else {
4069+ panic (fmt .Sprintf ("Unexpected node kind %q" , accessor .Kind ))
4070+ }
4071+ // otherAccessor := ast.GetDeclarationOfKind(c.getSymbolOfDeclaration(accessor), otherKind)
4072+ var otherAccessor * AccessorDeclaration
4073+ for _ , d := range declarationsOfSymbol {
4074+ if d .Kind == otherKind {
4075+ otherAccessor = d
4076+ break
4077+ }
4078+ }
4079+
4080+ var firstAccessor * AccessorDeclaration
4081+ var secondAccessor * AccessorDeclaration
4082+ if otherAccessor != nil && (otherAccessor .Pos () < accessor .Pos ()) {
4083+ firstAccessor = otherAccessor
4084+ secondAccessor = accessor
4085+ } else {
4086+ firstAccessor = accessor
4087+ secondAccessor = otherAccessor
4088+ }
4089+
4090+ var setAccessor * SetAccessorDeclaration
4091+ var getAccessor * GetAccessorDeclaration
4092+ if accessor .Kind == KindSetAccessor {
4093+ setAccessor = accessor .AsSetAccessorDeclaration ()
4094+ if otherAccessor != nil {
4095+ getAccessor = otherAccessor .AsGetAccessorDeclaration ()
4096+ }
4097+ } else {
4098+ getAccessor = accessor .AsGetAccessorDeclaration ()
4099+ if otherAccessor != nil {
4100+ setAccessor = otherAccessor .AsSetAccessorDeclaration ()
4101+ }
4102+ }
4103+
4104+ return AllAccessorDeclarations {
4105+ FirstAccessor : firstAccessor ,
4106+ SecondAccessor : secondAccessor ,
4107+ SetAccessor : setAccessor ,
4108+ GetAccessor : getAccessor ,
4109+ }
4110+ }
4111+
4112+ func GetAllAccessorDeclarations (parentDeclarations []* Node , accessor * AccessorDeclaration ) AllAccessorDeclarations {
4113+ if HasDynamicName (accessor ) {
4114+ // dynamic names can only be match up via checker symbol lookup, just return an object with just this accessor
4115+ return GetAllAccessorDeclarationsForDeclaration (accessor , []* Node {accessor })
4116+ }
4117+
4118+ accessorName := GetPropertyNameForPropertyNameNode (accessor .Name ())
4119+ accessorStatic := IsStatic (accessor )
4120+ var matches []* Node
4121+ for _ , member := range parentDeclarations {
4122+ if ! IsAccessor (member ) || IsStatic (member ) != accessorStatic {
4123+ continue
4124+ }
4125+ memberName := GetPropertyNameForPropertyNameNode (member .Name ())
4126+ if memberName == accessorName {
4127+ matches = append (matches , member )
4128+ }
4129+ }
4130+ return GetAllAccessorDeclarationsForDeclaration (accessor , matches )
4131+ }
4132+
4133+ func IsAsyncFunction (node * Node ) bool {
4134+ switch node .Kind {
4135+ case KindFunctionDeclaration , KindFunctionExpression , KindArrowFunction , KindMethodDeclaration :
4136+ data := node .BodyData ()
4137+ return data .Body != nil && data .AsteriskToken == nil && HasSyntacticModifier (node , ModifierFlagsAsync )
4138+ }
4139+ return false
4140+ }
4141+
4142+ /**
4143+ * Gets the most likely element type for a TypeNode. This is not an exhaustive test
4144+ * as it assumes a rest argument can only be an array type (either T[], or Array<T>).
4145+ *
4146+ * @param node The type node.
4147+ *
4148+ * @internal
4149+ */
4150+ func GetRestParameterElementType (node * ParameterDeclarationNode ) * Node {
4151+ if node == nil {
4152+ return node
4153+ }
4154+ if node .Kind == KindArrayType {
4155+ return node .AsArrayTypeNode ().ElementType
4156+ }
4157+ if node .Kind == KindTypeReference && node .AsTypeReferenceNode ().TypeArguments != nil {
4158+ return core .FirstOrNil (node .AsTypeReferenceNode ().TypeArguments .Nodes )
4159+ }
4160+ return nil
4161+ }
4162+
4163+ func isTagName (node * Node ) bool {
4164+ return node .Parent != nil && IsJSDocTag (node .Parent ) && node .Parent .TagName () == node
4165+ }
4166+
4167+ // We want to store any numbers/strings if they were a name that could be
4168+ // related to a declaration. So, if we have 'import x = require("something")'
4169+ // then we want 'something' to be in the name table. Similarly, if we have
4170+ // "a['propname']" then we want to store "propname" in the name table.
4171+ func literalIsName (node * Node ) bool {
4172+ return IsDeclarationName (node ) ||
4173+ node .Parent .Kind == KindExternalModuleReference ||
4174+ isArgumentOfElementAccessExpression (node ) ||
4175+ IsLiteralComputedPropertyDeclarationName (node )
4176+ }
4177+
4178+ func isArgumentOfElementAccessExpression (node * Node ) bool {
4179+ return node != nil && node .Parent != nil &&
4180+ node .Parent .Kind == KindElementAccessExpression &&
4181+ node .Parent .AsElementAccessExpression ().ArgumentExpression == node
4182+ }
0 commit comments