private void InstantiateProperties(string path, Dictionary <string, string> namespaces, StatementNode node, int token, ObjectInstanceType objectType, object item) { // Process the name=value properties on the item. for (int i = token; i < node.Statement.Tokens.Count; ++i) { // These were already processed by GetObjectNamespaces(). if (node.Statement.Tokens[i].TokenType == ParserTokenType.NamespacePrefixDeclaration || node.Statement.Tokens[i].TokenType == ParserTokenType.NamespaceDeclaration) { continue; } string typeNamespace = null; // If a namespace is present then we must be working with an attached property. if (node.Statement.Tokens[i].TokenType == ParserTokenType.NamespacePrefix) { string prefix = node.Statement.Tokens[i].Value; ++i; typeNamespace = namespaces[prefix]; } if (node.Statement.Tokens[i].TokenType == ParserTokenType.AttachedPropertyObject) { string attachedPropertyName = node.Statement.Tokens[i].Value; ++i; if (node.Statement.Tokens[i].TokenType != ParserTokenType.PropertyName) { this.OnMessage(new CompilerMessageEventArgs(CompilerMessage.ExpectedToken("property name", node.Statement.Tokens[i].Value), path, node.Statement.Range)); break; } string name = node.Statement.Tokens[i].Value; ++i; if (node.Statement.Tokens[i].TokenType != ParserTokenType.Equals) { this.OnMessage(new CompilerMessageEventArgs(CompilerMessage.ExpectedToken("equals", node.Statement.Tokens[i].Value), path, node.Statement.Range)); break; } ++i; if (node.Statement.Tokens[i].TokenType != ParserTokenType.PropertyValue) { this.OnMessage(new CompilerMessageEventArgs(CompilerMessage.ExpectedToken("property value", node.Statement.Tokens[i].Value), path, node.Statement.Range)); break; } string value = node.Statement.Tokens[i].Value; if (String.IsNullOrEmpty(typeNamespace)) { this.OnMessage(new CompilerMessageEventArgs(CompilerMessage.AttachedPropertyRequiresNamespace(attachedPropertyName), path, node.Statement.Range)); break; } AttachedPropertyObjectType apt; if (!this.TypeCache.TryGetAttachedPropertyType(typeNamespace, attachedPropertyName, out apt)) { this.OnMessage(new CompilerMessageEventArgs(CompilerMessage.UnknownAttachedProperty(typeNamespace, attachedPropertyName), path, node.Statement.Range)); } else // set the property value. { AttachedPropertySetterType setter; if (!apt.TryGetPropertySetter(name, out setter)) { this.OnMessage(new CompilerMessageEventArgs(CompilerMessage.UnknownAttachedPropertyValue(typeNamespace, attachedPropertyName, name), path, node.Statement.Range)); } else if (!setter.TrySetValue(item, value)) { this.OnMessage(new CompilerMessageEventArgs(CompilerMessage.CannotAssignAttachedPropertyVale(typeNamespace, attachedPropertyName, name, value), path, node.Statement.Range)); } } } else // must be a simple property assignment. { // Get the property name (if there isn't one, we must want the "default" property). string name = null; if (node.Statement.Tokens[i].TokenType == ParserTokenType.PropertyName) { name = node.Statement.Tokens[i].Value; ++i; if (node.Statement.Tokens[i].TokenType != ParserTokenType.Equals) { this.OnMessage(new CompilerMessageEventArgs(CompilerMessage.ExpectedToken("=", node.Statement.Tokens[i].Value), path, node.Statement.Range)); break; } ++i; } // Set the property value. if (node.Statement.Tokens[i].TokenType != ParserTokenType.PropertyValue) { this.OnMessage(new CompilerMessageEventArgs(CompilerMessage.ExpectedToken("property value", node.Statement.Tokens[i].Value), path, node.Statement.Range)); } string value = node.Statement.Tokens[i].Value; if (!String.IsNullOrEmpty(typeNamespace)) { this.OnMessage(new CompilerMessageEventArgs(CompilerMessage.PropertyCannotSpecifyNamespace(name, typeNamespace), path, node.Statement.Range)); break; } PropertyInstanceType propertyType; if (!objectType.TryGetProperty(name, out propertyType)) { this.OnMessage(new CompilerMessageEventArgs(CompilerMessage.UnknownProperty(name), path, node.Statement.Range)); } else if (!propertyType.TrySetValue(item, value)) { this.OnMessage(new CompilerMessageEventArgs(CompilerMessage.CannotAssignPropertyValue(name, value), path, node.Statement.Range)); } } } }