protected override void VisitTypedIdentifierSyntax(TypedIdentifierSyntax pNode) { base.VisitTypedIdentifierSyntax(pNode); if (_locals.IsVariableDefinedInScope(pNode.Value)) { CompilerErrors.IdentifierAlreadyDeclared(pNode, pNode.Span); } else { _locals.DefineVariableInScope(pNode.Value, LocalDefinition.Create(false, pNode.Type)); } }
protected override void VisitDeclarationSyntax(DeclarationSyntax pNode) { Visit(pNode.Value); var isTuple = pNode.Value.Type.IsTuple; for (int i = 0; i < pNode.Variables.Count; i++) { if (!SyntaxHelper.IsDiscard(pNode.Variables[i])) { if (_locals.IsVariableDefinedInScope(pNode.Variables[i].Value)) { CompilerErrors.IdentifierAlreadyDeclared(pNode.Variables[i], pNode.Span); } else { //We do not allow variables to have the same names as types //This makes it easier to check for "static" method/fields if (SmallTypeCache.IsTypeDefined(pNode.Variables[i].Value)) { CompilerErrors.ValueDefinedAsType(pNode.Variables[i], pNode.Variables[i].Span); } else { //For tuple types we set the individual variables to the tuple field type... not the tuple itself var t = isTuple ? pNode.Value.Type.GetFieldType(i) : pNode.Value.Type; //Report expression errors and change the type to Undefined so we don't get further no expression errors if (pNode.Value.Type == SmallTypeCache.NoValue) { CompilerErrors.ExpressionNoValue(pNode.Value.Span); t = SmallTypeCache.Undefined; } pNode.Variables[i].SetType(t); _locals.DefineVariableInScope(pNode.Variables[i].Value, LocalDefinition.Create(pNode.IsConst, pNode.Variables[i].Type)); } } } } //Check that we are declaring the proper number of variables if (isTuple && pNode.Value.Type.GetFieldCount() != pNode.Variables.Count) { CompilerErrors.DeclarationCountMismatch(pNode.Value.Type.GetFieldCount(), pNode.Variables.Count, pNode.Span); } }