Example #1
0
        bool TraceMetaPropertyLocation(MetaLocation loc, TraceData trace)
        {
            if (trace.VisitedLocations.Contains(loc))
            {
                return(true);
            }
            trace.VisitedLocations.Add(loc);

            var mp = GetProperty(loc);

            // Detect circular references (should not happen)
            foreach (var ploc in trace.Stack)
            {
                if (ploc == loc)
                {
                    return(false);
                }
            }

            if (mp.Definitions.Length == 0)
            {
                trace.Stack.Add(loc);
                trace.Errors.Add(new TraceError(mp.Source, ErrorCode.E2508, "Meta property " + mp.Name.Quote() + " has no definitions in " + Path.Quote(), null, trace.Stack.ToArray()));
                trace.Stack.RemoveLast();
                return(true);
            }

            trace.Stack.Add(loc);
            bool errorsFound = false;

            for (int i = 0; i < mp.Definitions.Length; i++)
            {
                var def = mp.Definitions[i];

                foreach (var req in def.Requirements)
                {
                    if (Path.FailedReqStatements.Contains(Tuple.Create(loc, def, req)))
                    {
                        errorsFound = true;

                        switch (req.Type)
                        {
                        case ReqStatementType.Object:
                        {
                            var ri = req as ReqObject;
                            trace.Errors.Add(new TraceError(req.Source, ErrorCode.E2500, "An instance of " + ri.ObjectType.Quote() + " is not available in " + Path.Quote(), req, trace.Stack.ToArray()));
                            break;
                        }

                        case ReqStatementType.File:
                        {
                            var rf = req as ReqFile;
                            trace.Errors.Add(new TraceError(req.Source, ErrorCode.E2501, "Required file " + rf.Filename.Quote() + " does not exist", req, trace.Stack.ToArray()));
                            break;
                        }

                        case ReqStatementType.Property:
                        {
                            var rmp  = req as ReqProperty;
                            var rloc = TryGetLocation(loc, rmp.PropertyName, rmp.Offset);

                            if (rloc == null)
                            {
                                trace.Errors.Add(new TraceError(req.Source, ErrorCode.E2502, "Meta property " + rmp.PropertyName.Quote() + " was not found in " + Path.Quote(), req, trace.Stack.ToArray()));
                                break;
                            }

                            var rdt = GetProperty(rloc.Value).ReturnType;
                            if (rmp.PropertyType != null && !rmp.PropertyType.Equals(rdt))
                            {
                                trace.Errors.Add(new TraceError(req.Source, ErrorCode.E2503, "Meta property " + rmp.PropertyName.Quote() + " did not have expected type " + rmp.PropertyType.Quote() + " in " + Path.Quote(), req, trace.Stack.ToArray()));
                                break;
                            }

                            if (rmp.Tag != null)
                            {
                                var rdef = GetValidDefinition(rloc.Value);
                                if (rdef != null && !rdef.Tags.Contains(rmp.Tag))
                                {
                                    trace.Errors.Add(new TraceError(req.Source, ErrorCode.E2504, "Meta property " + rmp.PropertyName.Quote() + " did not specify required tag " + rmp.Tag.Quote() + " in " + Path.Quote(), req, trace.Stack.ToArray()));
                                    break;
                                }
                            }

                            if (!TraceMetaPropertyLocation(rloc.Value, trace))
                            {
                                trace.Errors.Add(new TraceError(req.Source, ErrorCode.E2505, "Meta property " + rmp.PropertyName.Quote() + " could not be used in " + Path.Quote(), req, trace.Stack.ToArray()));
                                break;
                            }

                            break;
                        }

                        default:
                            trace.Errors.Add(new TraceError(req.Source, ErrorCode.E2506, "Unsupported req statement", req, trace.Stack.ToArray()));
                            break;
                        }

                        continue;
                    }
                }
            }

            trace.Stack.RemoveLast();
            return(errorsFound);
        }