a575963da9
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
289 lines
8.1 KiB
C#
289 lines
8.1 KiB
C#
// ProjectProperty.cs
|
|
//
|
|
// Author:
|
|
// Rolf Bjarne Kvinge (rolf@xamarin.com)
|
|
// Atsushi Enomoto (atsushi@xamarin.com)
|
|
//
|
|
// Copyright (C) 2011,2013 Xamarin Inc.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining
|
|
// a copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to
|
|
// permit persons to whom the Software is furnished to do so, subject to
|
|
// the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be
|
|
// included in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
//
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.Build.Construction;
|
|
using Microsoft.Build.Internal;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using System.IO;
|
|
|
|
namespace Microsoft.Build.Evaluation
|
|
{
|
|
// In .NET 4.0 MSDN says it is non-abstract, but some of those
|
|
// members are abstract and had been there since 4.0.
|
|
// I take this as doc bug, as non-abstract to abstract is a
|
|
// breaking change and I'd rather believe API designer's sanity.
|
|
public abstract class ProjectProperty
|
|
{
|
|
internal ProjectProperty (Project project) // hide default ctor
|
|
{
|
|
Project = project;
|
|
}
|
|
|
|
public string EvaluatedValue {
|
|
get { return InternalEvaluatedValue; }
|
|
}
|
|
|
|
public abstract bool IsEnvironmentProperty { get; }
|
|
|
|
public abstract bool IsGlobalProperty { get; }
|
|
|
|
[MonoTODO]
|
|
public abstract bool IsImported { get; }
|
|
|
|
public abstract bool IsReservedProperty { get; }
|
|
|
|
internal virtual bool IsWellKnownProperty {
|
|
get { return false; }
|
|
}
|
|
|
|
public abstract string Name { get; }
|
|
|
|
public abstract ProjectProperty Predecessor { get; }
|
|
|
|
public Project Project { get; private set; }
|
|
|
|
public abstract string UnevaluatedValue { get; set; }
|
|
|
|
public abstract ProjectPropertyElement Xml { get; }
|
|
|
|
internal abstract string InternalEvaluatedValue { get; }
|
|
}
|
|
|
|
// copy from MS.Build.Engine/BuildProperty.cs
|
|
internal enum PropertyType {
|
|
Reserved,
|
|
Global,
|
|
Normal,
|
|
Environment
|
|
}
|
|
|
|
internal abstract class BaseProjectProperty : ProjectProperty
|
|
{
|
|
public BaseProjectProperty (Project project, PropertyType propertyType, string name)
|
|
: base (project)
|
|
{
|
|
property_type = propertyType;
|
|
this.name = name;
|
|
predecessor = project.Properties.FirstOrDefault (p => p.Name.Equals (name, StringComparison.OrdinalIgnoreCase));
|
|
if (predecessor != null)
|
|
project.RemoveProperty (predecessor);
|
|
}
|
|
|
|
PropertyType property_type;
|
|
|
|
readonly string name;
|
|
public override string Name {
|
|
get { return name; }
|
|
}
|
|
|
|
public override bool IsEnvironmentProperty {
|
|
get { return property_type == PropertyType.Environment; }
|
|
}
|
|
public override bool IsGlobalProperty {
|
|
get { return property_type == PropertyType.Global; }
|
|
}
|
|
public override bool IsImported {
|
|
get { return false; }
|
|
}
|
|
public override bool IsReservedProperty {
|
|
get { return property_type == PropertyType.Reserved; }
|
|
}
|
|
readonly ProjectProperty predecessor;
|
|
public override ProjectProperty Predecessor {
|
|
get { return predecessor; }
|
|
}
|
|
}
|
|
|
|
internal abstract class ImmutableProjectProperty : BaseProjectProperty
|
|
{
|
|
public ImmutableProjectProperty (Project project, PropertyType propertyType, string name)
|
|
: base (project, propertyType, name)
|
|
{
|
|
}
|
|
|
|
internal override string InternalEvaluatedValue {
|
|
get { return UnevaluatedValue; }
|
|
}
|
|
}
|
|
|
|
internal abstract class MutableProjectProperty : BaseProjectProperty
|
|
{
|
|
public MutableProjectProperty (Project project, PropertyType propertyType, string name)
|
|
: base (project, propertyType, name)
|
|
{
|
|
}
|
|
|
|
string evaluated_value; // see UpdateEvaluatedValue().
|
|
internal void UpdateEvaluatedValue ()
|
|
{
|
|
evaluated_value = Project.ExpandString (UnevaluatedValue);
|
|
}
|
|
|
|
internal override string InternalEvaluatedValue {
|
|
get { return evaluated_value; }
|
|
}
|
|
}
|
|
|
|
internal class XmlProjectProperty : MutableProjectProperty
|
|
{
|
|
public XmlProjectProperty (Project project, ProjectPropertyElement xml, PropertyType propertyType, bool isImported)
|
|
: base (project, propertyType, xml.Name)
|
|
{
|
|
this.xml = xml;
|
|
this.is_imported = isImported;
|
|
UpdateEvaluatedValue ();
|
|
}
|
|
|
|
readonly ProjectPropertyElement xml;
|
|
readonly bool is_imported;
|
|
|
|
public override bool IsImported {
|
|
get { return is_imported; }
|
|
}
|
|
|
|
public override string UnevaluatedValue {
|
|
get { return xml.Value; }
|
|
set { xml.Value = value; }
|
|
}
|
|
|
|
public override ProjectPropertyElement Xml {
|
|
get { return xml; }
|
|
}
|
|
}
|
|
|
|
internal class EnvironmentProjectProperty : ImmutableProjectProperty
|
|
{
|
|
static string extensions_path;
|
|
internal static string DefaultExtensionsPath {
|
|
get {
|
|
if (extensions_path == null) {
|
|
// NOTE: code from mcs/tools/gacutil/driver.cs
|
|
PropertyInfo gac = typeof (System.Environment).GetProperty (
|
|
"GacPath", BindingFlags.Static | BindingFlags.NonPublic);
|
|
|
|
if (gac != null) {
|
|
MethodInfo get_gac = gac.GetGetMethod (true);
|
|
string gac_path = (string) get_gac.Invoke (null, null);
|
|
extensions_path = Path.GetFullPath (Path.Combine (
|
|
gac_path, Path.Combine ("..", "xbuild")));
|
|
}
|
|
}
|
|
return extensions_path;
|
|
}
|
|
}
|
|
|
|
public EnvironmentProjectProperty (Project project, string name, string value, bool wellknown = false)
|
|
: base (project, PropertyType.Environment, name)
|
|
{
|
|
this.value = value;
|
|
this.wellknown = wellknown;
|
|
}
|
|
|
|
readonly string value;
|
|
readonly bool wellknown;
|
|
|
|
internal override bool IsWellKnownProperty {
|
|
get { return wellknown; }
|
|
}
|
|
|
|
// It can override possible another environment vairable property BUT never gives Predecessor.
|
|
public override ProjectProperty Predecessor {
|
|
get { return null; }
|
|
}
|
|
|
|
public override string UnevaluatedValue {
|
|
get { return value; }
|
|
set { throw new InvalidOperationException (string.Format ("You cannot change value of environment property '{0}'.", Name)); }
|
|
}
|
|
public override ProjectPropertyElement Xml {
|
|
get { return null; }
|
|
}
|
|
}
|
|
|
|
internal class GlobalProjectProperty : ImmutableProjectProperty
|
|
{
|
|
public GlobalProjectProperty (Project project, string name, string value)
|
|
: base (project, PropertyType.Global, name)
|
|
{
|
|
this.value = value;
|
|
}
|
|
|
|
readonly string value;
|
|
|
|
public override string UnevaluatedValue {
|
|
get { return value; }
|
|
set { throw new InvalidOperationException (string.Format ("You cannot change value of global property '{0}'.", Name)); }
|
|
}
|
|
public override ProjectPropertyElement Xml {
|
|
get { return null; }
|
|
}
|
|
}
|
|
|
|
internal class ManuallyAddedProjectProperty : MutableProjectProperty
|
|
{
|
|
public ManuallyAddedProjectProperty (Project project, string name, string value)
|
|
: base (project, PropertyType.Normal, name)
|
|
{
|
|
this.UnevaluatedValue = value;
|
|
}
|
|
|
|
public override string UnevaluatedValue { get; set; }
|
|
|
|
public override ProjectPropertyElement Xml {
|
|
get { return null; }
|
|
}
|
|
}
|
|
|
|
internal class ReservedProjectProperty : ImmutableProjectProperty
|
|
{
|
|
public ReservedProjectProperty (Project project, string name, Func<string> value)
|
|
: base (project, PropertyType.Reserved, name)
|
|
{
|
|
this.value = value;
|
|
}
|
|
|
|
// make sure it does not give access to any possible attempted overrrides.
|
|
public override ProjectProperty Predecessor {
|
|
get { return null; }
|
|
}
|
|
|
|
readonly Func<string> value;
|
|
public override string UnevaluatedValue {
|
|
get { return value (); }
|
|
set { throw new InvalidOperationException (string.Format ("You cannot change value of reserved property '{0}'.", Name)); }
|
|
}
|
|
|
|
public override ProjectPropertyElement Xml {
|
|
get { return null; }
|
|
}
|
|
}
|
|
}
|