Exemplo n.º 1
0
        // Check given symbol type against everything that's of a higher priority in the ordered SymbolType enum (above).
        // When the given symbol type level is reached, we early-out / return.
        public void CheckForNamingCollisions(Parsed.Object obj, Identifier identifier, SymbolType symbolType, string typeNameOverride = null)
        {
            string typeNameToPrint = typeNameOverride ?? obj.typeName;

            if (IsReservedKeyword(identifier?.name))
            {
                obj.Error("'" + name + "' cannot be used for the name of a " + typeNameToPrint.ToLower() + " because it's a reserved keyword");
                return;
            }

            if (FunctionCall.IsBuiltIn(identifier?.name))
            {
                obj.Error("'" + name + "' cannot be used for the name of a " + typeNameToPrint.ToLower() + " because it's a built in function");
                return;
            }

            // Top level knots
            FlowBase knotOrFunction = ContentWithNameAtLevel(identifier?.name, FlowLevel.Knot) as FlowBase;

            if (knotOrFunction && (knotOrFunction != obj || symbolType == SymbolType.Arg))
            {
                NameConflictError(obj, identifier?.name, knotOrFunction, typeNameToPrint);
                return;
            }

            if (symbolType < SymbolType.List)
            {
                return;
            }

            // Lists
            foreach (var namedListDef in _listDefs)
            {
                var listDefName = namedListDef.Key;
                var listDef     = namedListDef.Value;
                if (identifier?.name == listDefName && obj != listDef && listDef.variableAssignment != obj)
                {
                    NameConflictError(obj, identifier?.name, listDef, typeNameToPrint);
                }

                // We don't check for conflicts between individual elements in
                // different lists because they are namespaced.
                if (!(obj is ListElementDefinition))
                {
                    foreach (var item in listDef.itemDefinitions)
                    {
                        if (identifier?.name == item.name)
                        {
                            NameConflictError(obj, identifier?.name, item, typeNameToPrint);
                        }
                    }
                }
            }

            // Don't check for VAR->VAR conflicts because that's handled separately
            // (necessary since checking looks up in a dictionary)
            if (symbolType <= SymbolType.Var)
            {
                return;
            }

            // Global variable collision
            VariableAssignment varDecl = null;

            if (variableDeclarations.TryGetValue(identifier?.name, out varDecl))
            {
                if (varDecl != obj && varDecl.isGlobalDeclaration && varDecl.listDefinition == null)
                {
                    NameConflictError(obj, identifier?.name, varDecl, typeNameToPrint);
                }
            }

            if (symbolType < SymbolType.SubFlowAndWeave)
            {
                return;
            }

            // Stitches, Choices and Gathers
            var path          = new Path(identifier);
            var targetContent = path.ResolveFromContext(obj);

            if (targetContent && targetContent != obj)
            {
                NameConflictError(obj, identifier?.name, targetContent, typeNameToPrint);
                return;
            }

            if (symbolType < SymbolType.Arg)
            {
                return;
            }

            // Arguments to the current flow
            if (symbolType != SymbolType.Arg)
            {
                FlowBase flow = obj as FlowBase;
                if (flow == null)
                {
                    flow = obj.ClosestFlowBase();
                }
                if (flow && flow.hasParameters)
                {
                    foreach (var arg in flow.arguments)
                    {
                        if (arg.identifier?.name == identifier?.name)
                        {
                            obj.Error(typeNameToPrint + " '" + name + "': Name has already been used for a argument to " + flow.identifier + " on " + flow.debugMetadata);
                            return;
                        }
                    }
                }
            }
        }
Exemplo n.º 2
0
 void NameConflictError(Parsed.Object obj, string name, Parsed.Object existingObj, string typeNameToPrint)
 {
     obj.Error(typeNameToPrint + " '" + name + "': name has already been used for a " + existingObj.typeName.ToLower() + " on " + existingObj.debugMetadata);
 }