@@ -842,3 +842,158 @@ func IsImportMeta(node *Node) bool {
842
842
}
843
843
return false
844
844
}
845
+
846
+ func IsInJSFile (node * Node ) bool {
847
+ return node != nil && node .Flags & NodeFlagsJavaScriptFile != 0
848
+ }
849
+
850
+ func IsDeclaration (node * Node ) bool {
851
+ if node .Kind == KindTypeParameter {
852
+ return node .Parent != nil
853
+ }
854
+ return IsDeclarationNode (node )
855
+ }
856
+
857
+ // True if `name` is the name of a declaration node
858
+ func IsDeclarationName (name * Node ) bool {
859
+ return ! IsSourceFile (name ) && ! IsBindingPattern (name ) && IsDeclaration (name .Parent )
860
+ }
861
+
862
+ // Like 'isDeclarationName', but returns true for LHS of `import { x as y }` or `export { x as y }`.
863
+ func IsDeclarationNameOrImportPropertyName (name * Node ) bool {
864
+ switch name .Parent .Kind {
865
+ case KindImportSpecifier , KindExportSpecifier :
866
+ return IsIdentifier (name ) || name .Kind == KindStringLiteral
867
+ default :
868
+ return IsDeclarationName (name )
869
+ }
870
+ }
871
+
872
+ func IsLiteralComputedPropertyDeclarationName (node * Node ) bool {
873
+ return IsStringOrNumericLiteralLike (node ) &&
874
+ node .Parent .Kind == KindComputedPropertyName &&
875
+ IsDeclaration (node .Parent .Parent )
876
+ }
877
+
878
+ func IsExternalModuleImportEqualsDeclaration (node * Node ) bool {
879
+ return node .Kind == KindImportEqualsDeclaration && node .AsImportEqualsDeclaration ().ModuleReference .Kind == KindExternalModuleReference
880
+ }
881
+
882
+ func IsLiteralImportTypeNode (node * Node ) bool {
883
+ return IsImportTypeNode (node ) && IsLiteralTypeNode (node .AsImportTypeNode ().Argument ) && IsStringLiteral (node .AsImportTypeNode ().Argument .AsLiteralTypeNode ().Literal )
884
+ }
885
+
886
+ func IsEntityNameExpression (node * Node ) bool {
887
+ return node .Kind == KindIdentifier || isPropertyAccessEntityNameExpression (node )
888
+ }
889
+
890
+ func isPropertyAccessEntityNameExpression (node * Node ) bool {
891
+ if node .Kind == KindPropertyAccessExpression {
892
+ expr := node .AsPropertyAccessExpression ()
893
+ return expr .Name ().Kind == KindIdentifier && IsEntityNameExpression (expr .Expression )
894
+ }
895
+ return false
896
+ }
897
+
898
+ func IsJsxTagName (node * Node ) bool {
899
+ parent := node .Parent
900
+ switch parent .Kind {
901
+ case KindJsxOpeningElement , KindJsxClosingElement , KindJsxSelfClosingElement :
902
+ return parent .TagName () == node
903
+ }
904
+ return false
905
+ }
906
+
907
+ func IsImportOrExportSpecifier (node * Node ) bool {
908
+ return IsImportSpecifier (node ) || IsExportSpecifier (node )
909
+ }
910
+
911
+ func IsDynamicName (name * Node ) bool {
912
+ var expr * Node
913
+ switch name .Kind {
914
+ case KindComputedPropertyName :
915
+ expr = name .AsComputedPropertyName ().Expression
916
+ case KindElementAccessExpression :
917
+ expr = SkipParentheses (name .AsElementAccessExpression ().ArgumentExpression )
918
+ default :
919
+ return false
920
+ }
921
+ return ! IsStringOrNumericLiteralLike (expr ) && ! IsSignedNumericLiteral (expr )
922
+ }
923
+
924
+ func IsSignedNumericLiteral (node * Node ) bool {
925
+ if node .Kind == KindPrefixUnaryExpression {
926
+ node := node .AsPrefixUnaryExpression ()
927
+ return (node .Operator == KindPlusToken || node .Operator == KindMinusToken ) && IsNumericLiteral (node .Operand )
928
+ }
929
+ return false
930
+ }
931
+
932
+ func IsAssignmentExpression (node * Node , excludeCompoundAssignment bool ) bool {
933
+ if node .Kind == KindBinaryExpression {
934
+ expr := node .AsBinaryExpression ()
935
+ return (expr .OperatorToken .Kind == KindEqualsToken || ! excludeCompoundAssignment && IsAssignmentOperator (expr .OperatorToken .Kind )) &&
936
+ IsLeftHandSideExpression (expr .Left )
937
+ }
938
+ return false
939
+ }
940
+
941
+ func GetRightMostAssignedExpression (node * Node ) * Node {
942
+ for IsAssignmentExpression (node , true /*excludeCompoundAssignment*/ ) {
943
+ node = node .AsBinaryExpression ().Right
944
+ }
945
+ return node
946
+ }
947
+
948
+ func isVoidZero (node * Node ) bool {
949
+ return IsVoidExpression (node ) && IsNumericLiteral (node .Expression ()) && node .Expression ().Text () == "0"
950
+ }
951
+
952
+ func IsVoidExpression (node * Node ) bool {
953
+ return node .Kind == KindVoidExpression
954
+ }
955
+
956
+ func IsExportsIdentifier (node * Node ) bool {
957
+ return IsIdentifier (node ) && node .Text () == "exports"
958
+ }
959
+
960
+ func IsModuleIdentifier (node * Node ) bool {
961
+ return IsIdentifier (node ) && node .Text () == "module"
962
+ }
963
+
964
+ // Does not handle signed numeric names like `a[+0]` - handling those would require handling prefix unary expressions
965
+ // throughout late binding handling as well, which is awkward (but ultimately probably doable if there is demand)
966
+ func GetElementOrPropertyAccessArgumentExpressionOrName (node * Node ) * Node {
967
+ switch node .Kind {
968
+ case KindPropertyAccessExpression :
969
+ return node .Name ()
970
+ case KindElementAccessExpression :
971
+ arg := SkipParentheses (node .AsElementAccessExpression ().ArgumentExpression )
972
+ if IsStringOrNumericLiteralLike (arg ) {
973
+ return arg
974
+ }
975
+ return node
976
+ }
977
+ panic ("Unhandled case in GetElementOrPropertyAccessArgumentExpressionOrName" )
978
+ }
979
+
980
+ func IsExpressionWithTypeArgumentsInClassExtendsClause (node * Node ) bool {
981
+ return TryGetClassExtendingExpressionWithTypeArguments (node ) != nil
982
+ }
983
+
984
+ func TryGetClassExtendingExpressionWithTypeArguments (node * Node ) * ClassLikeDeclaration {
985
+ cls , isImplements := TryGetClassImplementingOrExtendingExpressionWithTypeArguments (node )
986
+ if cls != nil && ! isImplements {
987
+ return cls
988
+ }
989
+ return nil
990
+ }
991
+
992
+ func TryGetClassImplementingOrExtendingExpressionWithTypeArguments (node * Node ) (class * ClassLikeDeclaration , isImplements bool ) {
993
+ if IsExpressionWithTypeArguments (node ) {
994
+ if IsHeritageClause (node .Parent ) && IsClassLike (node .Parent .Parent ) {
995
+ return node .Parent .Parent , node .Parent .AsHeritageClause ().Token == KindImplementsKeyword
996
+ }
997
+ }
998
+ return nil , false
999
+ }
0 commit comments