private bool DiscoverTypes(string pType, TextSpan pSpan) { //If a node doesn't exist the type hasn't been declared if (!_discoveryGraph.NodeExists(pType)) { CompilerErrors.UndeclaredType(pType, pSpan); return(false); } //If we have been here already we have a circular reference in our types //ie Type1 has a field of Type2; Type2 has a field of Type1 var item = _discoveryGraph.GetNode(pType); if (item.Permanent) { return(true); } if (item.Temporary) { CompilerErrors.CircularReference(item.Node, item.Node.Span); return(false); } item.Temporary = true; for (int i = 0; i < item.Node.Fields.Count; i++) { var type = item.Node.Fields[i].TypeNode; var nt = type.Value; if (nt.IndexOf('[') > -1) { nt = nt.Substring(0, nt.IndexOf('[')); } //Only look through user defined types which should be undefined at this point if (!item.Node.TypeParameters.Contains(nt) && !_unit.IsTypeDefined(type.Namespace, nt) && !DiscoverTypes(nt, type.Span)) { return(false); } } item.Permanent = true; return(AddType(item.Node)); }
protected override void VisitIdentifierSyntax(IdentifierSyntax pNode) { if (CurrentType != null || !_unit.IsTypeDefined(Namespace, pNode.Value)) { //Normal identifier, continue as usual if (!IsVariableDefined(pNode.Value, out SmallType type)) { if (CurrentType == null) { //Generate a slightly different error message if we are in a struct //This can happen if we forget self if (Struct != null) { CompilerErrors.IdentifierNotDeclaredSelf(pNode, pNode.Span); } else { CompilerErrors.IdentifierNotDeclared(pNode, pNode.Span); } } else { CompilerErrors.IdentifierNotDeclared(CurrentType, pNode, pNode.Span); } } else { pNode.SetType(type); } } else { //Shared or enum value var result = _unit.FromString(Namespace, pNode.Value, out SmallType t); switch (result) { case Compiler.FindResult.Found: pNode.SetType(t); break; case Compiler.FindResult.IncorrectScope: CompilerErrors.TypeNotInScope(pNode.Value, pNode.Span); break; case Compiler.FindResult.NotFound: CompilerErrors.UndeclaredType(pNode.Value, pNode.Span); break; } } }
private bool IsConstant(string pNamespace, SyntaxNode pNode) { if (pNode.SyntaxType == SyntaxType.BooleanLiteral || pNode.SyntaxType == SyntaxType.NumericLiteral || pNode.SyntaxType == SyntaxType.StringLiteral) { return(true); } else if (pNode.SyntaxType == SyntaxType.MemberAccess) { var ma = (MemberAccessSyntax)pNode; if (ma.Value.SyntaxType == SyntaxType.MemberAccess) { return(IsConstant(ma.Identifier.Value, ma.Value)); } if (_cache.IsTypeDefined(pNamespace, ma.Identifier.Value) && _cache.FromString(pNamespace, ma.Identifier.Value, out SmallType t) == Compiler.FindResult.Found) { return(t.IsEnum); } } return(false); }