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

150 lines
6.3 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 Constant : AST{
internal FieldAttributes attributes;
private Completion completion;
internal CustomAttributeList customAttributes;
internal JSVariableField field;
private FieldBuilder valueField;
private Lookup identifier;
internal String name;
internal AST value;
internal Constant(Context context, Lookup identifier, TypeExpression type, AST value, FieldAttributes attributes, CustomAttributeList customAttributes)
: base(context){
this.attributes = attributes | FieldAttributes.InitOnly;
this.customAttributes = customAttributes;
this.completion = new Completion();
this.identifier = identifier;
this.name = identifier.ToString();
this.value = value;
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();
if (current_scope is ClassScope){
if (this.name == ((ClassScope)current_scope).name){
identifier.context.HandleError(JSError.CannotUseNameOfClass);
this.name = this.name + " const";
}
if (attributes == 0) attributes = FieldAttributes.Public;
}else{
if (attributes != 0)
this.context.HandleError(JSError.NotInsideClass);
attributes = FieldAttributes.Public;
}
FieldInfo field = ((IActivationObject)current_scope).GetLocalField(this.name);
if (field != null){
identifier.context.HandleError(JSError.DuplicateName, true);
this.name = this.name + " const";
}
if (current_scope is ActivationObject)
this.field = ((ActivationObject)current_scope).AddNewField(this.identifier.ToString(), value, attributes);
else
this.field = ((StackFrame)current_scope).AddNewField(this.identifier.ToString(), value, 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;
}
internal override Object Evaluate(){
if (this.value == null)
this.completion.value = this.field.value;
else
this.completion.value = this.value.Evaluate();
return this.completion;
}
internal override AST PartiallyEvaluate(){
this.field.attributeFlags &= ~FieldAttributes.InitOnly;
this.identifier.PartiallyEvaluateAsReference();
if (this.field.type != null)
this.field.type.PartiallyEvaluate();
ScriptObject scope = (ScriptObject)Globals.ScopeStack.Peek();
if (this.value != null){
this.value = this.value.PartiallyEvaluate();
this.identifier.SetPartialValue(this.value);
if (this.value is ConstantWrapper){
Object val = this.field.value = this.value.Evaluate();
if (this.field.type != null) this.field.value = Convert.Coerce(val, this.field.type, true);
if (this.field.IsStatic && (val is Type || val is ClassScope || val is TypedArray ||
Convert.GetTypeCode(val) != TypeCode.Object)){
this.field.attributeFlags |= FieldAttributes.Literal;
goto set_field_type;
}
}
this.field.attributeFlags |= FieldAttributes.InitOnly;
set_field_type:
if (this.field.type == null)
this.field.type = new TypeExpression(new ConstantWrapper(this.value.InferType(null), null));
}else{
this.value = new ConstantWrapper(null, this.context);
this.field.attributeFlags |= FieldAttributes.InitOnly;
}
// 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){
if ((this.field.attributeFlags & FieldAttributes.Literal) != 0){
Object val = this.field.value;
if (val is Type || val is ClassScope || val is TypedArray){
this.field.attributeFlags &= ~FieldAttributes.Literal;
this.identifier.TranslateToILPreSet(il);
this.identifier.TranslateToILSet(il, new ConstantWrapper(val, null));
this.field.attributeFlags |= FieldAttributes.Literal;
}
}else{
if (!this.field.IsStatic){
FieldBuilder fb = this.valueField = this.field.metaData as FieldBuilder;
if (fb != null)
this.field.metaData = ((TypeBuilder)fb.DeclaringType).DefineField(this.name+" value", this.field.type.ToType(), FieldAttributes.Private);
}
this.field.attributeFlags &= ~FieldAttributes.InitOnly;
this.identifier.TranslateToILPreSet(il);
this.identifier.TranslateToILSet(il, this.value);
this.field.attributeFlags |= FieldAttributes.InitOnly;
}
}
internal void TranslateToILInitOnlyInitializers(ILGenerator il){
FieldBuilder fb = this.valueField;
if (fb != null){
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Dup);
il.Emit(OpCodes.Ldfld, (FieldBuilder)this.field.metaData);
il.Emit(OpCodes.Stfld, fb);
this.valueField = (FieldBuilder)this.field.metaData;
this.field.metaData = fb;
}
}
internal override void TranslateToILInitializer(ILGenerator il){
}
}
}