/// <summary> /// Creates a type literal with shape {} /// </summary> private static TypeLiteralNode CreateEmptyTypeLiteral(int pos, ISourceFile sourceFile) { var emptyTypeLiteral = CreateInjectedNode <TypeLiteralNode>(SyntaxKind.TypeLiteral, pos, sourceFile); emptyTypeLiteral.Members = NodeArray.Empty <ITypeElement>(); return(emptyTypeLiteral); }
private static void AnalyzeVariableStatement(INode node, DiagnosticContext context) { var statement = node.Cast <IVariableStatement>(); if (statement.IsTopLevelOrNamespaceLevelDeclaration()) { foreach (var declaration in (statement.DeclarationList?.Declarations ?? NodeArray.Empty <IVariableDeclaration>()).AsStructEnumerable()) { var type = context.SemanticModel.GetTypeAtLocation(declaration); if (type != null && type.IsMutable()) { context.Logger.ReportNoMutableDeclarationsAtTopLevel( context.LoggingContext, statement.LocationForLogging(context.SourceFile)); } } } }
private static void DoGetChildren(INode node, List <NodeOrNodeArray> nodes, bool recurseThroughIdentifiers = false) { if (node == null) { return; } switch (node.Kind) { case SyntaxKind.QualifiedName: { var concreteNode = node.Cast <IQualifiedName>(); nodes.Add(Node(concreteNode.Left)); nodes.Add(Node(concreteNode.Right)); break; } case SyntaxKind.TypeParameter: { var concreteNode = node.Cast <ITypeParameterDeclaration>(); nodes.Add(Node(concreteNode.Name)); nodes.Add(Node(concreteNode.Constraint)); nodes.Add(Node(concreteNode.Expression)); break; } case SyntaxKind.ShorthandPropertyAssignment: { var concreteNode = node.Cast <IShorthandPropertyAssignment>(); nodes.Add(Nodes(node.Decorators)); nodes.Add(Nodes(node.Modifiers)); nodes.Add(Node(concreteNode.Name)); nodes.Add(Node(concreteNode.QuestionToken.ValueOrDefault)); nodes.Add(Node(concreteNode.EqualsToken.ValueOrDefault)); nodes.Add(Node(concreteNode.ObjectAssignmentInitializer)); break; } case SyntaxKind.Parameter: case SyntaxKind.PropertyDeclaration: case SyntaxKind.PropertySignature: case SyntaxKind.PropertyAssignment: case SyntaxKind.VariableDeclaration: case SyntaxKind.BindingElement: { var concreteNode = node.Cast <IVariableLikeDeclaration>(); nodes.Add(Nodes(node.Decorators)); nodes.Add(Nodes(node.Modifiers)); nodes.Add(Node(concreteNode.PropertyName)); nodes.Add(Node(concreteNode.DotDotDotToken.ValueOrDefault)); nodes.Add(Node(concreteNode.Name)); nodes.Add(Node(concreteNode.QuestionToken.ValueOrDefault)); nodes.Add(Node(concreteNode.Type)); nodes.Add(Node(concreteNode.Initializer)); break; } case SyntaxKind.FunctionType: case SyntaxKind.ConstructorType: case SyntaxKind.CallSignature: case SyntaxKind.ConstructSignature: case SyntaxKind.IndexSignature: { var concreteNode = node.Cast <ISignatureDeclaration>(); nodes.Add(Nodes(node.Decorators)); nodes.Add(Nodes(node.Modifiers)); nodes.Add(Nodes(concreteNode.TypeParameters ?? NodeArray.Empty <ITypeParameterDeclaration>())); nodes.Add(Nodes(concreteNode.Parameters)); nodes.Add(Node(concreteNode.Type)); break; } case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: case SyntaxKind.Constructor: case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: case SyntaxKind.FunctionExpression: case SyntaxKind.FunctionDeclaration: case SyntaxKind.ArrowFunction: { var concreteNode = node.Cast <IFunctionLikeDeclaration>(); nodes.Add(Nodes(node.Decorators)); nodes.Add(Nodes(node.Modifiers)); nodes.Add(Node(concreteNode.AsteriskToken.ValueOrDefault)); nodes.Add(Node(concreteNode.Name)); nodes.Add(Node(concreteNode.QuestionToken.ValueOrDefault)); nodes.Add(Nodes(concreteNode.TypeParameters ?? NodeArray.Empty <ITypeParameterDeclaration>())); nodes.Add(Nodes(concreteNode.Parameters)); nodes.Add(Node(concreteNode.Type)); nodes.Add(Node(node.As <IArrowFunction>()?.EqualsGreaterThanToken)); nodes.Add(Node(concreteNode.Body)); break; } case SyntaxKind.TypeReference: { var concreteNode = node.Cast <ITypeReferenceNode>(); nodes.Add(Node(concreteNode.TypeName)); nodes.Add(Nodes(concreteNode.TypeArguments ?? NodeArray.Empty <ITypeNode>())); break; } case SyntaxKind.TypePredicate: { var concreteNode = node.Cast <ITypePredicateNode>(); nodes.Add(Node(concreteNode.ParameterName)); nodes.Add(Node(concreteNode.Type)); break; } case SyntaxKind.TypeQuery: nodes.Add(Node(node.Cast <ITypeQueryNode>().ExprName)); break; case SyntaxKind.TypeLiteral: nodes.Add(Nodes(node.Cast <ITypeLiteralNode>().Members)); break; case SyntaxKind.ArrayType: nodes.Add(Node(node.Cast <IArrayTypeNode>().ElementType)); break; case SyntaxKind.TupleType: nodes.Add(Nodes(node.Cast <ITupleTypeNode>().ElementTypes)); break; case SyntaxKind.UnionType: case SyntaxKind.IntersectionType: nodes.Add(Nodes(node.Cast <IUnionOrIntersectionTypeNode>().Types)); break; case SyntaxKind.ParenthesizedType: nodes.Add(Node(node.Cast <IParenthesizedTypeNode>().Type)); break; case SyntaxKind.ObjectBindingPattern: case SyntaxKind.ArrayBindingPattern: nodes.Add(Nodes(node.Cast <IBindingPattern>().Elements)); break; case SyntaxKind.ArrayLiteralExpression: nodes.Add(Nodes(node.Cast <IArrayLiteralExpression>().Elements)); break; case SyntaxKind.ObjectLiteralExpression: nodes.Add(Nodes(node.Cast <IObjectLiteralExpression>().Properties)); break; case SyntaxKind.PropertyAccessExpression: { var concreteNode = node.Cast <IPropertyAccessExpression>(); nodes.Add(Node(concreteNode.Expression)); nodes.Add(Node(concreteNode.DotToken)); nodes.Add(Node(concreteNode.Name)); break; } case SyntaxKind.ElementAccessExpression: { var concreteNode = node.Cast <IElementAccessExpression>(); nodes.Add(Node(concreteNode.Expression)); nodes.Add(Node(concreteNode.ArgumentExpression)); break; } case SyntaxKind.CallExpression: case SyntaxKind.NewExpression: { var concreteNode = node.Cast <ICallExpression>(); nodes.Add(Node(concreteNode.Expression)); nodes.Add(Nodes(concreteNode.TypeArguments)); nodes.Add(Nodes(concreteNode.Arguments)); break; } case SyntaxKind.TaggedTemplateExpression: { var concreteNode = node.Cast <ITaggedTemplateExpression>(); nodes.Add(Node(concreteNode.Tag)); nodes.Add(Node(concreteNode.TemplateExpression)); break; } case SyntaxKind.TypeAssertionExpression: { var concreteNode = node.Cast <ITypeAssertion>(); nodes.Add(Node(concreteNode.Type)); nodes.Add(Node(concreteNode.Expression)); break; } case SyntaxKind.ParenthesizedExpression: nodes.Add(Node(node.Cast <IParenthesizedExpression>().Expression)); break; case SyntaxKind.DeleteExpression: nodes.Add(Node(node.Cast <IDeleteExpression>().Expression)); break; case SyntaxKind.TypeOfExpression: nodes.Add(Node(node.Cast <ITypeOfExpression>().Expression)); break; case SyntaxKind.VoidExpression: nodes.Add(Node(node.Cast <IVoidExpression>().Expression)); break; case SyntaxKind.PrefixUnaryExpression: nodes.Add(Node(node.Cast <IPrefixUnaryExpression>().Operand)); break; case SyntaxKind.YieldExpression: { var concreteExpression = node.Cast <IYieldExpression>(); nodes.Add(Node(concreteExpression.AsteriskToken)); nodes.Add(Node(concreteExpression.Expression)); break; } case SyntaxKind.AwaitExpression: nodes.Add(Node(node.Cast <IAwaitExpression>().Expression)); break; case SyntaxKind.PostfixUnaryExpression: nodes.Add(Node(node.Cast <IPostfixUnaryExpression>().Operand)); break; case SyntaxKind.BinaryExpression: { var concreteNode = node.Cast <IBinaryExpression>(); nodes.Add(Node(concreteNode.Left)); nodes.Add(Node(concreteNode.OperatorToken)); nodes.Add(Node(concreteNode.Right)); break; } case SyntaxKind.AsExpression: { var concreteNode = node.Cast <IAsExpression>(); nodes.Add(Node(concreteNode.Expression)); nodes.Add(Node(concreteNode.Type)); break; } case SyntaxKind.ConditionalExpression: { var concreteNode = node.Cast <IConditionalExpression>(); nodes.Add(Node(concreteNode.Condition)); nodes.Add(Node(concreteNode.QuestionToken)); nodes.Add(Node(concreteNode.WhenTrue)); nodes.Add(Node(concreteNode.ColonToken)); nodes.Add(Node(concreteNode.WhenFalse)); break; } case SyntaxKind.SwitchExpression: { var concreteNode = node.Cast <ISwitchExpression>(); nodes.Add(Node(concreteNode.Expression)); foreach (var clause in concreteNode.Clauses) { nodes.Add(Node(clause)); } break; } case SyntaxKind.SwitchExpressionClause: { var concreteNode = node.Cast <ISwitchExpressionClause>(); if (!concreteNode.IsDefaultFallthrough) { nodes.Add(Node(concreteNode.Match)); } nodes.Add(Node(concreteNode.Expression)); break; } case SyntaxKind.SpreadElementExpression: nodes.Add(Node(node.Cast <ISpreadElementExpression>().Expression)); break; case SyntaxKind.Block: case SyntaxKind.ModuleBlock: nodes.Add(Nodes(node.Cast <IBlock>().Statements)); break; case SyntaxKind.SourceFile: nodes.Add(Nodes(node.Cast <ISourceFile>().Statements)); nodes.Add(Node(node.Cast <ISourceFile>().EndOfFileToken)); break; case SyntaxKind.VariableStatement: nodes.Add(Nodes(node.Decorators)); nodes.Add(Nodes(node.Modifiers)); nodes.Add(Node(node.Cast <IVariableStatement>().DeclarationList)); break; case SyntaxKind.VariableDeclarationList: nodes.Add(Nodes(node.Cast <IVariableDeclarationList>().Declarations)); break; case SyntaxKind.ExpressionStatement: nodes.Add(Node(node.Cast <IExpressionStatement>().Expression)); break; case SyntaxKind.IfStatement: { var concreteNode = node.Cast <IIfStatement>(); nodes.Add(Node(concreteNode.Expression)); nodes.Add(Node(concreteNode.ThenStatement)); nodes.Add(Node(concreteNode.ElseStatement.ValueOrDefault)); break; } case SyntaxKind.DoStatement: { var concreteNode = node.Cast <IDoStatement>(); nodes.Add(Node(concreteNode.Statement)); nodes.Add(Node(concreteNode.Expression)); break; } case SyntaxKind.WhileStatement: { var concreteNode = node.Cast <IWhileStatement>(); nodes.Add(Node(concreteNode.Expression)); nodes.Add(Node(concreteNode.Statement)); break; } case SyntaxKind.ForStatement: { var concreteNode = node.Cast <IForStatement>(); nodes.Add(Node(concreteNode.Initializer)); nodes.Add(Node(concreteNode.Condition)); nodes.Add(Node(concreteNode.Incrementor)); nodes.Add(Node(concreteNode.Statement)); break; } case SyntaxKind.ForInStatement: { var concreteNode = node.Cast <IForInStatement>(); nodes.Add(Node(concreteNode.Initializer)); nodes.Add(Node(concreteNode.Expression)); nodes.Add(Node(concreteNode.Statement)); break; } case SyntaxKind.ForOfStatement: { var concreteNode = node.Cast <IForOfStatement>(); nodes.Add(Node(concreteNode.Initializer)); nodes.Add(Node(concreteNode.Expression)); nodes.Add(Node(concreteNode.Statement)); break; } case SyntaxKind.ContinueStatement: case SyntaxKind.BreakStatement: nodes.Add(Node(node.Cast <IBreakOrContinueStatement>().Label)); break; case SyntaxKind.ReturnStatement: nodes.Add(Node(node.Cast <IReturnStatement>().Expression)); break; case SyntaxKind.WithStatement: { var concreteNode = node.Cast <IWithStatement>(); nodes.Add(Node(concreteNode.Expression)); nodes.Add(Node(concreteNode.Statement)); break; } case SyntaxKind.SwitchStatement: { var concreteNode = node.Cast <ISwitchStatement>(); nodes.Add(Node(concreteNode.Expression)); nodes.Add(Node(concreteNode.CaseBlock)); break; } case SyntaxKind.CaseBlock: nodes.Add(Nodes(node.Cast <ICaseBlock>().Clauses)); break; case SyntaxKind.CaseClause: { var concreteNode = node.Cast <ICaseClause>(); nodes.Add(Node(concreteNode.Expression)); nodes.Add(Nodes(concreteNode.Statements)); break; } case SyntaxKind.DefaultClause: nodes.Add(Nodes(node.Cast <IDefaultClause>().Statements)); break; case SyntaxKind.LabeledStatement: { var concreteNode = node.Cast <ILabeledStatement>(); nodes.Add(Node(concreteNode.Label)); nodes.Add(Node(concreteNode.Statement)); break; } case SyntaxKind.ThrowStatement: nodes.Add(Node(node.Cast <IThrowStatement>().Expression)); break; case SyntaxKind.TryStatement: { var concreteNode = node.Cast <ITryStatement>(); nodes.Add(Node(concreteNode.TryBlock)); nodes.Add(Node(concreteNode.CatchClause)); nodes.Add(Node(concreteNode.FinallyBlock)); break; } case SyntaxKind.CatchClause: { var concreteNode = node.Cast <ICatchClause>(); nodes.Add(Node(concreteNode.VariableDeclaration)); nodes.Add(Node(concreteNode.Block)); break; } case SyntaxKind.Decorator: nodes.Add(Node(node.Cast <IDecorator>().Expression)); break; case SyntaxKind.ClassDeclaration: case SyntaxKind.ClassExpression: { var concreteNode = node.Cast <IClassLikeDeclaration>(); nodes.Add(Nodes(node.Decorators)); nodes.Add(Nodes(node.Modifiers)); nodes.Add(Node(concreteNode.Name)); nodes.Add(Nodes(concreteNode.TypeParameters)); nodes.Add(Nodes(concreteNode.HeritageClauses)); nodes.Add(Nodes(concreteNode.Members)); break; } case SyntaxKind.InterfaceDeclaration: { var concreteNode = node.Cast <IInterfaceDeclaration>(); nodes.Add(Nodes(node.Decorators)); nodes.Add(Nodes(node.Modifiers)); nodes.Add(Node(concreteNode.Name)); nodes.Add(Nodes(concreteNode.TypeParameters)); nodes.Add(Nodes(concreteNode.HeritageClauses)); nodes.Add(Nodes(concreteNode.Members)); break; } case SyntaxKind.TypeAliasDeclaration: { var concreteNode = node.Cast <ITypeAliasDeclaration>(); nodes.Add(Nodes(node.Decorators)); nodes.Add(Nodes(node.Modifiers)); nodes.Add(Node(concreteNode.Name)); nodes.Add(Nodes(concreteNode.TypeParameters)); nodes.Add(Node(concreteNode.Type)); break; } case SyntaxKind.EnumDeclaration: { var concreteNode = node.Cast <IEnumDeclaration>(); nodes.Add(Nodes(node.Decorators)); nodes.Add(Nodes(node.Modifiers)); nodes.Add(Node(concreteNode.Name)); nodes.Add(Nodes(concreteNode.Members)); break; } case SyntaxKind.EnumMember: { var concreteNode = node.Cast <IEnumMember>(); nodes.Add(Nodes(node.Decorators)); nodes.Add(Node(concreteNode.Name)); nodes.Add(Node(concreteNode.Initializer.ValueOrDefault)); break; } case SyntaxKind.ModuleDeclaration: { var concreteNode = node.Cast <IModuleDeclaration>(); nodes.Add(Nodes(node.Decorators)); nodes.Add(Nodes(node.Modifiers)); nodes.Add(Node(concreteNode.Name)); nodes.Add(Node(concreteNode.Body)); break; } case SyntaxKind.ImportEqualsDeclaration: { var concreteNode = node.Cast <IImportEqualsDeclaration>(); nodes.Add(Nodes(node.Decorators)); nodes.Add(Nodes(node.Modifiers)); nodes.Add(Node(concreteNode.Name)); nodes.Add(Node(concreteNode.ModuleReference)); break; } case SyntaxKind.ImportDeclaration: { var concreteNode = node.Cast <IImportDeclaration>(); nodes.Add(Nodes(node.Decorators)); nodes.Add(Nodes(node.Modifiers)); nodes.Add(Node(concreteNode.ImportClause)); nodes.Add(Node(concreteNode.ModuleSpecifier)); break; } case SyntaxKind.ImportClause: { var concreteNode = node.Cast <IImportClause>(); nodes.Add(Node(concreteNode.Name)); nodes.Add(Node(concreteNode.NamedBindings)); break; } case SyntaxKind.NamespaceImport: nodes.Add(Node(node.Cast <INamespaceImport>().Name)); break; case SyntaxKind.NamedImports: nodes.Add(Nodes(node.Cast <INamedImports>().Elements)); break; case SyntaxKind.NamedExports: nodes.Add(Nodes(node.Cast <INamedExports>().Elements)); break; case SyntaxKind.ExportDeclaration: { var concreteNode = node.Cast <IExportDeclaration>(); nodes.Add(Nodes(node.Decorators)); nodes.Add(Nodes(node.Modifiers)); nodes.Add(Node(concreteNode.ExportClause)); nodes.Add(Node(concreteNode.ModuleSpecifier)); break; } case SyntaxKind.ImportSpecifier: { var concreteNode = node.Cast <IImportSpecifier>(); nodes.Add(Node(concreteNode.PropertyName)); nodes.Add(Node(concreteNode.Name)); break; } case SyntaxKind.ExportSpecifier: { var concreteNode = node.Cast <IExportSpecifier>(); nodes.Add(Node(concreteNode.PropertyName)); nodes.Add(Node(concreteNode.Name)); break; } case SyntaxKind.ExportAssignment: { nodes.Add(Nodes(node.Decorators)); nodes.Add(Nodes(node.Modifiers)); nodes.Add(Node(node.Cast <IExportAssignment>().Expression)); break; } case SyntaxKind.TemplateExpression: { var concreteNode = node.Cast <ITemplateExpression>(); nodes.Add(Node(concreteNode.Head)); nodes.Add(Nodes(concreteNode.TemplateSpans)); break; } case SyntaxKind.TemplateSpan: { var concreteNode = node.Cast <ITemplateSpan>(); nodes.Add(Node(concreteNode.Expression)); nodes.Add(Node(concreteNode.Literal)); break; } case SyntaxKind.ComputedPropertyName: nodes.Add(Node(node.Cast <IComputedPropertyName>().Expression)); break; case SyntaxKind.HeritageClause: nodes.Add(Nodes(node.Cast <IHeritageClause>().Types)); break; case SyntaxKind.ExpressionWithTypeArguments: { var concreteNode = node.Cast <IExpressionWithTypeArguments>(); nodes.Add(Node(concreteNode.Expression)); nodes.Add(Nodes(concreteNode.TypeArguments)); break; } case SyntaxKind.ExternalModuleReference: nodes.Add(Node(node.Cast <IExternalModuleReference>().Expression)); break; case SyntaxKind.MissingDeclaration: nodes.Add(Nodes(node.Decorators)); break; case SyntaxKind.Identifier: { if (recurseThroughIdentifiers) { var declarationName = node.TryCast <DelegatingUnionNode>(); if (declarationName != null) { nodes.Add(Node(declarationName.Node)); } } break; } case SyntaxKind.StringLiteralType: // DScript-specific: decorators on string literal types nodes.Add(Nodes(node.Decorators)); break; } }
/// <summary> /// Returns type arguments of a given type, if any. The result is never null; /// </summary> public static INodeArray <ITypeNode> GetTypeArguments([NotNull] this ITypeNode type) { return(type is ITypeReferenceNode typeReference ? typeReference.TypeArguments ?? NodeArray.Empty <ITypeNode>() : NodeArray.Empty <ITypeNode>()); }
private bool IsTypeAccessible(ITypeNode type) { // type not declared --> treat it as accessible if (type == null) { return(true); } // predefined types are always accessible if (type.IsPredefinedType()) { return(true); } // descend into ParenthesizedType if (type.Kind == TypeScript.Net.Types.SyntaxKind.ParenthesizedType) { return(IsTypeAccessible(type.Cast <IParenthesizedTypeNode>().Type)); } // an array type is accessible iff its element type is accessible if (type.Kind == TypeScript.Net.Types.SyntaxKind.ArrayType) { return(IsTypeAccessible(type.Cast <IArrayTypeNode>().ElementType)); } // a union type is accessible iff all its types are accessible if (type.Kind == TypeScript.Net.Types.SyntaxKind.UnionType) { return(type.Cast <IUnionOrIntersectionTypeNode>().Types.All(t => IsTypeAccessible(t))); } // a function type is accessible iff its return type and its type parameters are accessible if (type.Kind == TypeScript.Net.Types.SyntaxKind.FunctionType) { var fnType = type.Cast <IFunctionOrConstructorTypeNode>(); var fnParameters = fnType.Parameters ?? NodeArray.Empty <IParameterDeclaration>(); return (IsTypeAccessible(fnType.Type) && fnParameters.All(tp => IsTypeAccessible(tp.Type))); } // a type literal is accessible iff all its members are accessible if (type.Kind == TypeScript.Net.Types.SyntaxKind.TypeLiteral) { return(type.Cast <ITypeLiteralNode>().Members.All(m => IsMemberAccessible(m))); bool IsMemberAccessible(ITypeElement e) { var memberTypes = e.Kind == TypeScript.Net.Types.SyntaxKind.PropertySignature ? new[] { e.Cast <IPropertySignature>().Type } : null; // handle other kinds if needed return(memberTypes != null && memberTypes.All(t => IsTypeAccessible(t))); } } // if any type argument is inaccessible, this type is not accessible either var typeArguments = type.GetTypeArguments(); if (!typeArguments.All(t => IsTypeAccessible(t))) { return(false); } // if this type couldn't be resolved, treat it as inaccessible var resolvedSymbol = type.ResolvedSymbol; if (resolvedSymbol == null) { return(false); } // otherwise, a type is accessible if any of its declarations is either explicitly exported or defined in the prelude return(resolvedSymbol .GetDeclarations() .Any(d => d.IsExported() || m_semanticModel.TypeChecker.IsPreludeDeclaration(d))); }