/// <summary> /// Parse type string into an advance type declaration. /// </summary> /// <returns></returns> public AdvanceType GetAdvanceType() { AdvanceType at = new AdvanceType(); List <string> tokens = new List <string>(); StringBuilder b = new StringBuilder(); for (int i = 0; i < this.TypeString.Length; i++) { char c = this.TypeString[i]; if (c == ',' || c == '<' || c == '>') { tokens.Add(b.ToString().Trim()); tokens.Add(c.ToString()); b.Clear(); } else { b.Append(c); } } if (b.Length > 0) { tokens.Add(b.ToString()); } // uri[<uri[<...>][,uri[<...>]]>] at.TypeURI = new Uri(tokens[0]); if (tokens.Count > 3 && tokens[1].Equals("<")) { tokens.RemoveAt(0); int pointer = 2; ParseUriList(at, tokens, ref pointer); } return(at); }
/// <summary> /// Remove unused type variables /// </summary> public void RemoveUnusedTypeVariables() { HashSet <AdvanceType> visited = new HashSet <AdvanceType>(); HashSet <string> used = new HashSet <string>(); List <AdvanceType> queue = new List <AdvanceType>(); foreach (AdvanceCompositeBlockParameterDescription p in this.inputs.Values) { queue.Add(p.Type); } foreach (AdvanceCompositeBlockParameterDescription p in this.outputs.Values) { queue.Add(p.Type); } while (queue.Count > 0) { AdvanceType t = queue[0]; queue.RemoveAt(0); switch (t.Kind) { case TypeKind.VARIABLE_TYPE: used.Add(t.TypeVariableName); break; case TypeKind.PARAMETRIC_TYPE: if (!visited.Contains(t)) { visited.Add(t); queue.AddRange(t.TypeArguments); } break; } } // TODO remove unused }
/// <summary> /// Creates an {@code advance:type} type constructor XML /// </summary> /// <param name="type">type to convert to XML</param> /// <returns>Type Xml</returns> public static XmlNode CreateType(AdvanceType type) { XmlDocument doc = new XmlDocument(); XmlElement node = doc.CreateElement("type"); type.FillXmlElement(node); return(node); }
/// <summary> /// Creates a concrete (e.g., no type arguments or parametric type with the supplied base type and type arguments. /// </summary> /// <example>createType(COLLECTION, createType(STRING)</example> /// <param name="baseType">base type</param> /// <param name="types">type arguments.</param> /// <returns>created new type</returns> public static AdvanceType CreateType(Uri baseType, ICollection <AdvanceType> types) { AdvanceType t = new AdvanceType(); t.TypeURI = baseType; t.TypeArguments = new List <AdvanceType>(types); return(t); }
/// <summary> /// Creates a bounded variable type. /// </summary> /// <param name="name">variable name</param> /// <param name="upperBound">True if type bounds are the upper bounds, e.g., {@code T super B1, B2, B3}</param> /// <param name="bounds">type bounds</param> /// <returns></returns> public static AdvanceType CreateType(string name, bool upperBound, ICollection <AdvanceType> bounds) { AdvanceType t = CreateType(name); t.TypeVariable.IsUpperBound = upperBound; t.TypeVariable.Bounds.AddRange(bounds); return(t); }
/// <summary> /// Creates a bounded variable type. /// </summary> /// <param name="name">variable name</param> /// <param name="upperBound">True if type bounds are the upper bounds, e.g., {@code T super B1, B2, B3}</param> /// <param name="bound1">first bound</param> /// <param name="boundsRest">more bounds</param> /// <returns>created type</returns> public static AdvanceType CreateType(string name, bool upperBound, AdvanceType bound1, params AdvanceType[] boundsRest) { AdvanceType t = CreateType(name); t.TypeVariable.IsUpperBound = upperBound; t.TypeVariable.Bounds.Add(bound1); t.TypeVariable.Bounds.AddRange(boundsRest); return(t); }
/// <summary> /// Creates an unbounded variable type. /// </summary> /// <param name="name">variable name</param> /// <returns>created type</returns> public static AdvanceType CreateType(string name) { AdvanceType t = new AdvanceType(); t.TypeVariableName = name; t.TypeVariable = new AdvanceTypeVariable(); t.TypeVariable.Name = name; return(t); }
/// <summary> /// Link variable types in the parameter to the common types /// </summary> /// <param name="p"></param> protected void LinkParameterType(AdvanceCompositeBlockParameterDescription p) { switch (p.Type.Kind) { case TypeKind.VARIABLE_TYPE: AdvanceType t; if (this.sharedTypeVariables.TryGetValue(p.Type.TypeVariableName, out t)) { p.Type = t; } else { this.AddSharedTypeVariable(p.Type.TypeVariableName, p.Type); } break; case TypeKind.PARAMETRIC_TYPE: HashSet <AdvanceType> visited = new HashSet <AdvanceType>(); List <List <AdvanceType> > queue = new List <List <AdvanceType> >(); queue.Add(p.Type.TypeArguments); while (queue.Count > 0) { List <AdvanceType> args = queue[0]; queue.RemoveAt(0); for (int i = 0; i < args.Count; i++) { AdvanceType at = args[i]; switch (at.Kind) { case TypeKind.VARIABLE_TYPE: AdvanceType st; if (this.sharedTypeVariables.TryGetValue(at.TypeVariableName, out st)) { args[i] = st; } else { this.AddSharedTypeVariable(at.TypeVariableName, at); } break; case TypeKind.PARAMETRIC_TYPE: if (!visited.Contains(at)) { visited.Add(at); queue.Add(at.TypeArguments); } break; } } } break; } }
/** * Adds a shared type variable and type. * @param name the variable name * @param t the type, if null, an IllegalArgumentException is thrown */ protected void AddSharedTypeVariable(String name, AdvanceType t) { if (t == null) { this.ThrowException("Illegal argument AdvanceType " + name + " is null"); } if (t.TypeVariable == null) { t.TypeVariable = new AdvanceTypeVariable(); t.TypeVariable.Name = name; } this.TypeVariables.Add(name, t.TypeVariable); this.sharedTypeVariables.Add(name, t); }
/// <summary> /// Adds a type variable to this composite /// </summary> /// <param name="tv">type variable</param> /// <returns>true if it was new</returns> public bool AddTypeVariable(AdvanceTypeVariable tv) { if (this.TypeVariables.ContainsKey(tv.Name)) { return(false); } else { AdvanceType t = new AdvanceType(); t.TypeVariable = tv; t.TypeVariableName = tv.Name; this.AddSharedTypeVariable(tv.Name, t); return(true); } }
/// <summary> /// Creates new instance of this type /// </summary> /// <returns>new instance of this type declaration</returns> public AdvanceType Copy() { AdvanceType result = new AdvanceType(); result.Id = this.Id; result.TypeVariableName = this.TypeVariableName; result.TypeURI = this.TypeURI; result.Type = Type; if (this.TypeVariable != null) { result.TypeVariable = this.TypeVariable.Copy(); } foreach (AdvanceType ta in this.TypeArguments) { result.TypeArguments.Add(ta.Copy()); } return(result); }
/// <summary> /// Parses the token sequence into a list of type arguments. /// </summary> /// <param name="argsFor">parent type</param> /// <param name="tokens"> list of remaining tokens</param> /// <param name="pointer">pointer in tokenlist</param> private static void ParseUriList(AdvanceType argsFor, List <string> tokens, ref int pointer) { while (pointer < tokens.Count) { AdvanceType at = new AdvanceType(); argsFor.TypeArguments.Add(at); at.TypeURI = new Uri(tokens[pointer++]); if (tokens.Count > pointer) { switch (tokens[pointer++]) { case "<": ParseUriList(at, tokens, ref pointer); break; case ">": return; default: break; } } } }
/// <summary> /// Establish a direct link between type variables referencing other type variables. /// </summary> protected void LinkTypeVariables() { HashSet <AdvanceType> visited = new HashSet <AdvanceType>(); List <List <AdvanceType> > queue = new List <List <AdvanceType> >(); foreach (AdvanceTypeVariable tv in this.TypeVariables.Values) { queue.Add(tv.Bounds); } while (queue.Count > 0) { List <AdvanceType> bounds = queue[0]; queue.RemoveAt(0); for (int i = 0; i < bounds.Count; i++) { AdvanceType t = bounds[i]; switch (t.Kind) { case TypeKind.VARIABLE_TYPE: AdvanceType st; if (this.sharedTypeVariables.TryGetValue(t.TypeVariableName, out st)) { bounds[i] = st; } else { this.ThrowMissingTypeVariableException(null, t.TypeVariableName); } break; case TypeKind.PARAMETRIC_TYPE: if (!visited.Contains(t)) { visited.Add(t); queue.Add(t.TypeArguments); } break; } } } }
/// <summary> /// Fill object data from xml node /// </summary> /// <param name="source"></param> protected override void LoadFromXmlNode(XmlNode source) { this.Id = GetAttribute(source, "id"); this.DisplayName = GetAttribute(source, "displayname", null); this.Documentation = GetUriAttribute(source, "documentation"); this.Required = GetBoolAttribute(source, "required", true); XmlNode defNode = GetChildNode(source, "default"); if (defNode != null) { XmlNodeList children = GetChildren(defNode, "*"); if (children.Count == 1) { this.DefaultValue = children[0]; } else { Log.LogString("Missing default value: " + source.Name); } } this.Varargs = GetBoolAttribute(source, "varargs", false); this.Type = XmlReadWrite.CreateFromXml <AdvanceType>(source); }
/// <summary> /// Fill object data from xml node /// </summary> /// <param name="source"></param> protected override void LoadFromXmlNode(XmlNode source) { this.Id = GetAttribute(source, "id"); this.DisplayName = GetAttribute(source, "displayname", null); this.Documentation = GetUriAttribute(source, "documentation"); this.Tooltip = GetAttribute(source, "tooltip", null); this.Keywords = GetListAttribute(source, "keywords"); this.Category = GetAttribute(source, "category", null); List <AdvanceType> typeRefs = new List <AdvanceType>(); Dictionary <String, AdvanceType> sharedTypes = new Dictionary <string, AdvanceType>(); foreach (XmlNode tp in GetChildren(source, "type-variable")) { AdvanceTypeVariable bpd = CreateFromXml <AdvanceTypeVariable>(tp); if (this.TypeVariables.ContainsKey(bpd.Name)) { this.ThrowDuplicatedIdentifierException(tp, this.Id); } typeRefs.AddRange(bpd.Bounds); AdvanceType st = new AdvanceType(); st.TypeVariableName = bpd.Name; st.TypeVariable = bpd; sharedTypes.Add(bpd.Name, st); } // throw new MissingTypeVariableException(root.getXPath(), b.typeVariableName); while (typeRefs.Count > 0) { AdvanceType tvb = typeRefs[0]; typeRefs.RemoveAt(0); if (tvb.TypeVariableName != null) { if (!this.TypeVariables.TryGetValue(tvb.TypeVariableName, out tvb.TypeVariable)) { this.ThrowMissingTypeVariableException(source, tvb.TypeVariableName); } } else { typeRefs.AddRange(tvb.TypeArguments); } } List <AdvanceType> typeParams = new List <AdvanceType>(); this.HasVarargs = false; foreach (XmlNode inode in GetChildren(source, "input")) { AdvanceBlockParameterDescription bpd = CreateFromXml <AdvanceBlockParameterDescription>(inode); this.HasVarargs |= bpd.Varargs; if (this.Inputs.ContainsKey(bpd.Id)) { this.ThrowDuplicatedIdentifierException(inode, bpd.Id); } else { this.Inputs.Add(bpd.Id, bpd); } // use the shared type object instead of an individual type if (sharedTypes.ContainsKey(bpd.Type.TypeVariableName)) { bpd.Type = sharedTypes[bpd.Type.TypeVariableName]; } typeParams.Add(bpd.Type); } foreach (XmlNode onode in GetChildren(source, "output")) { AdvanceBlockParameterDescription bpd = CreateFromXml <AdvanceBlockParameterDescription>(onode); if (this.Outputs.ContainsKey(bpd.Id)) { this.ThrowDuplicatedIdentifierException(onode, bpd.Id); } else { this.Inputs.Add(bpd.Id, bpd); } // use the shared type object instead of an individual type if (sharedTypes.ContainsKey(bpd.Type.TypeVariableName)) { bpd.Type = sharedTypes[bpd.Type.TypeVariableName]; } typeParams.Add(bpd.Type); } while (typeParams.Count > 0) { AdvanceType at = typeParams[0]; typeParams.RemoveAt(0); if (at.Kind == TypeKind.VARIABLE_TYPE && at.TypeVariable == null) { this.TypeVariables.TryGetValue(at.TypeVariableName, out at.TypeVariable); } else if (at.Kind == TypeKind.PARAMETRIC_TYPE) { for (int i = 0; i < at.TypeArguments.Count; i++) { AdvanceType ta = at.TypeArguments[i]; if (ta.Kind == TypeKind.VARIABLE_TYPE) { AdvanceType sv; if (!sharedTypes.TryGetValue(ta.TypeVariableName, out sv)) { this.ThrowMissingTypeVariableException(source, ta.TypeVariableName); } at.TypeArguments[i] = sv; } } typeParams.AddRange(at.TypeArguments); } } }