private void BindFunctionDeclaration(FunctionDeclarationSyntax declaration) { var returnType = _symbolSet.ResolveType(declaration.ReturnType, null, null); Func<FunctionSymbol, IEnumerable<ParameterSymbol>> lazyParameterSymbols = fd => { var parameterSymbols = new List<ParameterSymbol>(); foreach (var parameterSyntax in declaration.ParameterList.Parameters) { var parameterValueType = _symbolSet.ResolveType(parameterSyntax.Type, null, null); var parameterDirection = SyntaxFacts.GetParameterDirection(parameterSyntax.Modifiers); parameterSymbols.Add(new SourceParameterSymbol( parameterSyntax, fd, parameterValueType, parameterDirection)); } return parameterSymbols; }; var symbol = new SourceFunctionDeclarationSymbol(declaration, returnType, lazyParameterSymbols); _bindingResult.AddSymbol(declaration, symbol); _symbolSet.AddGlobal(symbol); }
private void BindFunctionDeclaration(FunctionDeclarationSyntax syntax) { var parameters = ImmutableArray.CreateBuilder <ParameterSymbol>(); var seenParameterNames = new HashSet <string>(); foreach (var parameterSyntax in syntax.Parameters) { var parameterName = parameterSyntax.Identifier.Text; var parameterType = BindTypeClause(parameterSyntax.Type); if (!seenParameterNames.Add(parameterName)) { _diagnostics.ReportParameterAlreadyDeclared(parameterSyntax.Span, parameterName); } else { var parameter = new ParameterSymbol(parameterName, parameterType); parameters.Add(parameter); } } var type = BindTypeClause(syntax.Type) ?? TypeSymbol.Void; if (type != TypeSymbol.Void) { _diagnostics.XXX_ReportFunctionsAreUnsupported(syntax.Type.Span); } var function = new FunctionSymbol(syntax.Identifier.Text, parameters.ToImmutable(), type, syntax); if (!_scope.TryDeclareFunction(function)) { _diagnostics.ReportSymbolAlreadyDeclared(syntax.Identifier.Span, function.Name); } }
private void ResolveSignatureTypesInFunction(FunctionDeclarationSyntax function) { function.Type.BeginFulfilling(); var diagnosticCount = diagnostics.Count; // Resolve the declaring type because we need its type for things like `self` if (function.DeclaringType != null) ResolveSignatureTypesInTypeDeclaration(function.DeclaringType); var selfType = ResolveSelfType(function); var resolver = new ExpressionTypeResolver(function.File, diagnostics, selfType); if (function.GenericParameters != null) ResolveTypesInGenericParameters(function.GenericParameters, resolver); var parameterTypes = ResolveTypesInParameters(function, resolver); var returnType = ResolveReturnType(function, resolver); DataType functionType = new FunctionType(parameterTypes, returnType); if (function.GenericParameters?.Any() ?? false) functionType = new MetaFunctionType(function.GenericParameters.Select(p => p.Type.Fulfilled()), functionType); function.Type.Fulfill(functionType); if (diagnosticCount != diagnostics.Count) function.Poison(); }
internal SourceFunctionSymbol(FunctionDeclarationSyntax syntax, Symbol parent, TypeSymbol returnType, Func <InvocableSymbol, IEnumerable <ParameterSymbol> > lazyParameters = null) : base(syntax.Name.GetName(), string.Empty, parent, returnType, lazyParameters) { DeclarationSyntaxes = new List <FunctionDeclarationSyntax> { syntax }; }
private FixedList<DataType> ResolveTypesInParameters( FunctionDeclarationSyntax function, ExpressionTypeResolver expressionResolver) { var types = new List<DataType>(); foreach (var parameter in function.Parameters) switch (parameter) { case NamedParameterSyntax namedParameter: { parameter.Type.BeginFulfilling(); var type = expressionResolver.CheckAndEvaluateTypeExpression(namedParameter .TypeExpression); types.Add(parameter.Type.Fulfill(type)); } break; case SelfParameterSyntax _: // Skip, we have already handled the self parameter break; case FieldParameterSyntax fieldParameter: throw new NotImplementedException(); default: throw NonExhaustiveMatchException.For(parameter); } return types.ToFixedList(); }
private void BuildGraph(FunctionDeclarationSyntax function) { // Temp Variable for return if (function is ConstructorDeclarationSyntax constructor) { graph.AddParameter(true, constructor.SelfParameterType, SpecialName.Self); } else { graph.Let(function.ReturnType.Resolved()); } // TODO don't emit temp variables for unused parameters foreach (var parameter in function.Parameters.Where(p => !p.Unused)) { graph.AddParameter(parameter.MutableBinding, parameter.Type.Resolved(), parameter.Name.UnqualifiedName); } var currentBlock = graph.NewBlock(); foreach (var statement in function.Body.Statements) { currentBlock = ConvertToStatement(currentBlock, statement, null); } // Generate the implicit return statement if (currentBlock != null && !currentBlock.IsTerminated) { currentBlock.AddReturn(); } function.ControlFlow = graph.Build(); }
private void OutputFunctionDeclaration(FunctionDeclarationSyntax node, string prefix) { builder.AddFragment(new OutputFragment(prefix, DefaultColour)); builder.AddFragment(new OutputFragment($"{node.KeywToken} ", StatementColour)); builder.AddFragment(new OutputFragment(node.Identifier.ToString(), FunctionNameColour)); builder.AddFragment(new OutputFragment("(", DefaultColour)); var paramCount = node.Parameters.Count; for (int index = 0; index < paramCount; index++) { var parameter = node.Parameters[index]; Output(parameter, string.Empty); if (index < paramCount - 1) { builder.AddFragment(new OutputFragment(", ", DefaultColour)); } } builder.AddFragment(new OutputFragment(") {", DefaultColour)); builder.NewLine(); Output(node.Body, prefix + IndentString); builder.NewLine(); builder.AddFragment(new OutputFragment(prefix, DefaultColour)); builder.AddFragment(new OutputFragment("}", DefaultColour)); }
private static void BuildScopesInFunctionParameters( LexicalScope containingScope, FunctionDeclarationSyntax function, ExpressionLexicalScopesBuilder binder) { if (function.GenericParameters != null) { foreach (var parameter in function.GenericParameters) { binder.VisitExpression(parameter.TypeExpression, containingScope); } } foreach (var parameter in function.Parameters) { switch (parameter) { case NamedParameterSyntax namedParameter: binder.VisitExpression(namedParameter.TypeExpression, containingScope); break; case SelfParameterSyntax _: case FieldParameterSyntax _: // Nothing to bind break; default: throw NonExhaustiveMatchException.For(parameter); } } }
public FunctionSymbol(string name, ImmutableArray <ParameterSymbol> parameters, TypeSymbol type, FunctionDeclarationSyntax declaration) : base(name) { Parameters = parameters; Type = type; Declaration = declaration; }
private void BindFunctionDeclaration(FunctionDeclarationSyntax declaration) { var returnType = _symbolSet.ResolveType(declaration.ReturnType, null, null); Func <FunctionSymbol, IEnumerable <ParameterSymbol> > lazyParameterSymbols = fd => { var parameterSymbols = new List <ParameterSymbol>(); foreach (var parameterSyntax in declaration.ParameterList.Parameters) { var parameterValueType = _symbolSet.ResolveType(parameterSyntax.Type, null, null); var parameterDirection = SyntaxFacts.GetParameterDirection(parameterSyntax.Modifiers); parameterSymbols.Add(new SourceParameterSymbol( parameterSyntax, fd, parameterValueType, parameterDirection)); } return(parameterSymbols); }; var symbol = new SourceFunctionDeclarationSymbol(declaration, returnType, lazyParameterSymbols); _bindingResult.AddSymbol(declaration, symbol); _symbolSet.AddGlobal(symbol); }
internal FunctionSymbol(string name, ImmutableArray <ParameterSymbol> parameters, TypeSymbol returnType, FunctionDeclarationSyntax funcSyntax) { Name = name; Parameters = parameters; ReturnType = returnType; FuncSyntax = funcSyntax; }
private BoundFunctionDeclaration BindFunctionDeclaration(FunctionDeclarationSyntax declaration, Symbol parent) { BindAttributes(declaration.Attributes); var boundReturnType = Bind(declaration.ReturnType, x => BindType(x, parent)); var functionSymbol = LocalSymbols.OfType <SourceFunctionSymbol>() .FirstOrDefault(x => SyntaxFacts.HaveMatchingSignatures( x.DefinitionSyntax as FunctionSyntax ?? x.DeclarationSyntaxes[0], declaration)); if (functionSymbol != null) { functionSymbol.DeclarationSyntaxes.Add(declaration); } else { functionSymbol = new SourceFunctionSymbol(declaration, parent, boundReturnType.TypeSymbol); AddSymbol(functionSymbol, declaration.Name.SourceRange, true); } if (declaration.Semantic != null) { Bind(declaration.Semantic, BindVariableQualifier); } var functionBinder = new FunctionBinder(_sharedBinderState, this, functionSymbol); var boundParameters = BindParameters(declaration.ParameterList, functionBinder, functionSymbol); return(new BoundFunctionDeclaration(functionSymbol, boundReturnType, boundParameters.ToImmutableArray())); }
public FunctionSymbol(string name, ImmutableArray <ParameterSymbol> parameter, TypeSymbol type, FunctionDeclarationSyntax declaration = null) : base(name) { // Name = name; Parameter = parameter; Type = type; Declaration = declaration; }
private static DataType ResolveReturnType( FunctionDeclarationSyntax function, ExpressionSyntax returnTypeExpression, ExpressionTypeResolver expressionResolver) { var returnType = returnTypeExpression != null ? expressionResolver.CheckAndEvaluateTypeExpression(returnTypeExpression) : DataType.Void; return function.ReturnType.Fulfill(returnType); }
public FunctionSymbol(string name, ImmutableArray <ParameterSymbol> parameters, TypeSymbol type, FunctionDeclarationSyntax declaration = null, bool isPublic = false, string package = "", bool isVirtual = false, bool isOverride = false, Text.TextLocation location = new Text.TextLocation()) : base(name, location) { Parameters = parameters; Type = type; Declaration = declaration; IsPublic = isPublic; Package = package; IsVirtual = isVirtual; IsOverride = isOverride; }
private static void Check(FunctionDeclarationSyntax function, Diagnostics diagnostics) { if (function.Body == null) { return; } var moveChecker = new BindingMutabilityChecker(function, diagnostics); moveChecker.VisitExpression(function.Body, false); }
public void Render(FunctionDeclarationSyntax functionDeclaration) { Render(functionDeclaration.IdentifierNode); WriteSpace(); Render(functionDeclaration.TakesKeywordNode); WriteSpace(); Render(functionDeclaration.ParameterListReferenceNode); WriteSpace(); Render(functionDeclaration.ReturnsKeywordNode); WriteSpace(); Render(functionDeclaration.ReturnTypeNode); }
public static NativeFunctionDeclarationSyntax NativeFunctionDeclaration(FunctionDeclarationSyntax functionDeclaration, bool constant) { return(constant ? new NativeFunctionDeclarationSyntax( new EmptyNode(0), new TokenNode(new SyntaxToken(SyntaxTokenType.NativeKeyword), 0), functionDeclaration) : new NativeFunctionDeclarationSyntax( new TokenNode(new SyntaxToken(SyntaxTokenType.ConstantKeyword), 0), new TokenNode(new SyntaxToken(SyntaxTokenType.NativeKeyword), 0), functionDeclaration)); }
private void ResolveBodyTypesInFunction(FunctionDeclarationSyntax function) { if (function.Body == null) return; var diagnosticCount = diagnostics.Count; // TODO the return types of constructors and init functions should probably be void for purposes of expressions var resolver = new ExpressionTypeResolver(function.File, diagnostics, (Metatype)function.DeclaringType?.Type.Fulfilled(), function.ReturnType.Fulfilled()); // The body of a function shouldn't itself evaluate to anything. // There should be no `=> value` for the block, so the type is `void`. resolver.CheckExpressionType(function.Body, DataType.Void); if (diagnosticCount != diagnostics.Count) function.Poison(); }
private LiveVariables AnalyzeFunction(FunctionDeclarationSyntax function) { // We can't check because of errors or no body if (function.Poisoned || function.ControlFlow == null) { return(null); } var edges = function.ControlFlow.Edges; // Compute aliveness at point after each statement return(ComputeLiveness(function.ControlFlow, edges)); }
public override void VisitFunctionDeclaration(FunctionDeclarationSyntax node) { var symbol = _semanticModel.GetDeclaredSymbol(node); if (symbol != null) { CreateTag(node.Name.GetUnqualifiedName().Name, symbol.Parent != null && (symbol.Parent.Kind == SymbolKind.Class || symbol.Parent.Kind == SymbolKind.Struct) ? HlslClassificationTypeNames.MethodIdentifier : HlslClassificationTypeNames.FunctionIdentifier); } base.VisitFunctionDeclaration(node); }
private HashSet <Claim> AcquireParameterClaims(FunctionDeclarationSyntax function) { var claimsBeforeStatement = new HashSet <Claim>(); foreach (var parameter in function.ControlFlow.VariableDeclarations .Where(v => v.IsParameter && v.Type is ReferenceType)) { claimsBeforeStatement.Add(new Loan(parameter.Number, nextObjectId)); nextObjectId += 1; } return(claimsBeforeStatement); }
private static void BuildScopesInFunctionBody( LexicalScope containingScope, FunctionDeclarationSyntax function, ExpressionLexicalScopesBuilder binder) { var symbols = new List <ISymbol>(); foreach (var parameter in function.Parameters) { symbols.Add(parameter); } containingScope = new NestedScope(containingScope, symbols, Enumerable.Empty <ISymbol>()); binder.VisitBlock(function.Body, containingScope); }
private FunctionDeclarationSyntax ParseFunctionDeclaration() { var node = new FunctionDeclarationSyntax(); ParseExpected(SyntaxKind.FunctionKeyword); node.Identifier = ParseExpected(SyntaxKind.IdentifierToken); node.Parameters = ParseParameterList(); node.Body = ParseBlockStatement(); ParseOptional(SyntaxKind.SemicolonToken); return(node); }
private void BindFunctionDeclaration(FunctionDeclarationSyntax syntax) { string funcName = syntax.Identifier == null ? syntax.ImplicitLabel : syntax.Identifier.ToString(); var parameters = ImmutableArray.CreateBuilder <ParameterSymbol>(); var returnType = TypeDescriptionBinder.BindTypeDescription(syntax.ReturnType.TypeDescription); foreach (var parameter in syntax.Parameters) { string parameterName = parameter.IdentifierName.ToString(); var typeBind = TypeDescriptionBinder.BindTypeDescription(parameter.Definition.TypeDescription); int line = parameter.Definition.TypeDescription.Location.Line; int column = parameter.Definition.TypeDescription.Location.Column; var span = parameter.Definition.TypeDescription.Span; if (typeBind == null) { diagnostics.AddDiagnostic(Diagnostic.ReportInvalidParameterDefinition(line, column, span)); return; } if (typeBind.Equals(ValueTypeSymbol.Void)) { diagnostics.AddDiagnostic(Diagnostic.ReportVoidType(parameter.Definition.TypeDescription.Location, span)); return; } parameters.Add(new ParameterSymbol(parameterName, typeBind)); } if (returnType == null) { diagnostics.AddDiagnostic(Diagnostic.ReportInvalidReturnType(syntax.ReturnType.Location, syntax.ReturnType.Span)); return; } var functionSymbol = new FunctionSymbol(funcName, parameters.ToImmutable(), returnType, syntax); if (!scope.TryDefineFunction(functionSymbol)) { diagnostics.AddDiagnostic(Diagnostic.ReportCannotRedefineFunction(syntax.Identifier.Location, syntax.Identifier.Span)); } else { functions.Add(functionSymbol); } }
private static DataType ResolveReturnType( FunctionDeclarationSyntax function, ExpressionTypeResolver expressionResolver) { function.ReturnType.BeginFulfilling(); switch (function) { case NamedFunctionDeclarationSyntax namedFunction: return ResolveReturnType(function, namedFunction.ReturnTypeExpression, expressionResolver); case OperatorDeclarationSyntax @operator: return ResolveReturnType(function, @operator.ReturnTypeExpression, expressionResolver); case ConstructorDeclarationSyntax _: case InitializerDeclarationSyntax _: return function.ReturnType.Fulfill(function.DeclaringType.Metatype.Instance); default: throw NonExhaustiveMatchException.For(function); } }
private static void Check(FunctionDeclarationSyntax function, Diagnostics diagnostics) { if (function.Body == null) { return; } var bindingScope = EmptyBindingScope.Instance; foreach (var parameter in function.Parameters) { bindingScope = new VariableBindingScope(bindingScope, parameter); } var shadowChecker = new ShadowChecker(function, diagnostics); shadowChecker.VisitExpression(function.Body, bindingScope); }
public virtual void VisitFunctionDeclaration(FunctionDeclarationSyntax functionDeclaration, A args) { switch (functionDeclaration) { case NamedFunctionDeclarationSyntax namedFunction: VisitNamedFunctionDeclaration(namedFunction, args); break; case ConstructorDeclarationSyntax constructorDeclaration: VisitConstructorDeclaration(constructorDeclaration, args); break; case null: // Ignore break; default: throw NonExhaustiveMatchException.For(functionDeclaration); } }
private HashSet <Claim> ClaimsBeforeBlock( FunctionDeclarationSyntax function, BasicBlock block, Claims claims, HashSet <Claim> parameterClaims) { var claimsBeforeStatement = new HashSet <Claim>(); if (block == function.ControlFlow.EntryBlock) { claimsBeforeStatement.UnionWith(parameterClaims); } foreach (var predecessor in function.ControlFlow.Edges.To(block).Select(b => b.Terminator)) { claimsBeforeStatement.UnionWith(claims.After(predecessor)); } return(claimsBeforeStatement); }
private void Transform(FunctionDeclarationSyntax function, LiveVariables liveness) { var graph = function.ControlFlow; var builder = new ControlFlowGraphBuilder(graph.VariableDeclarations); foreach (var block in graph.BasicBlocks) { var blockBuilder = builder.NewBlock(); if (block.Number != blockBuilder.BlockNumber) { throw new Exception("New block number does not match old block number"); } foreach (var statement in block.ExpressionStatements) { // Copy the existing statement blockBuilder.Add(statement); var before = liveness.Before(statement); var after = liveness.After(statement); // dead = live before and not live after var dead = ((BitArray)after.Clone()).Not().And(before); foreach (var variableNumber in dead.TrueIndexes()) { var variable = graph.VariableDeclarations[variableNumber]; if (variable.Type is ObjectType type && type.IsOwned) { // The delete happens after the last statement var span = new TextSpan(statement.Span.End, 0); blockBuilder.AddDelete(new VariableReference(variableNumber, span), type, span); } } } // TODO what about if there is a variable delete after the terminator? blockBuilder.Add(block.Terminator); } function.ControlFlow = builder.Build(); }
private DataType ResolveSelfType(FunctionDeclarationSyntax function) { var declaringType = function.DeclaringType?.Metatype.Instance; if (declaringType == null) return null; switch (function) { case ConstructorDeclarationSyntax constructor: return constructor.SelfParameterType = ((ObjectType)declaringType).ForConstructor(); case NamedFunctionDeclarationSyntax namedFunction: var selfParameter = namedFunction.Parameters.OfType<SelfParameterSyntax>().SingleOrDefault(); if (selfParameter == null) return null; // Static function selfParameter.Type.BeginFulfilling(); // TODO deal with structs and ref self var selfType = (ObjectType)declaringType; if (selfParameter.MutableSelf) selfType = selfType.AsMutable(); return namedFunction.SelfParameterType = selfParameter.Type.Fulfill(selfType); case InitializerDeclarationSyntax _: throw new NotImplementedException(); default: throw NonExhaustiveMatchException.For(function); } }
public virtual void VisitFunctionDeclaration(FunctionDeclarationSyntax node) { DefaultVisit(node); }
public SourceFunctionDeclarationSymbol(FunctionDeclarationSyntax syntax, TypeSymbol returnType, Func<FunctionSymbol, IEnumerable<ParameterSymbol>> lazyParameters) : base(syntax.Name.Text, string.Empty, returnType, lazyParameters) { Syntax = syntax; }
public override void VisitFunctionDeclaration(FunctionDeclarationSyntax node) { ProcessItem(node.Name, node.GetDescription(false, false), node.GetTextSpanSafe(), NavigateToItemKind.Method, node.Parent, Glyph.Function); }
private BoundFunctionDeclaration BindFunctionDeclaration(FunctionDeclarationSyntax declaration, Symbol parent) { BindAttributes(declaration.Attributes); var boundReturnType = Bind(declaration.ReturnType, x => BindType(x, parent)); var functionSymbol = LocalSymbols.OfType<SourceFunctionSymbol>() .FirstOrDefault(x => SyntaxFacts.HaveMatchingSignatures( x.DefinitionSyntax as FunctionSyntax ?? x.DeclarationSyntaxes[0], declaration)); if (functionSymbol != null) { functionSymbol.DeclarationSyntaxes.Add(declaration); } else { functionSymbol = new SourceFunctionSymbol(declaration, parent, boundReturnType.TypeSymbol); AddSymbol(functionSymbol, declaration.Name.GetTextSpanSafe(), true); } if (declaration.Semantic != null) Bind(declaration.Semantic, BindVariableQualifier); var functionBinder = new Binder(_sharedBinderState, this); var boundParameters = BindParameters(declaration.ParameterList, functionBinder, functionSymbol); return new BoundFunctionDeclaration(functionSymbol, boundReturnType, boundParameters.ToImmutableArray()); }
public FunctionSymbol GetDeclaredSymbol(FunctionDeclarationSyntax syntax) { var result = _bindingResult.GetBoundNode(syntax) as BoundFunction; return result?.FunctionSymbol; }
public SourceMethodDeclarationSymbol(FunctionDeclarationSyntax syntax, TypeSymbol parent, TypeSymbol returnType, Func<MethodSymbol, IEnumerable<ParameterSymbol>> lazyParameters) : base(syntax.Name.Text, string.Empty, parent, returnType, lazyParameters) { }
internal SourceFunctionSymbol(FunctionDeclarationSyntax syntax, Symbol parent, TypeSymbol returnType, Func<InvocableSymbol, IEnumerable<ParameterSymbol>> lazyParameters = null) : base(syntax.Name.GetName(), string.Empty, parent, returnType, lazyParameters) { DeclarationSyntaxes = new List<FunctionDeclarationSyntax> { syntax }; }