Files
yallie 9fa3874800 Added the contents of the archive.
Moved the original file to the archive subfolder.
2017-11-20 16:11:42 +03:00

157 lines
6.5 KiB
C#

// ==++==
//
//
// Copyright (c) 2002 Microsoft Corporation. All rights reserved.
//
// The use and distribution terms for this software are contained in the file
// named license.txt, which can be found in the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by the
// terms of this license.
//
// You must not remove this notice, or any other, from this software.
//
//
// ==--==
namespace Microsoft.JScript
{
using System;
using System.Reflection;
using System.Reflection.Emit;
internal sealed class VariableDeclaration : AST{
internal Lookup identifier;
private TypeExpression type;
internal AST initializer;
internal JSVariableField field;
private Completion completion;
internal VariableDeclaration(Context context, Lookup identifier, TypeExpression type, AST initializer, FieldAttributes attributes, CustomAttributeList customAttributes)
: base(context) {
if (initializer != null)
this.context.UpdateWith(initializer.context);
else if (type != null)
this.context.UpdateWith(type.context);
this.identifier = identifier;
this.type = type;
this.initializer = initializer;
ScriptObject current_scope = (ScriptObject)Globals.ScopeStack.Peek();
while (current_scope is WithObject) //Can only happen at run time and only if there is an eval
current_scope = current_scope.GetParent();
String name = this.identifier.ToString();
if (current_scope is ClassScope){
if (name == ((ClassScope)current_scope).name){
identifier.context.HandleError(JSError.CannotUseNameOfClass);
name = name + " var";
}
}else{
if (attributes != (FieldAttributes)0){
this.context.HandleError(JSError.NotInsideClass);
attributes = FieldAttributes.Public;
}else
attributes |= FieldAttributes.Public;
}
FieldInfo field = ((IActivationObject)current_scope).GetLocalField(name);
if (field != null){
if (field.IsLiteral || current_scope is ClassScope || type != null)
identifier.context.HandleError(JSError.DuplicateName, true);
this.type = type = null;
}
if (current_scope is ActivationObject)
if (field == null || field is JSVariableField)
this.field = ((ActivationObject)current_scope).AddFieldOrUseExistingField(this.identifier.ToString(), Missing.Value, attributes);
else
this.field = ((ActivationObject)current_scope).AddNewField(this.identifier.ToString(), null, attributes);
else
this.field = ((StackFrame)current_scope).AddNewField(this.identifier.ToString(), null, attributes|FieldAttributes.Static);
this.field.type = type;
this.field.customAttributes = customAttributes;
this.field.originalContext = context;
if (this.field is JSLocalField)
// emit debug info for the local only if this block of code is in a section that has debug set
((JSLocalField)this.field).debugOn = this.identifier.context.document.debugOn;
this.completion = new Completion();
}
internal override Object Evaluate(){
ScriptObject scope = Globals.ScopeStack.Peek();
Object value = null;
if (this.initializer != null)
value = this.initializer.Evaluate();
if (this.type != null)
value = Convert.Coerce(value, this.type);
else{
while (scope is BlockScope) scope = scope.GetParent();
if (scope is WithObject)
this.identifier.SetWithValue((WithObject)scope, value);
while (scope is WithObject || scope is BlockScope)
scope = scope.GetParent();
if (this.initializer == null && !(this.field.value is Missing)){
this.completion.value = this.field.value;
return this.completion;
}
}
this.field.SetValue(scope, this.completion.value = value);
return this.completion;
}
internal override AST PartiallyEvaluate(){
AST id = this.identifier = (Lookup)this.identifier.PartiallyEvaluateAsReference();
if (this.type != null)
this.field.type = this.type = (TypeExpression)this.type.PartiallyEvaluate();
else if (this.initializer == null && !(this.field is JSLocalField) &&
this.field.value is Missing){
id.context.HandleError(JSError.VariableLeftUninitialized);
this.field.type = this.type = new TypeExpression(new ConstantWrapper(Typeob.Object, id.context));
}
if (this.initializer != null){
if (this.field.IsStatic){
ScriptObject scope = this.Engine.ScriptObjectStackTop();
ClassScope cscope = null;
while (scope != null && (cscope = scope as ClassScope) == null) scope = scope.GetParent();
if (cscope != null) cscope.inStaticInitializerCode = true;
this.initializer = this.initializer.PartiallyEvaluate();
if (cscope != null) cscope.inStaticInitializerCode = false;
}else
this.initializer = this.initializer.PartiallyEvaluate();
id.SetPartialValue(this.initializer);
}
// deal with custom attributes
if (this.field != null && this.field.customAttributes != null)
this.field.customAttributes.PartiallyEvaluate();
return this;
}
internal override void TranslateToIL(ILGenerator il, Type rtype){
//This assumes that rtype == Void.class
//If the initializer is missing. Do nothing, we're done.
if (this.initializer == null)
return;
// this.initializer.context can be null when a default initializer is forced in the variable (i.e. for_in case)
if (this.context.document.debugOn && this.initializer.context != null)
this.context.EmitLineInfo(il);
Lookup id = (Lookup)this.identifier;
id.TranslateToILPreSet(il, true);
id.TranslateToILSet(il, true, this.initializer);
}
internal override void TranslateToILInitializer(ILGenerator il){
if (this.type != null)
this.type.TranslateToILInitializer(il);
if (this.initializer != null)
this.initializer.TranslateToILInitializer(il);
}
internal override Context GetFirstExecutableContext(){
if (this.initializer == null)
return null;
else
return this.context;
}
}
}