예제 #1
0
        // Return an expression that yields an appropriate StructureTemplate
        // instance of type bstruct from our current context. stmpl is an expression
        // that returns an instance of the structure that we are bound to.
        // Typical usage:
        //
        //    UserType bstruct = BaseClass.ResolveUsedStructureType (trc, errors);
        //    ...
        //    ctor.BaseConstructorArgs.Add (ContextualStructRef (bstruct, stmpl));
        //
        // If bstruct is null, CDH.Null is returned -- so in the above case, we
        // will pass null to the base constructor, which is appropriate since it
        // needs no structure.

        public CodeExpression ContextualStructRef(UserType bstruct, CodeExpression stmpl)
        {
            if (bstruct == null)
            {
                return(CDH.Null);
            }

            if (bstruct.Equals(NS.ParamsType))
            {
                // Sweet! We are referring to ourselves.
                return(stmpl);
            }

            // We need some nontrivial different structure
            // type. Search our structure for a member that points to
            // a structure of that type.

            string foundparam = null;

            foreach (string param in Params.Parameters)
            {
                if (Params[param] != StructureParameterKind.Structure)
                {
                    continue;
                }

                if (!bstruct.Equals(Params.StructParamType(param)))
                {
                    continue;
                }

                // FIXME: better model that handles this.
                if (foundparam != null)
                {
                    throw ExHelp.App("Ambiguous structure chain: structure {0} contains two parameters " +
                                     "of type {1}: {2} and {3}", Params, bstruct, foundparam, param);
                }

                foundparam = param;
            }

            if (foundparam == null)
            {
                throw ExHelp.App("Missing structure chain: structure {0} needs a parameter of type {1} " +
                                 "to allow chaining of type {2} to its base class {3}", Params,
                                 bstruct, this, BaseClass);
            }

            return(new CodeFieldReferenceExpression(stmpl, foundparam));
        }
예제 #2
0
        public UserType Resolve(string tname, bool errors)
        {
            if (tname.IndexOf('.') >= 0)
            {
                return(driver.LookupFQN(tname, !errors));
            }

            // Not fully-qualified. Spelunk namespaces.

            UserType ut = null;

            //Console.WriteLine ("Trying to look up {0}", tname);

            foreach (string ns in AllUsings)
            {
                string   full = ns + "." + tname;
                UserType hit  = driver.LookupFQN(full, !errors);

                //Console.WriteLine ("       {0} -> {1}", full, hit);

                if (hit == null)
                {
                    continue;
                }

                if (errors && ut != null && !ut.Equals(hit))
                {
                    string s = String.Format("Ambiguous type name {0}: could be {1} " +
                                             "or {2}", tname, ut, hit);
                    throw new Exception(s);
                }

                ut = hit;
            }

            if (errors && ut == null)
            {
                throw new Exception("Could not resolve the type name " + tname);
            }

            return(ut);
        }
예제 #3
0
	// Return an expression that yields an appropriate StructureTemplate
	// instance of type bstruct from our current context. stmpl is an expression
	// that returns an instance of the structure that we are bound to.
	// Typical usage:
	//
	//    UserType bstruct = BaseClass.ResolveUsedStructureType (trc, errors);
	//    ...
	//    ctor.BaseConstructorArgs.Add (ContextualStructRef (bstruct, stmpl));
	//
	// If bstruct is null, CDH.Null is returned -- so in the above case, we
	// will pass null to the base constructor, which is appropriate since it
	// needs no structure.

	public CodeExpression ContextualStructRef (UserType bstruct, CodeExpression stmpl)
	{
	    if (bstruct == null)
		return CDH.Null;

	    if (bstruct.Equals (NS.ParamsType))
		// Sweet! We are referring to ourselves.
		return stmpl;

	    // We need some nontrivial different structure
	    // type. Search our structure for a member that points to
	    // a structure of that type.

	    string foundparam = null;

	    foreach (string param in Params.Parameters) {
		if (Params[param] != StructureParameterKind.Structure)
		    continue;

		if (!bstruct.Equals (Params.StructParamType (param)))
		    continue;

		// FIXME: better model that handles this.
		if (foundparam != null)
		    throw ExHelp.App ("Ambiguous structure chain: structure {0} contains two parameters " +
				      "of type {1}: {2} and {3}", Params, bstruct, foundparam, param);

		foundparam = param;
	    }

	    if (foundparam == null)
		throw ExHelp.App ("Missing structure chain: structure {0} needs a parameter of type {1} " +
				  "to allow chaining of type {2} to its base class {3}", Params,
				  bstruct, this, BaseClass);

	    return new CodeFieldReferenceExpression (stmpl, foundparam);
	}
예제 #4
0
        // Setup

        public bool Resolve(TypeResolveContext trc, bool errors)
        {
            // We need to resolve the rule as a template now, rather
            // than letting NameLookupContext do it, because NLC will
            // be operating with an undefined set of 'usings', and
            // probably won't be able to find the RTemplate associated
            // with the rule.

            if (Rule.ResolveExtension("RTemplate", trc, errors))
            {
                return(true);
            }

            // Now we need to check that, if we have a template that
            // uses a structure, that our provider can access such
            // a structure, so that the template can actually be
            // instantiated.
            //
            // FIXME: This code is exactly parallel to
            // StructureBoundItem.ContextualStructRef.

            UserType ttmpl = Rule.ResolveUsedStructureType(trc, errors);

            if (ttmpl == null)
            {
                // Great, it's doesn't use anything, so whatever.
                return(false);
            }

            // XXX shouldn't apply anymore -- unbound providers are now impossible.
            // Would they have ever been useful?
            //
            //if (prov.Structure == null) {
            //if (errors)
            //	    Console.Error.WriteLine ("Target {0} in provider {1} references rule {2} that " +
            //			     "is bound to structure {3}, but the provider is not " +
            //			     "bound to a structure and so can provide no context",
            //			     this, prov, Rule, ttmpl);
            //return true;
            //}

            if (ttmpl.Equals(prov.NS.ParamsType))
            {
                // It just depends on our containing structure. No problem.
                return(false);
            }

            foreach (string param in prov.Structure.Parameters)
            {
                if (prov.Structure[param] != StructureParameterKind.Structure)
                {
                    continue;
                }

                if (ttmpl.Equals(prov.Structure.StructParamType(param)))
                {
                    return(false);
                }
            }

            if (errors)
            {
                // WORST ERROR MESSAGE EVAR
                Console.Error.WriteLine("Target {0} in provider {1} references rule {2} that " +
                                        "is bound to structure {3}, but the provider's containing " +
                                        "structure {4} does not have an argument referencing that structure. " +
                                        "You probably need to add another parameter to the containing structure.",
                                        this, prov, Rule, ttmpl, prov.Structure);
            }
            return(true);
        }