use an ExpressionInterpolationExpression to give a better message when the expression evaluates to void

#region license
// Copyright (c) 2003, 2004, 2005 Rodrigo B. de Oliveira (rbo@acm.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//     * Neither the name of Rodrigo B. de Oliveira nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion

namespace Boo.Lang.PatternMatching.Impl

import Boo.Lang.Compiler
import Boo.Lang.Compiler.Ast

internal class MatchExpansion:

	node as MacroStatement
	expression as Expression
	context as CompilerContext
	[getter(Value)] final value as Statement

	def constructor(context as CompilerContext, node as MacroStatement):
		self.context = context
		self.node = node
		self.expression = node.Arguments[0]
		self.value = Expand(NewTemp(expression))

	def Expand(matchValue as Expression):

		topLevel = expanded = ExpandCase(matchValue, caseListFor(node)[0])
		for case in caseListFor(node)[1:]:
			caseExpansion = ExpandCase(matchValue, case)
			expanded.FalseBlock = caseExpansion.ToBlock()
			expanded = caseExpansion
		expanded.FalseBlock = ExpandOtherwise(matchValue)

		return [|
			block:
				$matchValue = $expression
				$topLevel
		|].Body

	def ExpandOtherwise(matchValue as Expression):
		otherwise as MacroStatement = node["otherwise"]
		if otherwise is null: return DefaultOtherwise(matchValue)
		return ExpandOtherwise(otherwise)

	def ExpandOtherwise(node as MacroStatement):
		assert 0 == len(node.Arguments)
		return node.Body

	def DefaultOtherwise(matchValue as Expression):

		errorMessage = ExpressionInterpolationExpression(matchValue.LexicalInfo)
		errorMessage.Expressions.Add(StringLiteralExpression.Lift("`$(expression.ToCodeString())` failed to match `"))
		errorMessage.Expressions.Add(matchValue.CloneNode())
		errorMessage.Expressions.Add(StringLiteralExpression.Lift("`"))

		matchError = [| raise MatchError($errorMessage) |]
		matchError.LexicalInfo = node.LexicalInfo

		return matchError.ToBlock()

	def ExpandCase(matchValue as Expression, node as MacroStatement):
		assert 1 == len(node.Arguments)
		pattern = node.Arguments[0]
		condition = ExpandPattern(matchValue, pattern)
		return [|
			if $condition:
				$(node.Body)
		|]

	def ExpandPattern(matchValue as Expression, pattern as Expression) as Expression:
		return PatternExpander().Expand(matchValue, pattern)

#region license
// Copyright (c) 2003, 2004, 2005 Rodrigo B. de Oliveira (rbo@acm.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//     * Neither the name of Rodrigo B. de Oliveira nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion

namespace Boo.Lang.PatternMatching.Impl

import Boo.Lang.Compiler
import Boo.Lang.Compiler.Ast

internal class MatchExpansion:

	node as MacroStatement
	expression as Expression
	context as CompilerContext
	[getter(Value)] final value as Statement

	def constructor(context as CompilerContext, node as MacroStatement):
		self.context = context
		self.node = node
		self.expression = node.Arguments[0]
		self.value = Expand(NewTemp(expression))

	def Expand(matchValue as Expression):

		topLevel = expanded = ExpandCase(matchValue, caseListFor(node)[0])
		for case in caseListFor(node)[1:]:
			caseExpansion = ExpandCase(matchValue, case)
			expanded.FalseBlock = caseExpansion.ToBlock()
			expanded = caseExpansion
		expanded.FalseBlock = ExpandOtherwise(matchValue)

		return [|
			block:
				$matchValue = $expression
				$topLevel
		|].Body

	def ExpandOtherwise(matchValue as Expression):
		otherwise as MacroStatement = node["otherwise"]
		if otherwise is null: return DefaultOtherwise(matchValue)
		return ExpandOtherwise(otherwise)

	def ExpandOtherwise(node as MacroStatement):
		assert 0 == len(node.Arguments)
		return node.Body

	def DefaultOtherwise(matchValue as Expression):
		errMsg = "`${expression.ToCodeString()}` failed to match `{0}`"
		matchError = [| raise MatchError(string.Format($errMsg, $matchValue)) |]
		matchError.LexicalInfo = node.LexicalInfo
		return matchError.ToBlock()

	def ExpandCase(matchValue as Expression, node as MacroStatement):
		assert 1 == len(node.Arguments)
		pattern = node.Arguments[0]
		condition = ExpandPattern(matchValue, pattern)
		return [|
			if $condition:
				$(node.Body)
		|]

	def ExpandPattern(matchValue as Expression, pattern as Expression) as Expression:
		return PatternExpander().Expand(matchValue, pattern)


fix nowarn|warnaserror behavior to match csc task

git-svn-id: fcce7d6ce0ac15bf24f68871b5145d46fc068279@3296 2c1201b4-01cd-e047-a400-b836ae1fbc61

#region license
// Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//     * Neither the name of Rodrigo B. de Oliveira nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion

namespace Boo.NAnt

import System
import System.IO
import System.Text
import System.Text.RegularExpressions
import NAnt.Core.Attributes
import NAnt.Core.Types
import NAnt.DotNet.Types

import NAnt.DotNet.Tasks
import System.Reflection

[TaskName('booc')]
public class BoocTask(CompilerBase):
	#region Private Instance Fields
	private _debugOutput as DebugOutput = DebugOutput.Enable
	private _exe as string

	private _useruntime = true //keep true for mono compatibility (don't call booc.exe directly)
	private _noconfig = false
	private _nostdlib = false
	private _wsa = false
	private _ducky = false
	private _checked = true
	private _defineSymbols as string = null
	private _embed = FileSet()
	private _pipeline as string
	private _strict = false

	#endregion Private Instance Fields
	#region Private Static Fields
	private static _classNameRegex = Regex('^((?<comment>/\\*.*?(\\*/|$))|[\\s\\.\\{]+|class\\s+(?<class>\\w+)|(?<keyword>\\w+))*')

	private static _namespaceRegex = Regex('^((?<comment>/\\*.*?(\\*/|$))|[\\s\\.\\{]+|namespace\\s+(?<namespace>(\\w+(\\.\\w+)*)+)|(?<keyword>\\w+))*')

	#endregion Private Static Fields

	def constructor():
		SupportsKeyFile = true
		SupportsKeyContainer = true
		SupportsPackageReferences = true

	[FrameworkConfigurable("exename")]
	[TaskAttribute('exename')]
	public override ExeName as string:
		get:
			return _exe
		set:
			_exe = value

	[FrameworkConfigurable("useruntimeengine")]
	[TaskAttribute('useruntimeengine')]
	override UseRuntimeEngine as bool:
		get:
			return _useruntime
		set:
			_useruntime = value

	#region Public Instance Properties

	[TaskAttribute('debug')]
	public DebugOutput as DebugOutput:
		get:
			return _debugOutput
		set:
			_debugOutput = value

	[TaskAttribute('pipeline')]
	public Pipeline:
		get:
			return _pipeline
		set:
			_pipeline = value

	public Debug as bool:
		get:
			return (DebugOutput != DebugOutput.None)
		set:
			if value:
				DebugOutput = DebugOutput.Enable
			else:
				DebugOutput = DebugOutput.None

	[FrameworkConfigurable('noconfig')]
	[TaskAttribute('noconfig')]
	[BooleanValidator]
	public NoConfig as bool:
		get:
			return _noconfig
		set:
			_noconfig = value

	[FrameworkConfigurable('nostdlib')]
	[TaskAttribute('nostdlib')]
	[BooleanValidator]
	public NoStdLib as bool:
		get:
			return _nostdlib
		set:
			_nostdlib = value

	[TaskAttribute('wsa')]
	[BooleanValidator]
	public WhiteSpaceAgnostic as bool:
		get:
			return _wsa
		set:
			_wsa = value

	[TaskAttribute('ducky')]
	[BooleanValidator]
	public Ducky as bool:
		get:
			return _ducky
		set:
			_ducky = value

	[TaskAttribute('checked')]
	[BooleanValidator]
	public Checked as bool:
		get:
			return _checked
		set:
			_checked = value

	[TaskAttribute('define')]
	public DefineSymbols as string:
		get:
			return _defineSymbols
		set:
			_defineSymbols = value

	[BuildElement("embed")]
	Embed:
		get:
			return _embed
		set:
			_embed = value

	[TaskAttribute('strict')]
	[BooleanValidator]
	public Strict as bool:
		get:
			return _strict
		set:
			_strict = value

	override public SupportsNoWarnList as bool:
		get:
			return true
		set:
			pass

	override public SupportsWarnAsErrorList as bool:
		get:
			return true
		set:
			pass

	private def FindBooc() as string:
		path as string
		dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
		if Project.TargetFramework:
			frameworkname = Project.TargetFramework.Name
			path = Path.Combine(Path.Combine(dir, frameworkname), "booc.exe")
			if File.Exists(path):
				return path
			//treat mono-1.0==net-1.1 and mono-##==net-##
			frameworkname = frameworkname.Replace("mono-1.0","net-1.1").Replace("mono-","net-")
			path = Path.Combine(Path.Combine(dir, frameworkname), "booc.exe")
			if File.Exists(path):
				return path
		path = Path.Combine(dir, "booc.exe")
		if File.Exists(path):
			return path
		_useruntime = false
		return "booc" //try booc in PATH

	protected override def ExecuteTask():
		if not ExeName or ExeName == string.Empty:
			ExeName = FindBooc()
		super()

	#endregion Public Instance Properties
	#region Override implementation of CompilerBase
	protected override def WriteOptions(writer as TextWriter):
		if DebugOutput != DebugOutput.None:
			WriteOption(writer, 'debug')
		else:
			WriteOption(writer, 'debug-')
		if NoConfig and (not Arguments.Contains('-noconfig')):
			Arguments.Add(Argument('-noconfig'))
		if NoStdLib:
			WriteOption(writer, "nostdlib")
		if Verbose:
			WriteOption(writer, "vv")
		if WhiteSpaceAgnostic:
			WriteOption(writer, "wsa")
		if Ducky:
			WriteOption(writer, "ducky")
		if not Checked:
			WriteOption(writer, "checked-")
		if Strict:
			WriteOption(writer, "strict")
		if DefineSymbols is not null:
			WriteOption(writer, "define", DefineSymbols)
		if Pipeline:
			WriteOption(writer, "p", _pipeline)
		for embed in _embed.FileNames:
			WriteOption(writer, "embedres", embed)

	protected override def WriteOption(writer as TextWriter, name as string):
		writer.WriteLine("-{0}", name)

	protected override def WriteOption(writer as TextWriter, name as string, value as string):
		if " " in value and not IsQuoted(value):
			writer.WriteLine("-{0}:\"{1}\"", name, value)
		else:
			writer.WriteLine("-{0}:{1}", name, value)

	protected override def WriteNoWarnList(writer as TextWriter):
		if SuppressWarnings.Count > 0:
			sb = StringBuilder()
			for warning as CompilerWarning in SuppressWarnings:
				if warning.IfDefined and not warning.UnlessDefined:
					sb.Append(warning.Number)
					WriteOption(writer, "nowarn", sb.ToString())

	protected override def WriteWarningsAsError(writer as TextWriter):
		if WarnAsError:
			WriteOption(writer, "warnaserror")
			return
		if WarningAsError.Includes.Count > 0:
			sb = StringBuilder()
			for warning as CompilerWarning in WarningAsError.Includes:
				if warning.IfDefined and not warning.UnlessDefined:
					sb.Append(warning.Number)
			WriteOption(writer, "warnaserror", sb.ToString())

	def IsQuoted(value as string):
		return value.StartsWith("\"") and value.EndsWith("\"")

	public Extension as string:
		get:
			return 'boo'

	protected ClassNameRegex as Regex:
		get:
			return _classNameRegex

	protected NamespaceRegex as Regex:
		get:
			return _namespaceRegex
	#endregion Override implementation of CompilerBase

#region license
// Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//     * Neither the name of Rodrigo B. de Oliveira nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion

namespace Boo.NAnt

import System
import System.IO
import System.Text
import System.Text.RegularExpressions
import NAnt.Core.Attributes
import NAnt.Core.Types
import NAnt.DotNet.Types

import NAnt.DotNet.Tasks
import System.Reflection

[TaskName('booc')]
public class BoocTask(CompilerBase):
	#region Private Instance Fields
	private _debugOutput as DebugOutput = DebugOutput.Enable
	private _exe as string

	private _useruntime = true //keep true for mono compatibility (don't call booc.exe directly)
	private _noconfig = false
	private _nostdlib = false
	private _wsa = false
	private _ducky = false
	private _checked = true
	private _defineSymbols as string = null
	private _noWarn as string = null
	private _warnAsError as string = null
	private _embed = FileSet()
	private _pipeline as string
	private _strict = false

	#endregion Private Instance Fields
	#region Private Static Fields
	private static _classNameRegex = Regex('^((?<comment>/\\*.*?(\\*/|$))|[\\s\\.\\{]+|class\\s+(?<class>\\w+)|(?<keyword>\\w+))*')

	private static _namespaceRegex = Regex('^((?<comment>/\\*.*?(\\*/|$))|[\\s\\.\\{]+|namespace\\s+(?<namespace>(\\w+(\\.\\w+)*)+)|(?<keyword>\\w+))*')

	#endregion Private Static Fields

	def constructor():
		SupportsKeyFile = true
		SupportsKeyContainer = true
		SupportsPackageReferences = true

	[FrameworkConfigurable("exename")]
	[TaskAttribute('exename')]
	public override ExeName as string:
		get:
			return _exe
		set:
			_exe = value

	[FrameworkConfigurable("useruntimeengine")]
	[TaskAttribute('useruntimeengine')]
	override UseRuntimeEngine as bool:
		get:
			return _useruntime
		set:
			_useruntime = value

	#region Public Instance Properties

	[TaskAttribute('debug')]
	public DebugOutput as DebugOutput:
		get:
			return _debugOutput
		set:
			_debugOutput = value

	[TaskAttribute('pipeline')]
	public Pipeline:
		get:
			return _pipeline
		set:
			_pipeline = value

	public Debug as bool:
		get:
			return (DebugOutput != DebugOutput.None)
		set:
			if value:
				DebugOutput = DebugOutput.Enable
			else:
				DebugOutput = DebugOutput.None

	[FrameworkConfigurable('noconfig')]
	[TaskAttribute('noconfig')]
	[BooleanValidator]
	public NoConfig as bool:
		get:
			return _noconfig
		set:
			_noconfig = value

	[FrameworkConfigurable('nostdlib')]
	[TaskAttribute('nostdlib')]
	[BooleanValidator]
	public NoStdLib as bool:
		get:
			return _nostdlib
		set:
			_nostdlib = value

	[TaskAttribute('wsa')]
	[BooleanValidator]
	public WhiteSpaceAgnostic as bool:
		get:
			return _wsa
		set:
			_wsa = value

	[TaskAttribute('ducky')]
	[BooleanValidator]
	public Ducky as bool:
		get:
			return _ducky
		set:
			_ducky = value

	[TaskAttribute('checked')]
	[BooleanValidator]
	public Checked as bool:
		get:
			return _checked
		set:
			_checked = value

	[TaskAttribute('define')]
	public DefineSymbols as string:
		get:
			return _defineSymbols
		set:
			_defineSymbols = value

	[BuildElement("embed")]
	Embed:
		get:
			return _embed
		set:
			_embed = value

	[TaskAttribute('nowarn')]
	public NoWarn as string:
		get:
			return _noWarn
		set:
			_noWarn = value

	[TaskAttribute('strict')]
	[BooleanValidator]
	public Strict as bool:
		get:
			return _strict
		set:
			_strict = value

	override public SupportsNoWarnList as bool:
		get:
			return true
		set:
			pass

	override public SupportsWarnAsErrorList as bool:
		get:
			return true
		set:
			pass

	private def FindBooc() as string:
		path as string
		dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
		if Project.TargetFramework:
			frameworkname = Project.TargetFramework.Name
			path = Path.Combine(Path.Combine(dir, frameworkname), "booc.exe")
			if File.Exists(path):
				return path
			//treat mono-1.0==net-1.1 and mono-##==net-##
			frameworkname = frameworkname.Replace("mono-1.0","net-1.1").Replace("mono-","net-")
			path = Path.Combine(Path.Combine(dir, frameworkname), "booc.exe")
			if File.Exists(path):
				return path
		path = Path.Combine(dir, "booc.exe")
		if File.Exists(path):
			return path
		_useruntime = false
		return "booc" //try booc in PATH

	protected override def ExecuteTask():
		if not ExeName or ExeName == string.Empty:
			ExeName = FindBooc()
		super()

	#endregion Public Instance Properties
	#region Override implementation of CompilerBase
	protected override def WriteOptions(writer as TextWriter):
		if DebugOutput != DebugOutput.None:
			WriteOption(writer, 'debug')
		else:
			WriteOption(writer, 'debug-')
		if NoConfig and (not Arguments.Contains('-noconfig')):
			Arguments.Add(Argument('-noconfig'))
		if NoStdLib:
			WriteOption(writer, "nostdlib")
		if Verbose:
			WriteOption(writer, "vv")
		if WhiteSpaceAgnostic:
			WriteOption(writer, "wsa")
		if Ducky:
			WriteOption(writer, "ducky")
		if not Checked:
			WriteOption(writer, "checked-")
		if Strict:
			WriteOption(writer, "strict")
		if DefineSymbols is not null:
			WriteOption(writer, "define", DefineSymbols)
		if Pipeline:
			WriteOption(writer, "p", _pipeline)
		for embed in _embed.FileNames:
			WriteOption(writer, "embedres", embed)

	protected override def WriteOption(writer as TextWriter, name as string):
		writer.WriteLine("-{0}", name)

	protected override def WriteOption(writer as TextWriter, name as string, value as string):
		if " " in value and not IsQuoted(value):
			writer.WriteLine("-{0}:\"{1}\"", name, value)
		else:
			writer.WriteLine("-{0}:{1}", name, value)

	protected override def WriteNoWarnList(writer as TextWriter):
		if not NoWarn:
			return
		if NoWarn == "true" and SuppressWarnings.Count == 0:
			WriteOption(writer, "nowarn")
			return
		sb = StringBuilder()
		for warning as CompilerWarning in SuppressWarnings:
			if warning.IfDefined and not warning.UnlessDefined:
				sb.Append(warning.Number)
				WriteOption(writer, "nowarn", sb.ToString())

	protected override def WriteWarningsAsError(writer as TextWriter):
		if not WarnAsError:
			return
		if WarningAsError.Includes.Count == 0:
			WriteOption(writer, "warnaserror")
			return
		sb = StringBuilder()
		for warning as CompilerWarning in WarningAsError.Includes:
			if warning.IfDefined and not warning.UnlessDefined:
				sb.Append(warning.Number)
		WriteOption(writer, "warnaserror", sb.ToString())

	def IsQuoted(value as string):
		return value.StartsWith("\"") and value.EndsWith("\"")

	public Extension as string:
		get:
			return 'boo'

	protected ClassNameRegex as Regex:
		get:
			return _classNameRegex

	protected NamespaceRegex as Regex:
		get:
			return _namespaceRegex
	#endregion Override implementation of CompilerBase


resolve types only once

resolve types only once

namespace Boojay.Compilation.TypeSystem

import Boo.Lang.Compiler
import Boo.Lang.Compiler.TypeSystem
import Boo.Lang.Useful.Attributes

class JarMethod(IMethod):
	_declaringType as IType
	_name as string
	_descriptor as string
	_access as int

	def constructor(declaringType as IType, name as string, descriptor as string, access as int):
		_declaringType = declaringType
		_name = name
		_descriptor = descriptor
		_access = access

	EntityType:
		get: return EntityType.Method

	Name:
		get: return _name

	FullName:
		get: return "${_declaringType.FullName}.${_name}"

	DeclaringType:
		get: return _declaringType

	IsPublic:
		get: return (_access & org.objectweb.asm.Opcodes.ACC_PUBLIC) != 0

	IsProtected:
		get: return (_access & org.objectweb.asm.Opcodes.ACC_PROTECTED) != 0

	IsStatic:
		get: return (_access & org.objectweb.asm.Opcodes.ACC_STATIC) != 0

	AcceptVarArgs:
		get: return (_access & org.objectweb.asm.Opcodes.ACC_VARARGS) != 0

	IsVirtual:
		get: return (_access & org.objectweb.asm.Opcodes.ACC_FINAL) == 0

	IsExtension:
		get: return false // FIXME

	IsSpecialName:
		get: return false // FIXME

	Type:
		get: return self.CallableType

	CallableType:
		get: return my(TypeSystemServices).GetCallableType(self)

	GenericInfo:
		get: return null

	ConstructedInfo:
		get: return null

	IsDuckTyped:
		get: return false

	ReturnType as IType:
		[once] get:
			asmType = org.objectweb.asm.Type.getReturnType(_descriptor)
			return AsmTypeResolver.ResolveTypeName(asmType)

	[once]
	def GetParameters():
		asmParamTypes = org.objectweb.asm.Type.getArgumentTypes(_descriptor)
		result = (Parameter(self, "arg${i}", param) for i, param in enumerate(asmParamTypes))
		return array(IParameter, result)

class Parameter(IParameter):
	_declaringType as IMethod
	_name as string
	_type as org.objectweb.asm.Type

	def constructor(declaringType as IMethod, name as string, type as org.objectweb.asm.Type):
		_declaringType = declaringType
		_name = name
		_type = type
		Boojay.Compilation.log("${FullName} as ${_type} AS ${Type}")

	Type as IType:
		[once] get: return AsmTypeResolver.ResolveTypeName(_type)

	EntityType:
		get: return EntityType.Parameter

	Name:
		get: return _name

	FullName:
		get: return "${_declaringType.FullName}.${_name}"

	IsByRef:
		get: return false

namespace Boojay.Compilation.TypeSystem

import Boo.Lang.Compiler
import Boo.Lang.Compiler.TypeSystem

class JarMethod(IMethod):
	_declaringType as IType
	_name as string
	_descriptor as string
	_access as int

	def constructor(declaringType as IType, name as string, descriptor as string, access as int):
		_declaringType = declaringType
		_name = name
		_descriptor = descriptor
		_access = access

	EntityType:
		get: return EntityType.Method

	Name:
		get: return _name

	FullName:
		get: return "${_declaringType.FullName}.${_name}"

	DeclaringType:
		get: return _declaringType

	IsPublic:
		get: return (_access & org.objectweb.asm.Opcodes.ACC_PUBLIC) != 0

	IsProtected:
		get: return (_access & org.objectweb.asm.Opcodes.ACC_PROTECTED) != 0

	IsStatic:
		get: return (_access & org.objectweb.asm.Opcodes.ACC_STATIC) != 0

	AcceptVarArgs:
		get: return (_access & org.objectweb.asm.Opcodes.ACC_VARARGS) != 0

	IsVirtual:
		get: return (_access & org.objectweb.asm.Opcodes.ACC_FINAL) == 0

	IsExtension:
		get: return false // FIXME

	IsSpecialName:
		get: return false // FIXME

	Type:
		get: return self.CallableType

	CallableType:
		get: return my(TypeSystemServices).GetCallableType(self)

	GenericInfo:
		get: return null

	ConstructedInfo:
		get: return null

	IsDuckTyped:
		get: return false

	ReturnType as IType:
		get:
			asmType = org.objectweb.asm.Type.getReturnType(_descriptor)
			return AsmTypeResolver.ResolveTypeName(asmType)

	def GetParameters():
		asmParamTypes = org.objectweb.asm.Type.getArgumentTypes(_descriptor)
		result = (Parameter(self, "arg${i}", param) for i, param in enumerate(asmParamTypes))
		return array(IParameter, result)

class Parameter(IParameter):
	_declaringType as IMethod
	_name as string
	_type as org.objectweb.asm.Type

	def constructor(declaringType as IMethod, name as string, type as org.objectweb.asm.Type):
		_declaringType = declaringType
		_name = name
		_type = type

		Boojay.Compilation.log("${FullName} as ${_type} AS ${Type}")

	Type as IType:
		get: return AsmTypeResolver.ResolveTypeName(_type)

	EntityType:
		get: return EntityType.Parameter

	Name:
		get: return _name

	FullName:
		get: return "${_declaringType.FullName}.${_name}"

	IsByRef:
		get: return false


show the names of the modified files when leaving the application

git-svn-id: c3b8989232654601f1acea7403f771adaaa44a81@470 2c1201b4-01cd-e047-a400-b836ae1fbc61

namespace BooExplorer

import System
import System.IO
import System.ComponentModel
import System.Windows.Forms
import System.Drawing
import WeifenLuo.WinFormsUI

class MainForm(Form):

	_dockManager as DockManager
	_status as StatusBar
	_statusPanel1 as StatusBarPanel
	_timer as Timer

	[getter(DocumentOutline)]
	_documentOutline = BooExplorer.DocumentOutline()

	[getter(TaskList)]
	_taskList = BooExplorer.TaskList()

	_argv as (string)

	_menuItemClose as MenuItem
	_menuItemSave as MenuItem
	_menuItemSaveAs as MenuItem

	def constructor(argv as (string)):
		_argv = argv
		_dockManager = DockManager(Dock: DockStyle.Fill,
						ActiveAutoHideContent: null,
						TabIndex: 1,
						ActiveDocumentChanged: _dockManager_ActiveDocumentChanged,
						ContentAdded: _dockManager_ContentAdded,
						ContentRemoved: _dockManager_ContentRemoved)

		_statusPanel1 = StatusBarPanel(AutoSize: StatusBarPanelAutoSize.Contents)

		_status = StatusBar(ShowPanels: true, TabIndex: 2)
		_status.Panels.Add(_statusPanel1)

		SuspendLayout()

		self.Size = System.Drawing.Size(800, 600)
		self.Menu = CreateMainMenu()
		self.Text = "Boo Explorer"
		self.IsMdiContainer = true

		Controls.AddRange((
					_dockManager,
					_status))
		ResumeLayout(false)

		_timer = Timer(Tick: _timer_Tick, Interval: 50ms.TotalMilliseconds)
		_timer.Enabled = true

	private def CreateMainMenu():

		menu = MainMenu()
		file = MenuItem(Text: "&File", MergeOrder: 0)
		file.MenuItems.Add(MenuItem(Text: "&Open...",
									Click: _menuItemOpen_Click,
									Shortcut: Shortcut.CtrlO))
		file.MenuItems.Add(MenuItem(Text: "&New",
									Click: _menuItemNew_Click,
									Shortcut: Shortcut.CtrlN))

		file.MenuItems.Add(MenuItem("-"))

		file.MenuItems.Add(_menuItemSave = MenuItem(Text: "&Save",
									Enabled: false,
									Click: _menuItemSave_Click,
									Shortcut: Shortcut.CtrlS))
		file.MenuItems.Add(_menuItemSaveAs = MenuItem(Text: "S&ave as...",
									Enabled: false,
									Click: _menuItemSaveAs_Click))

		file.MenuItems.Add(_menuItemClose = MenuItem(Text: "&Close",
									Click: _menuItemClose_Click,
									Shortcut: Shortcut.CtrlW,
									Enabled: false))

		file.MenuItems.Add(MenuItem("-"))
		file.MenuItems.Add(MenuItem(Text: "E&xit",
									Shortcut: Shortcut.CtrlQ,
									Click: _menuItemExit_Click))

		view = MenuItem(Text: "&View", MergeOrder: 4)
		view.MenuItems.AddRange(
			(
				MenuItem(Text: "Document Outline",
						Click: _menuItemDocumentOutline_Click,
						Shortcut: Shortcut.CtrlShiftD),
				MenuItem(Text: "Task List",
						Click: _menuItemTaskList_Click,
						Shortcut: Shortcut.CtrlShiftT)
			))

		menu.MenuItems.AddRange((file, view))
		return menu

	def _timer_Tick(sender, args as EventArgs):

		_timer.Enabled = false
		for fname in _argv:
			try:
				OpenDocument(fname)
			except x:
				print(x)
		ShowDocumentOutline()

	StatusText as string:
		set:
			_statusPanel1.Text = value

	def ShowDocumentOutline():
		_documentOutline.Show(_dockManager)

	def NewDocument():
		editor = BooEditor(self)
		editor.Show(_dockManager)
		editor.TextArea.Focus()

	def OpenDocument([required] filename as string):
		filename = Path.GetFullPath(filename)
		content = FindEditor(filename)
		if content is null:
			editor = BooEditor(self)
			editor.Open(filename)
			editor.Show(_dockManager)
			editor.TextArea.Focus()
		else:
			content.Show(_dockManager)
			content.TextArea.Focus()

	def _dockManager_ActiveDocumentChanged(sender, args as EventArgs):
		document = _dockManager.ActiveDocument
		editor = document as BooEditor
		_documentOutline.ActiveDocument = editor
		_menuItemClose.Enabled = document is not null
		_menuItemSaveAs.Enabled = _menuItemSave.Enabled = document is not null

	def _dockManager_ContentAdded(sender, args as ContentEventArgs):
		pass

	def _dockManager_ContentRemoved(sender, args as ContentEventArgs):
		pass

	def _menuItemSaveAs_Click(sender, args as EventArgs):
		cast(BooEditor, _dockManager.ActiveDocument).SaveAs()

	def _menuItemSave_Click(sender, args as EventArgs):
		cast(BooEditor, _dockManager.ActiveDocument).Save()

	def _menuItemExit_Click(sender, args as EventArgs):
		self.Close()

	def _menuItemClose_Click(sender, args as EventArgs):
		_dockManager.ActiveDocument.Close()

	def _menuItemDocumentOutline_Click(sender, args as EventArgs):
		ShowDocumentOutline()

	def _menuItemTaskList_Click(sender, args as EventArgs):
		_taskList.Show(_dockManager)

	def _menuItemOpen_Click(sender, args as EventArgs):
		dlg = OpenFileDialog(
					Filter: "boo files (*.boo)|*.boo|All files (*.*)|*.*",
					Multiselect: true)
		if DialogResult.OK == dlg.ShowDialog(self):
			for fname in dlg.FileNames:
				OpenDocument(fname)

	def _menuItemNew_Click(sender, args as EventArgs):
		NewDocument()

	override protected def OnClosing(args as CancelEventArgs):
		super(args)
		if not args.Cancel:
			dirtyDocuments = [
							editor.GetSafeFileName()
							for editor as BooEditor in _dockManager.Documents
							if editor.IsDirty
							]
			return unless len(dirtyDocuments)

			args.Cancel = (
							DialogResult.Yes !=
							MessageBox.Show("The following files were modified:\n\n\t" +
											join(dirtyDocuments, "\n\t") +
											"\n\nAre you sure you want to leave and lose all your changes?",
											"Boo Explorer",
											MessageBoxButtons.YesNo))

	def FindEditor(fname as string):
		for document in _dockManager.Documents:
			editor = document as BooEditor
			if editor and editor.FileName == fname:
				return editor
		return null

namespace BooExplorer

import System
import System.IO
import System.ComponentModel
import System.Windows.Forms
import System.Drawing
import WeifenLuo.WinFormsUI

class MainForm(Form):

	_dockManager as DockManager
	_status as StatusBar
	_statusPanel1 as StatusBarPanel
	_timer as Timer

	[getter(DocumentOutline)]
	_documentOutline = BooExplorer.DocumentOutline()

	[getter(TaskList)]
	_taskList = BooExplorer.TaskList()

	_argv as (string)

	_menuItemClose as MenuItem
	_menuItemSave as MenuItem
	_menuItemSaveAs as MenuItem

	def constructor(argv as (string)):
		_argv = argv
		_dockManager = DockManager(Dock: DockStyle.Fill,
						ActiveAutoHideContent: null,
						TabIndex: 1,
						ActiveDocumentChanged: _dockManager_ActiveDocumentChanged,
						ContentAdded: _dockManager_ContentAdded,
						ContentRemoved: _dockManager_ContentRemoved)

		_statusPanel1 = StatusBarPanel(AutoSize: StatusBarPanelAutoSize.Contents)

		_status = StatusBar(ShowPanels: true, TabIndex: 2)
		_status.Panels.Add(_statusPanel1)

		SuspendLayout()

		self.Size = System.Drawing.Size(800, 600)
		self.Menu = CreateMainMenu()
		self.Text = "Boo Explorer"
		self.IsMdiContainer = true

		Controls.AddRange((
					_dockManager,
					_status))
		ResumeLayout(false)

		_timer = Timer(Tick: _timer_Tick, Interval: 50ms.TotalMilliseconds)
		_timer.Enabled = true

	private def CreateMainMenu():

		menu = MainMenu()
		file = MenuItem(Text: "&File", MergeOrder: 0)
		file.MenuItems.Add(MenuItem(Text: "&Open...",
									Click: _menuItemOpen_Click,
									Shortcut: Shortcut.CtrlO))
		file.MenuItems.Add(MenuItem(Text: "&New",
									Click: _menuItemNew_Click,
									Shortcut: Shortcut.CtrlN))

		file.MenuItems.Add(MenuItem("-"))

		file.MenuItems.Add(_menuItemSave = MenuItem(Text: "&Save",
									Enabled: false,
									Click: _menuItemSave_Click,
									Shortcut: Shortcut.CtrlS))
		file.MenuItems.Add(_menuItemSaveAs = MenuItem(Text: "S&ave as...",
									Enabled: false,
									Click: _menuItemSaveAs_Click))

		file.MenuItems.Add(_menuItemClose = MenuItem(Text: "&Close",
									Click: _menuItemClose_Click,
									Shortcut: Shortcut.CtrlW,
									Enabled: false))

		file.MenuItems.Add(MenuItem("-"))
		file.MenuItems.Add(MenuItem(Text: "E&xit",
									Shortcut: Shortcut.CtrlQ,
									Click: _menuItemExit_Click))

		view = MenuItem(Text: "&View", MergeOrder: 4)
		view.MenuItems.AddRange(
			(
				MenuItem(Text: "Document Outline",
						Click: _menuItemDocumentOutline_Click,
						Shortcut: Shortcut.CtrlShiftD),
				MenuItem(Text: "Task List",
						Click: _menuItemTaskList_Click,
						Shortcut: Shortcut.CtrlShiftT)
			))

		menu.MenuItems.AddRange((file, view))
		return menu

	def _timer_Tick(sender, args as EventArgs):

		_timer.Enabled = false
		for fname in _argv:
			try:
				OpenDocument(fname)
			except x:
				print(x)
		ShowDocumentOutline()

	StatusText as string:
		set:
			_statusPanel1.Text = value

	def ShowDocumentOutline():
		_documentOutline.Show(_dockManager)

	def NewDocument():
		editor = BooEditor(self)
		editor.Show(_dockManager)
		editor.TextArea.Focus()

	def OpenDocument([required] filename as string):
		filename = Path.GetFullPath(filename)
		content = FindEditor(filename)
		if content is null:
			editor = BooEditor(self)
			editor.Open(filename)
			editor.Show(_dockManager)
			editor.TextArea.Focus()
		else:
			content.Show(_dockManager)
			content.TextArea.Focus()

	def _dockManager_ActiveDocumentChanged(sender, args as EventArgs):
		document = _dockManager.ActiveDocument
		editor = document as BooEditor
		_documentOutline.ActiveDocument = editor
		_menuItemClose.Enabled = document is not null
		_menuItemSaveAs.Enabled = _menuItemSave.Enabled = document is not null

	def _dockManager_ContentAdded(sender, args as ContentEventArgs):
		pass

	def _dockManager_ContentRemoved(sender, args as ContentEventArgs):
		pass

	def _menuItemSaveAs_Click(sender, args as EventArgs):
		cast(BooEditor, _dockManager.ActiveDocument).SaveAs()

	def _menuItemSave_Click(sender, args as EventArgs):
		cast(BooEditor, _dockManager.ActiveDocument).Save()

	def _menuItemExit_Click(sender, args as EventArgs):
		self.Close()

	def _menuItemClose_Click(sender, args as EventArgs):
		_dockManager.ActiveDocument.Close()

	def _menuItemDocumentOutline_Click(sender, args as EventArgs):
		ShowDocumentOutline()

	def _menuItemTaskList_Click(sender, args as EventArgs):
		_taskList.Show(_dockManager)

	def _menuItemOpen_Click(sender, args as EventArgs):
		dlg = OpenFileDialog(
					Filter: "boo files (*.boo)|*.boo|All files (*.*)|*.*",
					Multiselect: true)
		if DialogResult.OK == dlg.ShowDialog(self):
			for fname in dlg.FileNames:
				OpenDocument(fname)

	def _menuItemNew_Click(sender, args as EventArgs):
		NewDocument()

	override protected def OnClosing(args as CancelEventArgs):
		super(args)
		if (not args.Cancel) and AreThereDirtyDocuments():
			args.Cancel = (
							DialogResult.Yes !=
							MessageBox.Show("Are you sure you want to leave and lose all your changes?",
											"Boo Explorer",
											MessageBoxButtons.YesNo))

	def AreThereDirtyDocuments():
		for editor as BooEditor in _dockManager.Documents:
			if editor.IsDirty:
				return true
		return false

	def FindEditor(fname as string):
		for document in _dockManager.Documents:
			editor = document as BooEditor
			if editor and editor.FileName == fname:
				return editor
		return null


Formatting, removing bad directory

Formatting, removing bad directory

git-svn-id: 6eea8ec865c4fa60105bc56808c028bdcf72a817@999 079b0acf-d9fa-0310-9935-e5ade295c882

import namespaces from "assembly://Binsor.Presentation.Framework/DefaultImport.boo"

class WellKnown:

	public static Types = (
		ICommand,
		IView,
		ILayout,
		ILayoutRegistry,
		IModuleLoader,
		IPresenter,
		ILayoutDecoratorResolver,
		IApplicationContext )

	public static Singletons = (
		ICommand,
		IModuleLoader,
		ILayoutRegistry,
		ILayoutDecoratorResolver,
		IApplicationContext )

	public static Assemblies = ("Binsor.Presentation.Framework", )

def InitializeContainer( *assemblies as (string) ):
	facility 'common.resolvers', AddCommonResolversFacility
	for assembly in cat(WellKnown.Assemblies, assemblies):
		for type as Type in Assembly.Load(assembly).GetTypes():
			continue unless type.IsClass and not type.IsAbstract
			continue if type.IsDefined(SkipAutomaticRegistrationAttribute, false)
			ProcessType(type)

def ProcessType(type as Type):
	for wellKnownType in WellKnown.Types:
		continue unless wellKnownType.IsAssignableFrom(type)
		lifeStyle = LifestyleType.Transient
		lifeStyle = LifestyleType.Singleton if wellKnownType in WellKnown.Singletons
		component ExtractName(type), ExtractInterface(wellKnownType, type), type, lifeStyle

def ExtractName(service as Type):
	att as (ComponentAttribute) = service .GetCustomAttributes(ComponentAttribute, false)
	return service.Name if att.Length == 0
	return att[0].Name

def ExtractInterface(service as Type, impl as Type):
	for interfaceType in impl.GetInterfaces():
		return interfaceType if service.IsAssignableFrom(interfaceType)
	return service

def PrintRegisteredComponents():
	# quick way to do reflection, quack
	kernel as duck = IoC.Container.Kernel
	for handler in kernel.NamingSubSystem.GetHandlers():
		print "${handler.ComponentModel.Name} => ${handler.ComponentModel.Service}"

import namespaces from "assembly://Binsor.Presentation.Framework/DefaultImport.boo"

class WellKnown:
	public static Types = (ICommand, IView, ILayout, ILayoutRegistry, IModuleLoader, IPresenter, IApplicationContext )
	public static Singletons = (ICommand, IModuleLoader, ILayoutRegistry, IApplicationContext )
	public static Assemblies = ("Binsor.Presentation.Framework", )

def InitializeContainer( *assemblies as (string) ):
	facility 'common.resolvers', AddCommonResolversFacility
	for assembly in cat(WellKnown.Assemblies, assemblies):
		for type as Type in Assembly.Load(assembly).GetTypes():
			continue unless type.IsClass and not type.IsAbstract
			continue if type.IsDefined(SkipAutomaticRegistrationAttribute, false)
			ProcessType(type)

def ProcessType(type as Type):
	for wellKnownType in WellKnown.Types:
		continue unless wellKnownType.IsAssignableFrom(type)
		lifeStyle = LifestyleType.Transient
		lifeStyle = LifestyleType.Singleton if wellKnownType in WellKnown.Singletons
		component ExtractName(type), ExtractInterface(wellKnownType, type), type, lifeStyle

def ExtractName(service as Type):
	att as (ComponentAttribute) = service .GetCustomAttributes(ComponentAttribute, false)
	return service.Name if att.Length == 0
	return att[0].Name

def ExtractInterface(service as Type, impl as Type):
	for interfaceType in impl.GetInterfaces():
		return interfaceType if service.IsAssignableFrom(interfaceType)
	return service

def PrintRegisteredComponents():
	# quick way to do reflection, quack
	kernel as duck = IoC.Container.Kernel
	for handler in kernel.NamingSubSystem.GetHandlers():
		print "${handler.ComponentModel.Name} => ${handler.ComponentModel.Service}"


object inspector

object inspector

git-svn-id: c3b8989232654601f1acea7403f771adaaa44a81@1155 2c1201b4-01cd-e047-a400-b836ae1fbc61

#region license
// Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//     * Neither the name of Rodrigo B. de Oliveira nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion

"""
Interactive Forms-based Console
"""

namespace BooExplorer

import System
import booish
import System.Windows.Forms
import System.Drawing
import WeifenLuo.WinFormsUI

class InteractiveConsole(DockContent):

	def constructor(mainForm as MainForm):

		self.Text = "Interactive Console"
		self.Controls.Add(console=PromptBox(Dock: DockStyle.Fill,
					Font: System.Drawing.Font("Lucida Console", 12)))

		console.Interpreter.SetValue("MainForm", mainForm)
		console.Interpreter.SetValue("inspect", inspect)

	def inspect([required] obj):
		f = Form(Text: "Object Inspector [${obj.ToString()[:10]}...]")
		f.Controls.Add(PropertyGrid(
							Dock: DockStyle.Fill,
							SelectedObject: obj,
							Font: Font,
							PropertySort: PropertySort.Alphabetical))
		f.Show()
		return f

	override def GetPersistString():
		return "InteractiveConsole|"

class PromptBox(TextBox):

	static Enter = chr(13)

	enum InputState:
		SingleLine = 0
		Block = 1

	_state = InputState.SingleLine

	_block = System.IO.StringWriter()

	[getter(Interpreter)]
	_interpreter = InteractiveInterpreter(
								RememberLastValue: true,
								Print: print)

	def constructor():
		self.Multiline = true
		self.AcceptsTab = true
		self.ScrollBars = ScrollBars.Vertical
		_interpreter.References.Add(typeof(TextBox).Assembly)
		_interpreter.References.Add(typeof(Font).Assembly)

		prompt()

	def GetCurrentLine():
		line = Lines[-1][4:]
		print("")
		return line

	def SingleLineInputState():
		code = GetCurrentLine()

		if code[-1:] in ":", "\\":
			_state = InputState.Block
			_block.GetStringBuilder().Length = 0
			_block.WriteLine(code)
		else:
			_interpreter.LoopEval(code)

	def BlockInputState():
		code = GetCurrentLine()
		if 0 == len(code):
			_interpreter.LoopEval(_block.ToString())
			_state = InputState.SingleLine
		else:
			_block.WriteLine(code)

	override def OnKeyPress(args as KeyPressEventArgs):
		if Enter == args.KeyChar:
			try:
				(SingleLineInputState, BlockInputState)[_state]()
			except x:
				print(x)
			prompt()
			args.Handled = true
		super(args)

	def print(msg):
		AppendText("${msg}\r\n")

	def prompt():
		AppendText((">>> ", "... ")[_state])

	static def chr(value as int):
		return cast(IConvertible, value).ToChar(null)

#region license
// Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//     * Neither the name of Rodrigo B. de Oliveira nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion

"""
Interactive Forms-based Console
"""

namespace BooExplorer

import System
import booish
import System.Windows.Forms
import System.Drawing
import WeifenLuo.WinFormsUI

class InteractiveConsole(DockContent):

	def constructor(mainForm as MainForm):

		self.Text = "Interactive Console"
		self.Controls.Add(console=PromptBox(Dock: DockStyle.Fill,
					Font: System.Drawing.Font("Lucida Console", 12)))

		console.Interpreter.SetValue("MainForm", mainForm)

	override def GetPersistString():
		return "InteractiveConsole|"

class PromptBox(TextBox):

	static Enter = chr(13)

	enum InputState:
		SingleLine = 0
		Block = 1

	_state = InputState.SingleLine

	_block = System.IO.StringWriter()

	[getter(Interpreter)]
	_interpreter = InteractiveInterpreter(
								RememberLastValue: true,
								Print: print)

	def constructor():
		self.Multiline = true
		self.AcceptsTab = true
		self.ScrollBars = ScrollBars.Vertical
		_interpreter.References.Add(typeof(TextBox).Assembly)
		_interpreter.References.Add(typeof(Font).Assembly)

		prompt()

	def GetCurrentLine():
		line = Lines[-1][4:]
		print("")
		return line

	def SingleLineInputState():
		code = GetCurrentLine()

		if code[-1:] in ":", "\\":
			_state = InputState.Block
			_block.GetStringBuilder().Length = 0
			_block.WriteLine(code)
		else:
			_interpreter.LoopEval(code)

	def BlockInputState():
		code = GetCurrentLine()
		if 0 == len(code):
			_interpreter.LoopEval(_block.ToString())
			_state = InputState.SingleLine
		else:
			_block.WriteLine(code)

	override def OnKeyPress(args as KeyPressEventArgs):
		if Enter == args.KeyChar:
			try:
				(SingleLineInputState, BlockInputState)[_state]()
			except x:
				print(x)
			prompt()
			args.Handled = true
		super(args)

	def print(msg):
		AppendText("${msg}\r\n")

	def prompt():
		AppendText((">>> ", "... ")[_state])

	static def chr(value as int):
		return cast(IConvertible, value).ToChar(null)


BOO-891

BOO-891

git-svn-id: fcce7d6ce0ac15bf24f68871b5145d46fc068279@2715 2c1201b4-01cd-e047-a400-b836ae1fbc61

#region license
// Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//     * Neither the name of Rodrigo B. de Oliveira nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion

namespace Boo.NAnt

import System
import System.Text
import System.Diagnostics
import System.IO
import NAnt.Core
import NAnt.Core.Attributes
import NAnt.Core.Types
import Boo.Lang.Compiler

abstract class AbstractBooTask(Task):

	_references = FileSet()

	_packages = OptionCollection()

	_pipeline as string

	[BuildElement("references")]
	References:
		get:
			return _references
		set:
			_references = value

	[BuildElementCollection("pkg-references", "package")]
	Packages:
		get:
			return _packages
		set:
			_packages = value

	[TaskAttribute("pipeline")]
	Pipeline:
		get:
			return _pipeline
		set:
			_pipeline = value

	protected def RunCompiler(compiler as BooCompiler):
		AddReferences(compiler.Parameters)
		AddPackages(compiler.Parameters)
		if _pipeline:
			compiler.Parameters.Pipeline = CompilerPipeline.GetPipeline(_pipeline)
		else:
			compiler.Parameters.Pipeline = GetDefaultPipeline()
		result = compiler.Run()
		CheckCompilationResult(result)
		return result

	protected def AddReferences(parameters as CompilerParameters):
		if _references.BaseDirectory is not null:
			baseDir = _references.BaseDirectory.ToString()
		else:
			baseDir = Project.BaseDirectory

		for reference as string in _references.Includes:
			path = reference
			if not Path.IsPathRooted(path):
				path = Path.Combine(baseDir, reference)
				if not File.Exists(path):
					print("${path} doesn't exist.")
					asm = Reflection.Assembly.Load(Path.GetFileNameWithoutExtension(reference))
				else:
					asm = Reflection.Assembly.LoadFrom(path)
			else:
				asm = Reflection.Assembly.LoadFrom(path)

			print("reference: ${path}")
			try:
				parameters.References.Add(asm)
				//TODO: rationalize above call to parameters.References.Add(parameters.LoadAssembly(reference)) ?
				//      move basedir into CompilerParameters ?
			except x:
				raise BuildException(
					Boo.Lang.ResourceManager.Format("BCE0041", reference),
					Location,
					x)

	protected def AddPackages(parameters as CompilerParameters):
		for package as string in _packages:
			try:
				parameters.LoadReferencesFromPackage(package);
			except x:
				raise BuildException(
					Boo.Lang.ResourceManager.Format("BCE0041", package),
					Location,
					x)

	protected def CheckCompilationResult(context as CompilerContext):
		errors = context.Errors
		verbose = context.Parameters.TraceSwitch.TraceInfo
		for error in errors:
			LogError(error.ToString(verbose))
		for warning in context.Warnings:
			LogWarning(warning.ToString());

		if len(errors):
			LogInfo("${len(errors)} error(s).")
			raise BuildException("boo compilation error", Location)

	abstract def GetDefaultPipeline() as CompilerPipeline:
		pass

	def GetFrameworkDirectory():
		return Project.TargetFramework.FrameworkAssemblyDirectory.ToString()

	def print(message):
		LogVerbose(message)

	def LogInfo(message):
		self.Log(Level.Info, "${message}")

	def LogVerbose(message):
		self.Log(Level.Verbose, "${message}")

	def LogWarning(message):
		self.Log(Level.Warning, "${message}")

	def LogError(message):
		self.Log(Level.Error, "${message}")

def read(fname as string):
	using reader=File.OpenText(fname):
		return reader.ReadToEnd()

def write(fname as string, contents as string):
	using writer=StreamWriter(fname, false, System.Text.Encoding.UTF8):
		writer.Write(contents)

#region license
// Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//     * Neither the name of Rodrigo B. de Oliveira nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion

namespace Boo.NAnt

import System
import System.Text
import System.Diagnostics
import System.IO
import NAnt.Core
import NAnt.Core.Attributes
import NAnt.Core.Types
import Boo.Lang.Compiler

abstract class AbstractBooTask(Task):

	_references = FileSet()

	_packages = OptionCollection()

	_pipeline as string

	[BuildElement("references")]
	References:
		get:
			return _references
		set:
			_references = value

	[BuildElementCollection("pkg-references", "package")]
	Packages:
		get:
			return _packages
		set:
			_packages = value

	[TaskAttribute("pipeline")]
	Pipeline:
		get:
			return _pipeline
		set:
			_pipeline = value

	protected def RunCompiler(compiler as BooCompiler):
		AddReferences(compiler.Parameters)
		AddPackages(compiler.Parameters)
		if _pipeline:
			compiler.Parameters.Pipeline = CompilerPipeline.GetPipeline(_pipeline)
		else:
			compiler.Parameters.Pipeline = GetDefaultPipeline()
		result = compiler.Run()
		CheckCompilationResult(result)
		return result

	protected def AddReferences(parameters as CompilerParameters):
		if _references.BaseDirectory is not null:
			baseDir = _references.BaseDirectory.ToString()
		else:
			baseDir = Project.BaseDirectory

		for reference as string in _references.Includes:
			path = reference
			if not Path.IsPathRooted(path):
				path = Path.Combine(baseDir, reference)
				if not File.Exists(path):
					print("${path} doesn't exist.")
					asm = Reflection.Assembly.LoadWithPartialName(Path.GetFileNameWithoutExtension(reference))
				else:
					asm = Reflection.Assembly.LoadFrom(path)
			else:
				asm = Reflection.Assembly.LoadFrom(path)

			print("reference: ${path}")
			try:
				parameters.References.Add(asm)
				//TODO: rationalize above call to parameters.References.Add(parameters.LoadAssembly(reference)) ?
				//      move basedir into CompilerParameters ?
			except x:
				raise BuildException(
					Boo.Lang.ResourceManager.Format("BCE0041", reference),
					Location,
					x)

	protected def AddPackages(parameters as CompilerParameters):
		for package as string in _packages:
			try:
				parameters.LoadReferencesFromPackage(package);
			except x:
				raise BuildException(
					Boo.Lang.ResourceManager.Format("BCE0041", package),
					Location,
					x)

	protected def CheckCompilationResult(context as CompilerContext):
		errors = context.Errors
		verbose = context.Parameters.TraceSwitch.TraceInfo
		for error in errors:
			LogError(error.ToString(verbose))
		for warning in context.Warnings:
			LogWarning(warning.ToString());

		if len(errors):
			LogInfo("${len(errors)} error(s).")
			raise BuildException("boo compilation error", Location)

	abstract def GetDefaultPipeline() as CompilerPipeline:
		pass

	def GetFrameworkDirectory():
		return Project.TargetFramework.FrameworkAssemblyDirectory.ToString()

	def print(message):
		LogVerbose(message)

	def LogInfo(message):
		self.Log(Level.Info, "${message}")

	def LogVerbose(message):
		self.Log(Level.Verbose, "${message}")

	def LogWarning(message):
		self.Log(Level.Warning, "${message}")

	def LogError(message):
		self.Log(Level.Error, "${message}")

def read(fname as string):
	using reader=File.OpenText(fname):
		return reader.ReadToEnd()

def write(fname as string, contents as string):
	using writer=StreamWriter(fname, false, System.Text.Encoding.UTF8):
		writer.Write(contents)


keep MonoDevelop project uptodate too

keep MonoDevelop project uptodate too

git-svn-id: fcce7d6ce0ac15bf24f68871b5145d46fc068279@2618 2c1201b4-01cd-e047-a400-b836ae1fbc61

import System.Xml
import System.IO
import System.Resources
import System.Windows.Forms
import Useful.IO from Boo.Lang.Useful

class XmlDocumentWrapper:

	_document as XmlDocument

	def constructor(document as XmlDocument):
		_document = document

	def constructor(fname as string):
		_document = XmlDocument()
		_document.Load(fname)

	NamespaceURI:
		get:
			xmlns = _document.DocumentElement.Attributes["xmlns"]
			if xmlns is null: return null
			return xmlns.Value

	BaseURI:
		get:
			return System.Uri(_document.BaseURI)

	AbsolutePath:
		get:
			return BaseURI.AbsolutePath

	def Save():
		_document.Save(AbsolutePath)

class Project(XmlDocumentWrapper):

	static def Load(fname as string):
		doc = XmlDocument()
		doc.Load(fname)
		if fname.EndsWith(".mdp"):
			return MDProject(doc)
		return VS2005Project(doc)

	_sourceFiles as XmlElement

	def constructor(document as XmlDocument, sourceFiles as XmlElement):
		super(document)
		_sourceFiles = sourceFiles

	def ResetSourceFiles():
		_sourceFiles.RemoveAll()

	def AddSourceFile(item as string):
		_sourceFiles.AppendChild(CreateSourceElement(item))

	protected abstract def CreateSourceElement(src as string) as XmlElement:
		pass

class MDProject(Project):
	def constructor(document as XmlDocument):
		super(document, document.SelectSingleNode("/Project/Contents"))

	override protected def CreateSourceElement(src as string):
		file = _document.CreateElement("File", NamespaceURI)
		file.SetAttribute("name", src)
		file.SetAttribute("buildaction", "Compile")
		file.SetAttribute("subtype", "Code")
		return file

class VS2005Project(Project):

	def constructor(document as XmlDocument):
		super(document, selectCompileItemGroup(document))

	private def selectCompileItemGroup(document as XmlDocument):
		compileItem = document.SelectSingleNode("//*[local-name()='ItemGroup']/*[local-name()='Compile']")
		return compileItem.ParentNode

	override protected def CreateSourceElement(src as string):
		compile = _document.CreateElement("Compile", NamespaceURI)
		compile.SetAttribute("Include", src.Replace('/', '\\'))
		return compile

def updateProjectFile(fname as string):
	project = Project.Load(fname)
	project.ResetSourceFiles()

	baseURI = project.BaseURI
	for item as string in listFiles(Path.GetDirectoryName(baseURI.AbsolutePath)):
		if item =~ /\.svn/: continue
		if not item.EndsWith(".cs"): continue
		uri = baseURI.MakeRelative(System.Uri(item))
		project.AddSourceFile(uri)
	project.Save()

	print project.AbsolutePath

def updateStringResources(txtFile as string):
	fname = Path.ChangeExtension(txtFile, ".resx")
	File.Delete(fname)

	using resourceFile = ResXResourceWriter(fname):

		using file=File.OpenText(txtFile):
			for line in file:
				if line.StartsWith(";"): continue
				line = line.Trim()
				if len(line) == 0: continue
				index = line.IndexOf('=')
				key = line[:index]
				value = line[index+1:]

				resourceFile.AddResource(key, value)

	print fname

def rebase(fname as string):
	#return Path.Combine("c:/projects/boo/", fname)
	return fname

fnames = (
"src/Boo.Lang/Boo.Lang-VS2005.csproj",
"src/Boo.Lang.Parser/Boo.Lang.Parser-VS2005.csproj",
"src/Boo.Lang.Compiler/Boo.Lang.Compiler-VS2005.csproj",
"tests/BooCompiler.Tests/BooCompiler.Tests-VS2005.csproj",

"src/Boo.Lang.Compiler/Boo.Lang.Compiler.mdp",
)
for fname in fnames:
	updateProjectFile(rebase(fname))

updateStringResources(rebase("src/Boo.Lang/Resources/strings.txt"))

import System.Xml
import System.IO
import System.Resources
import System.Windows.Forms
import Useful.IO from Boo.Lang.Useful

class XmlDocumentWrapper:

	_document as XmlDocument

	def constructor(document as XmlDocument):
		_document = document

	def constructor(fname as string):
		_document = XmlDocument()
		_document.Load(fname)

	NamespaceURI:
		get:
			return _document.DocumentElement.Attributes["xmlns"].Value

	BaseURI:
		get:
			return System.Uri(_document.BaseURI)

	AbsolutePath:
		get:
			return BaseURI.AbsolutePath

	def Save():
		_document.Save(AbsolutePath)

class VS2005Project(XmlDocumentWrapper):

	static def Load(fname as string):
		doc = XmlDocument()
		doc.Load(fname)

		compileItem = doc.SelectSingleNode("//*[local-name()='ItemGroup']/*[local-name()='Compile']")
		compileItemGroup = compileItem.ParentNode
		return VS2005Project(doc, compileItemGroup)

	_compileItemGroup as XmlElement

	def constructor(document as XmlDocument, compileItemGroup as XmlElement):
		super(document)
		_compileItemGroup = compileItemGroup

	def ResetCompileItemGroup():
		_compileItemGroup.RemoveAll()

	def AddCompileItem(item as string):
		compile = _document.CreateElement("Compile", NamespaceURI)
		compile.SetAttribute("Include", item.Replace('/', '\\'))
		_compileItemGroup.AppendChild(compile)

def updateProjectFile(fname as string):
	project = VS2005Project.Load(fname)
	project.ResetCompileItemGroup()

	baseURI = project.BaseURI
	for item as string in listFiles(Path.GetDirectoryName(baseURI.AbsolutePath)):
		if item =~ /\.svn/: continue
		if not item.EndsWith(".cs"): continue
		uri = baseURI.MakeRelative(System.Uri(item))
		project.AddCompileItem(uri)
	project.Save()

	print project.AbsolutePath

def updateStringResources(txtFile as string):
	fname = Path.ChangeExtension(txtFile, ".resx")
	File.Delete(fname)

	using resourceFile = ResXResourceWriter(fname):

		using file=File.OpenText(txtFile):
			for line in file:
				if line.StartsWith(";"): continue
				line = line.Trim()
				if len(line) == 0: continue
				index = line.IndexOf('=')
				key = line[:index]
				value = line[index+1:]

				resourceFile.AddResource(key, value)

	print fname

def rebase(fname as string):
	#return Path.Combine("c:/projects/boo/", fname)
	return fname

fnames = (
"src/Boo.Lang/Boo.Lang-VS2005.csproj",
"src/Boo.Lang.Parser/Boo.Lang.Parser-VS2005.csproj",
"src/Boo.Lang.Compiler/Boo.Lang.Compiler-VS2005.csproj",
"tests/BooCompiler.Tests/BooCompiler.Tests-VS2005.csproj"
)
for fname in fnames:
	updateProjectFile(rebase(fname))

updateStringResources(rebase("src/Boo.Lang/Resources/strings.txt"))


comment for future feature

comment for future feature

namespace Boo.Adt.Tests

import NUnit.Framework
import Boo.Adt

data Expression = Const(value as int) \
			| Add(left as Expression, right as Expression)

data ExpressionX < Expression = Mult(left as Expression, right as Expression)

data Result(Value as int) = Success() | Failure(Error as string)

data Foo(Value as int)

#data Bar(Value as int, Count as int) < Foo(Value)

[TestFixture]
class DataMacroTest:

	[Test]
	def TestMutableField():

		data Mutable(@m as int, i as int)

		assert not typeof(Mutable).GetField("m").IsInitOnly
		assert typeof(Mutable).GetField("i").IsInitOnly

	[Test]
	def TestSingleType():
		type = Foo
		assert object is type.BaseType
		Assert.AreEqual("Foo(42)", Foo(42).ToString())

	[Test]
	def TestBaseFields():
		Assert.AreEqual("Success(42)", Success(42).ToString())
		Assert.AreEqual("Failure(42, crash)", Failure(42, "crash").ToString())
		Assert.AreEqual(Success(42), Success(42))
		Assert.IsFalse(Success(42) == Success(21))

	[Test]
	def TestClassHierarchy():
		type = Expression
		assert type.IsAbstract

		for type in Const, Add:
			assert not type.IsAbstract
			assert not type.IsSealed
			assert Expression is type.BaseType

		assert Expression is typeof(ExpressionX).BaseType
		assert ExpressionX is typeof(Mult).BaseType

	[Test]
	def TestToString():
		Assert.AreEqual("Const(42)", Const(42).ToString())
		Assert.AreEqual("Add(Const(19), Const(22))", Add(Const(19), Const(22)).ToString())

	[Test]
	def TestEquals():
		Assert.AreEqual(Const(42), Const(42))
		assert Const(-1) != Const(42)

	[Test]
	def TestEqualsWithoutFields():
		data NoFields()
		Assert.AreEqual(NoFields(), NoFields())

	[Test]
	def TestProperties():
		Assert.AreEqual(42, Const(42).value)

namespace Boo.Adt.Tests

import NUnit.Framework
import Boo.Adt

data Expression = Const(value as int) \
			| Add(left as Expression, right as Expression)

data ExpressionX < Expression = Mult(left as Expression, right as Expression)

data Result(Value as int) = Success() | Failure(Error as string)

data Foo(Value as int)

[TestFixture]
class DataMacroTest:

	[Test]
	def TestMutableField():

		data Mutable(@m as int, i as int)

		assert not typeof(Mutable).GetField("m").IsInitOnly
		assert typeof(Mutable).GetField("i").IsInitOnly

	[Test]
	def TestSingleType():
		type = Foo
		assert object is type.BaseType
		Assert.AreEqual("Foo(42)", Foo(42).ToString())

	[Test]
	def TestBaseFields():
		Assert.AreEqual("Success(42)", Success(42).ToString())
		Assert.AreEqual("Failure(42, crash)", Failure(42, "crash").ToString())
		Assert.AreEqual(Success(42), Success(42))
		Assert.IsFalse(Success(42) == Success(21))

	[Test]
	def TestClassHierarchy():
		type = Expression
		assert type.IsAbstract

		for type in Const, Add:
			assert not type.IsAbstract
			assert not type.IsSealed
			assert Expression is type.BaseType

		assert Expression is typeof(ExpressionX).BaseType
		assert ExpressionX is typeof(Mult).BaseType

	[Test]
	def TestToString():
		Assert.AreEqual("Const(42)", Const(42).ToString())
		Assert.AreEqual("Add(Const(19), Const(22))", Add(Const(19), Const(22)).ToString())

	[Test]
	def TestEquals():
		Assert.AreEqual(Const(42), Const(42))
		assert Const(-1) != Const(42)

	[Test]
	def TestEqualsWithoutFields():
		data NoFields()
		Assert.AreEqual(NoFields(), NoFields())

	[Test]
	def TestProperties():
		Assert.AreEqual(42, Const(42).value)


Updating build script

Updating build script

configuration = "release"
test_assembly = "src/FluentLinqToSql.Tests/bin/${configuration}/FluentLinqToSql.Tests.dll"
dbtest_assembly = "src/FluentLinqToSql.DatabaseTests/bin/${configuration}/FluentLinqToSql.DatabaseTests.dll"
dbtest_enabled = true

target default, (init, compile, test, createDb, dbTest, deploy, package):
  pass

target ci, (init, compile, createDb, coverage, deploy, package):
  pass

target init:
  rmdir("build")

target noDatabase:
  dbtest_enabled = false

target compile:
  msbuild(file: "FluentLinqToSql.sln", configuration: "release")

target test:
  nunit(assembly: test_assembly)

target createDb:
  if not dbtest_enabled:
    print "Skipping database creation"
    return
  print "Trying to create test db"
  nunit(assembly: dbtest_assembly, include: "CreateDatabase")
  print "Test database created"

target dbTest:
  if not dbtest_enabled:
    print "Skipping database tests"
    return
  nunit(assembly: dbtest_assembly)

target deploy:
  with FileList():
    .Include("src/FluentLinqToSql/bin/${configuration}/*.{dll,pdb,xml}")
    .Include("readme.txt")
    .Include("License.txt")
    .Flatten(true)
    .ForEach def(file):
      file.CopyToDirectory("build/${configuration}")

target package:
  zip("build/${configuration}", "build/FluentLinqToSql.zip")

target coverage:
  ncover_path = "c:/program files (x86)/ncover"
  app_assemblies = ("FluentLinqToSql",)
  teamcity_launcher = env("teamcity.dotnet.nunitlauncher")

  #ensure the dbtest assembly is in the right place...
  cp(dbtest_assembly, "src/FluentLinqToSql.Tests/bin/${configuration}/")

  with ncover():
    .toolPath = "${ncover_path}/NCover.console.exe"
    .reportDirectory = "build/Coverage"
    .workingDirectory = "src/FluentLinqToSql.Tests/bin/${configuration}"
    .applicationAssemblies = app_assemblies
    .program = "${teamcity_launcher} v2.0 x86 NUnit-2.4.6"
    .testAssembly = "FluentLinqToSql.Tests.dll;FluentLinqToSql.DatabaseTests.dll"
    .excludeAttributes = "System.Runtime.CompilerServices.CompilerGeneratedAttribute"

  with ncover_explorer():
    .toolPath = "${ncover_path}/NCoverExplorer.console.exe"
    .project = "FluentLinqToSql"
    .reportDirectory = "build/coverage"

configuration = "release"
test_assembly = "src/FluentLinqToSql.Tests/bin/${configuration}/FluentLinqToSql.Tests.dll"
dbtest_assembly = "src/FluentLinqToSql.DatabaseTests/bin/${configuration}/FluentLinqToSql.DatabaseTests.dll"
dbtest_enabled = true

target default, (init, compile, test, createDb, dbTest, deploy, package):
  pass

target ci, (init, compile, createDb, coverage, deploy, package):
  pass

target init:
  rmdir("build")

target noDatabase:
  dbtest_enabled = false

target compile:
  msbuild(file: "FluentLinqToSql.sln", configuration: "release")

target test:
  nunit(assembly: test_assembly)

target createDb:
  if not dbtest_enabled:
    print "Skipping database creation"
    return
  print "Trying to create test db"
  nunit(assembly: dbtest_assembly, include: "CreateDatabase")
  print "Test database created"

target dbTest:
  if not dbtest_enabled:
    print "Skipping database tests"
    return
  nunit(assembly: dbtest_assembly)

target deploy:
  with FileList():
    .Include("src/FluentLinqToSql/bin/${configuration}/*.{dll,pdb,xml}")
    .Include("readme.txt")
    .Include("License.txt")
    .Flatten(true)
    .ForEach def(file):
      file.CopyToDirectory("build/${configuration}")

target package:
  zip("build/${configuration}", "build/FluentLinqToSql.zip")

target coverage:
  ncover_path = "c:/program files (x86)/ncover"
  app_assemblies = ("FluentLinqToSql",)
  teamcity_launcher = env("teamcity.dotnet.nunitlauncher")

  #ensure the dbtest assembly is in the right place...
  cp(dbtest_assembly, "src/FluentLinqToSql.Tests/bin/${configuration}")

  with ncover():
    .toolPath = "${ncover_path}/NCover.console.exe"
    .reportDirectory = "build/Coverage"
    .workingDirectory = "src/FluentLinqToSql.Tests/bin/${configuration}"
    .applicationAssemblies = app_assemblies
    .program = "${teamcity_launcher} v2.0 x86 NUnit-2.4.6"
    .testAssembly = "FluentLinqToSql.Tests.dll;FluentLinqToSql.DatabaseTests.dll"
    .excludeAttributes = "System.Runtime.CompilerServices.CompilerGeneratedAttribute"

  with ncover_explorer():
    .toolPath = "${ncover_path}/NCoverExplorer.console.exe"
    .project = "FluentLinqToSql"
    .reportDirectory = "build/coverage"


better version

better version

git-svn-id: fcce7d6ce0ac15bf24f68871b5145d46fc068279@2287 2c1201b4-01cd-e047-a400-b836ae1fbc61

#region license
// Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//     * Neither the name of Rodrigo B. de Oliveira nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion

namespace Boo.NAnt

import System
import System.Diagnostics
import System.IO
import NAnt.Core
import NAnt.Core.Attributes
import NAnt.Core.Types
import Boo.Lang.Compiler
import Boo.Lang.Compiler.IO
import Boo.Lang.Compiler.Ast
import Boo.Lang.Compiler.Pipelines
import Boo.Lang.Compiler.Steps

class AbstractScript:

	[property(Project)]
	_project as Project

	[property(Task)]
	_task as BooTask

	def print(msg):
		_task.LogInfo(msg)

	abstract def Run():
		pass

class PrepareScriptStep(AbstractCompilerStep):

	override def Run():
		module = CompileUnit.Modules[0]

		method = Method(Name: "Run",
						Modifiers: TypeMemberModifiers.Override,
						Body: module.Globals)

		module.Globals = Block()

		script = ClassDefinition(Name: "__Script__")
		script.BaseTypes.Add(SimpleTypeReference("Boo.NAnt.AbstractScript"))
		script.Members.Add(method)
		script.Members.Extend(module.Members)

		module.Members.Clear()
		module.Members.Add(script)

def WithWorkingDir(dir as string, block as callable()):
	_saved = Environment.CurrentDirectory
	Environment.CurrentDirectory = dir
	try:
		block()
	ensure:
		Environment.CurrentDirectory = _saved

[TaskName("boo")]
class BooTask(AbstractBooTask):

	_src as FileInfo

	[TaskAttribute("src", Required: false)]
	Source:
		get:
			return _src
		set:
			_src = value

	override def ExecuteTask():

		compiler = BooCompiler()
		parameters = compiler.Parameters
		parameters.OutputType = CompilerOutputType.Library
		if _src:
			parameters.Input.Add(FileInput(_src.ToString()))
		else:
			parameters.Input.Add(StringInput("boo", reindent(getSourceCode())))
		parameters.References.Add(GetType().Assembly)
		parameters.References.Add(typeof(NAnt.Core.Project).Assembly)

		result = RunCompiler(compiler)

		print("script successfully compiled.")
		try:
			scriptType = result.GeneratedAssembly.GetType("__Script__", true)
			script as AbstractScript = scriptType()
			script.Project = Project
			script.Task = self
			WithWorkingDir(Project.BaseDirectory) do:
				script.Run()
		except x:
			raise BuildException(x.Message, Location, x)

	override def GetDefaultPipeline():
		pipeline = CompileToMemory()
		pipeline.Insert(1, PrepareScriptStep())
		return pipeline

	private def getSourceCode():
		codeNode = self.XmlNode.SelectSingleNode("code")
		return (codeNode or self.XmlNode).InnerText

	private def reindent(code as string):
		lines = /\n/.Split(code.Replace("\r\n", "\n"))
		lines = [line for line in lines if len(line.Trim())].ToArray(string)

		first = lines[0]
		indent = /(\s*)/.Match(first).Groups[0].Value
		return code if 0 == len(indent)

		buffer = System.Text.StringBuilder()
		for line in lines:
			if not line.StartsWith(indent):
				return code // let the parser complain about it
			else:
				buffer.Append(line[len(indent):])
				buffer.Append("\n")
		return buffer.ToString()

#region license
// Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//     * Neither the name of Rodrigo B. de Oliveira nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion

namespace Boo.NAnt

import System
import System.Diagnostics
import System.IO
import NAnt.Core
import NAnt.Core.Attributes
import NAnt.Core.Types
import Boo.Lang.Compiler
import Boo.Lang.Compiler.IO
import Boo.Lang.Compiler.Ast
import Boo.Lang.Compiler.Pipelines
import Boo.Lang.Compiler.Steps

class AbstractScript:

	[property(Project)]
	_project as Project

	[property(Task)]
	_task as BooTask

	def print(msg):
		_task.LogInfo(msg)

	abstract def Run():
		pass

class PrepareScriptStep(AbstractCompilerStep):

	override def Run():
		module = CompileUnit.Modules[0]

		method = Method(Name: "Run",
						Modifiers: TypeMemberModifiers.Override,
						Body: module.Globals)

		module.Globals = Block()

		script = ClassDefinition(Name: "__Script__")
		script.BaseTypes.Add(SimpleTypeReference("Boo.NAnt.AbstractScript"))
		script.Members.Add(method)
		script.Members.Extend(module.Members)

		module.Members.Clear()
		module.Members.Add(script)

class WithWorkingDir(IDisposable):
	_saved as string
	def constructor(dir as string):
		_saved = Environment.CurrentDirectory
		Environment.CurrentDirectory = dir
	def Dispose():
		Environment.CurrentDirectory = _saved

[TaskName("boo")]
class BooTask(AbstractBooTask):

	_src as FileInfo

	[TaskAttribute("src", Required: false)]
	Source:
		get:
			return _src
		set:
			_src = value

	override def ExecuteTask():

		compiler = BooCompiler()
		parameters = compiler.Parameters
		parameters.OutputType = CompilerOutputType.Library
		if _src:
			parameters.Input.Add(FileInput(_src.ToString()))
		else:
			parameters.Input.Add(StringInput("boo", reindent(getSourceCode())))
		parameters.References.Add(GetType().Assembly)
		parameters.References.Add(typeof(NAnt.Core.Project).Assembly)

		result = RunCompiler(compiler)

		print("script successfully compiled.")
		using WithWorkingDir(Project.BaseDirectory):
			try:
				scriptType = result.GeneratedAssembly.GetType("__Script__", true)
				script as AbstractScript = scriptType()
				script.Project = Project
				script.Task = self
				script.Run()
			except x:
				raise BuildException(x.Message, Location, x)

	override def GetDefaultPipeline():
		pipeline = CompileToMemory()
		pipeline.Insert(1, PrepareScriptStep())
		return pipeline

	private def getSourceCode():
		codeNode = self.XmlNode.SelectSingleNode("code")
		return (codeNode or self.XmlNode).InnerText

	private def reindent(code as string):
		lines = /\n/.Split(code.Replace("\r\n", "\n"))
		lines = [line for line in lines if len(line.Trim())].ToArray(string)

		first = lines[0]
		indent = /(\s*)/.Match(first).Groups[0].Value
		return code if 0 == len(indent)

		buffer = System.Text.StringBuilder()
		for line in lines:
			if not line.StartsWith(indent):
				return code // let the parser complain about it
			else:
				buffer.Append(line[len(indent):])
				buffer.Append("\n")
		return buffer.ToString()