(spec, label, properties)
return [group]
Returns a PropertyGroup definition for the specified properties.

  Arguments:
    spec: The target project dict.
    label: An optional label for the PropertyGroup.
    properties: The dictionary to be converted.  The key is the name of the
        property.  The value is itself a dictionary; its key is the value and
        the value a list of condition for which this value is true.
Returns a PropertyGroup definition for the specified properties.
Returns a PropertyGroup definition for the specified properties .
def _GetMSBuildPropertyGroup(spec, label, properties):
    """Returns a PropertyGroup definition for the specified properties.

  Arguments:
    spec: The target project dict.
    label: An optional label for the PropertyGroup.
    properties: The dictionary to be converted.  The key is the name of the
        property.  The value is itself a dictionary; its key is the value and
        the value a list of condition for which this value is true.
  """
    group = ["PropertyGroup"]
    if label:
        group.append({"Label": label})
    num_configurations = len(spec["configurations"])

    def GetEdges(node):
        # Use a definition of edges such that user_of_variable -> used_varible.
        # This happens to be easier in this case, since a variable's
        # definition contains all variables it references in a single string.
        edges = set()
        for value in sorted(properties[node].keys()):
            # Add to edges all $(...) references to variables.
            #
            # Variable references that refer to names not in properties are excluded
            # These can exist for instance to refer built in definitions like
            # $(SolutionDir).
            #
            # Self references are ignored. Self reference is used in a few places to
            # append to the default value. I.e. PATH=$(PATH);other_path
            edges.update(
                {
                    v
                    for v in MSVS_VARIABLE_REFERENCE.findall(value)
                    if v in properties and v != node
                }
            )
        return edges

    properties_ordered = gyp.common.TopologicallySorted(properties.keys(), GetEdges)
    # Walk properties in the reverse of a topological sort on
    # user_of_variable -> used_variable as this ensures variables are
    # defined before they are used.
    # NOTE: reverse(topsort(DAG)) = topsort(reverse_edges(DAG))
    for name in reversed(properties_ordered):
        values = properties[name]
        for value, conditions in sorted(values.items()):
            if len(conditions) == num_configurations:
                # If the value is the same all configurations,
                # just add one unconditional entry.
                group.append([name, value])
            else:
                for condition in conditions:
                    group.append([name, {"Condition": condition}, value])
    return [group]
def _GetMSBuildPropertyGroup ( spec , label , properties ) : group = [ "PropertyGroup" ] if label : group . append ( { "Label" : label } ) num_configurations = len ( spec [ "configurations" ] ) def GetEdges ( node ) : # Use a definition of edges such that user_of_variable -> used_varible. # This happens to be easier in this case, since a variable's # definition contains all variables it references in a single string. edges = set ( ) for value in sorted ( properties [ node ] . keys ( ) ) : # Add to edges all $(...) references to variables. # # Variable references that refer to names not in properties are excluded # These can exist for instance to refer built in definitions like # $(SolutionDir). # # Self references are ignored. Self reference is used in a few places to # append to the default value. I.e. PATH=$(PATH);other_path edges . update ( { v for v in MSVS_VARIABLE_REFERENCE . findall ( value ) if v in properties and v != node } ) return edges properties_ordered = gyp . common . TopologicallySorted ( properties . keys ( ) , GetEdges ) # Walk properties in the reverse of a topological sort on # user_of_variable -> used_variable as this ensures variables are # defined before they are used. # NOTE: reverse(topsort(DAG)) = topsort(reverse_edges(DAG)) for name in reversed ( properties_ordered ) : values = properties [ name ] for value , conditions in sorted ( values . items ( ) ) : if len ( conditions ) == num_configurations : # If the value is the same all configurations, # just add one unconditional entry. group . append ( [ name , value ] ) else : for condition in conditions : group . append ( [ name , { "Condition" : condition } , value ] ) return [ group ]