Imported Upstream version 3.8.0

Former-commit-id: 6a76a29bd07d86e57c6c8da45c65ed5447d38a61
This commit is contained in:
Jo Shields
2014-09-04 09:07:35 +01:00
parent a575963da9
commit fe777c5c82
1062 changed files with 12460 additions and 5983 deletions

View File

@@ -182,7 +182,7 @@ namespace Microsoft.Build.BuildEngine {
e = new ConditionFactorExpression (token);
} else if (token.Type == TokenType.Item || token.Type == TokenType.Property
|| token.Type == TokenType.Metadata) {
e = ParseReferenceExpression (token.Value);
e = ParseReferenceExpression (token.Value [0]);
} else if (token.Type == TokenType.Not) {
e = ParseNotExpression ();
} else
@@ -224,21 +224,33 @@ namespace Microsoft.Build.BuildEngine {
}
//@prefix: @ or $
ConditionExpression ParseReferenceExpression (string prefix)
ConditionExpression ParseReferenceExpression (char prefix)
{
StringBuilder sb = new StringBuilder ();
string ref_type = prefix [0] == '$' ? "a property" : "an item list";
int token_pos = tokenizer.Token.Position;
string ref_type = prefix == '$' ? "a property" : "an item list";
IsAtToken (TokenType.LeftParen, String.Format (
"Expected {0} at position {1} in condition \"{2}\". Missing opening parantheses after the '{3}'.",
ref_type, token_pos, conditionStr, prefix));
tokenizer.GetNextToken ();
if (prefix == '$') {
//
// Tjhe scan should consider quoted parenthesis but it breaks on .net as well
// we are bug compatible
//
tokenizer.ScanForClosingParens ();
} else {
tokenizer.GetNextToken ();
}
if (tokenizer.IsEOF ())
throw new ExpressionParseException ("Missing closing parenthesis in condition " + conditionStr);
StringBuilder sb = new StringBuilder ();
sb.AppendFormat ("{0}({1}", prefix, tokenizer.Token.Value);
tokenizer.GetNextToken ();
if (prefix == "@" && tokenizer.Token.Type == TokenType.Transform) {
if (prefix == '@' && tokenizer.Token.Type == TokenType.Transform) {
tokenizer.GetNextToken ();
sb.AppendFormat ("->'{0}'", tokenizer.Token.Value);
@@ -250,9 +262,7 @@ namespace Microsoft.Build.BuildEngine {
}
}
IsAtToken (TokenType.RightParen, String.Format (
"Expected {0} at position {1} in condition \"{2}\". Missing closing parantheses'.",
ref_type, token_pos, conditionStr, prefix));
IsAtToken (TokenType.RightParen, "Missing closing parenthesis in condition " + conditionStr);
tokenizer.GetNextToken ();
sb.Append (")");

View File

@@ -257,6 +257,29 @@ namespace Microsoft.Build.BuildEngine {
} else
throw new ExpressionParseException (String.Format ("Invalid token: {0}", ch));
}
public void ScanForClosingParens (int parensCounter = 1)
{
tokenPosition = position;
int start = position;
int ch;
while ((ch = ReadChar ()) >= 0) {
switch (ch) {
case ')':
if (--parensCounter == 0) {
--position;
token = new Token (inputString.Substring (start, position - start), TokenType.String, tokenPosition);
return;
}
break;
case '(':
++parensCounter;
break;
}
}
token = new Token (null, TokenType.EOF, tokenPosition);
}
public int TokenPosition {
get { return tokenPosition; }

View File

@@ -55,6 +55,14 @@ namespace Microsoft.Build.BuildEngine {
internal class Expression {
enum TokenKind
{
OpenParens,
CloseParens,
Dot,
End
}
ExpressionCollection expressionCollection;
static Regex item_regex;
@@ -232,6 +240,7 @@ namespace Microsoft.Build.BuildEngine {
pos += 2;
int start = pos;
int end = 0;
bool requires_closing_parens = true;
var ch = text [pos];
if ((ch == 'r' || ch == 'R') && text.Substring (pos + 1).StartsWith ("egistry:", StringComparison.OrdinalIgnoreCase)) {
@@ -273,6 +282,7 @@ namespace Microsoft.Build.BuildEngine {
// Simple property reference $(Foo)
//
phase.Add (new PropertyReference (name));
requires_closing_parens = false;
} else {
end = 0;
}
@@ -287,6 +297,14 @@ namespace Microsoft.Build.BuildEngine {
pos = end;
}
if (requires_closing_parens) {
end = text.IndexOf (')', pos);
if (end < 0)
end = 0;
else
pos = end + 1;
}
}
end = text.IndexOf ("$(", pos, StringComparison.Ordinal);
@@ -493,70 +511,71 @@ namespace Microsoft.Build.BuildEngine {
static MemberInvocationReference ParseInvocation (string text, ref int p, Type type, IReference instance)
{
var open_parens = text.IndexOf ('(', p);
string name;
int end;
List<string> args;
TokenKind token;
MemberInvocationReference mir = null;
//
// Is it method or property
//
if (open_parens > 0) {
name = text.Substring (p, open_parens - p);
while (true) {
int prev = p;
token = ScanName (text, ref p);
var name = text.Substring (prev, p - prev).TrimEnd ();
//
// It can be instance method on static property
//
if (name.IndexOf ('.') > 0) {
var names = name.Split ('.');
int i;
for (i = 0; i < names.Length - 1; ++i) {
instance = new MemberInvocationReference (type, names [i]) {
Instance = instance
};
}
switch (token) {
case TokenKind.Dot:
case TokenKind.OpenParens:
break;
case TokenKind.CloseParens:
return new MemberInvocationReference (type, name) {
Instance = instance
};
type = null;
name = names [i];
}
++open_parens;
args = ParseArguments (text, ref open_parens);
end = text.IndexOf (')', open_parens);
} else {
end = text.IndexOf (')', p);
if (end < 0)
throw new InvalidProjectFileException (string.Format ("Invalid static method invocation syntax '{0}'", text.Substring (p)));
case TokenKind.End:
if (mir == null || name.Length != 0)
throw new InvalidProjectFileException (string.Format ("Invalid static method invocation syntax '{0}'", text.Substring (p)));
name = text.Substring (p, end - p);
//
// It can be instance member on static property
//
if (name.IndexOf ('.') > 0) {
var names = name.Split ('.');
int i;
for (i = 0; i < names.Length - 1; ++i) {
instance = new MemberInvocationReference (type, names [i]) {
Instance = instance
};
}
type = null;
name = names [i];
return mir;
default:
throw new NotImplementedException ();
}
args = null;
instance = mir = new MemberInvocationReference (type, name) {
Instance = instance
};
if (type != null) {
if (!IsMethodAllowed (type, name))
throw new InvalidProjectFileException (string.Format ("The function '{0}' on type '{1}' has not been enabled for execution", name, type.FullName));
type = null;
}
if (token == TokenKind.OpenParens) {
++p;
mir.Arguments = ParseArguments (text, ref p);
}
if (p < text.Length && text [p] == '.') {
++p;
continue;
}
return mir;
}
}
static TokenKind ScanName (string text, ref int p)
{
for (; p < text.Length; ++p) {
switch (text [p]) {
case '(':
return TokenKind.OpenParens;
case '.':
return TokenKind.Dot;
case ')':
return TokenKind.CloseParens;
}
}
name = name.TrimEnd ();
if (!IsMethodAllowed (type, name))
throw new InvalidProjectFileException (string.Format ("The function '{0}' on type '{1}' has not been enabled for execution", name, type.FullName));
p = end + 1;
return new MemberInvocationReference (type, name) {
Arguments = args,
Instance = instance
};
return TokenKind.End;
}
ArrayList SplitMetadata (string text)

View File

@@ -274,7 +274,11 @@ namespace Microsoft.Build.BuildEngine {
continue;
if (!Directory.Exists (extn_path)) {
project.ParentEngine.LogMessage (MessageImportance.Low, "Extension path '{0}' not found, ignoring.", extn_path);
if (extn_path != DotConfigExtensionsPath)
project.ParentEngine.LogMessage (
MessageImportance.Low,
"Extension path '{0}' not found, ignoring.",
extn_path);
continue;
}

View File

@@ -63,10 +63,16 @@ namespace Microsoft.Build.BuildEngine
{
var flags = BindingFlags.IgnoreCase | BindingFlags.Public;
object target;
string member_name = name;
if (Instance == null) {
target = null;
flags |= BindingFlags.Static;
if (string.Equals (member_name, "new", StringComparison.OrdinalIgnoreCase)) {
member_name = ConstructorInfo.ConstructorName;
flags |= BindingFlags.CreateInstance | BindingFlags.Instance;
} else {
flags |= BindingFlags.Static;
}
} else {
var mir = Instance as MemberInvocationReference;
if (mir != null) {
@@ -91,14 +97,14 @@ namespace Microsoft.Build.BuildEngine
} else {
flags |= BindingFlags.InvokeMethod;
ExpandArguments (project, options);
args = PrepareMethodArguments (flags);
args = PrepareMethodArguments (member_name, flags);
if (args == null)
throw new InvalidProjectFileException (string.Format ("Method '{0}({1})' arguments cannot be evaluated'", name, string.Join (", ", Arguments.ToArray ())));
}
object value;
try {
value = type.InvokeMember (name, flags, null, target, args, CultureInfo.InvariantCulture);
value = type.InvokeMember (member_name, flags, null, target, args, CultureInfo.InvariantCulture);
} catch (MissingFieldException) {
//
// It can be field/constant instead of a property
@@ -106,7 +112,7 @@ namespace Microsoft.Build.BuildEngine
if (args == null && Instance == null) {
flags &= ~BindingFlags.GetProperty;
flags |= BindingFlags.GetField;
value = type.InvokeMember (name, flags, null, null, null, CultureInfo.InvariantCulture);
value = type.InvokeMember (member_name, flags, null, null, null, CultureInfo.InvariantCulture);
} else {
throw;
}
@@ -132,9 +138,9 @@ namespace Microsoft.Build.BuildEngine
}
}
object[] PrepareMethodArguments (BindingFlags flags)
object[] PrepareMethodArguments (string name, BindingFlags flags)
{
var candidates = type.GetMember (name, MemberTypes.Method, flags);
var candidates = type.GetMember (name, MemberTypes.Method | MemberTypes.Constructor, flags);
object[] args = null;
ParameterInfo[] best = null;
foreach (MethodBase candidate in candidates) {