mirror of
https://github.com/SSCLI/sscli_20021101
synced 2026-06-08 12:28:57 +00:00
9fa3874800
Moved the original file to the archive subfolder.
237 lines
8.1 KiB
C#
237 lines
8.1 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.Collections;
|
|
using System.Reflection;
|
|
using System.Reflection.Emit;
|
|
|
|
public sealed class Block : AST{
|
|
private Completion completion;
|
|
private ArrayList list;
|
|
|
|
internal Block(Context context)
|
|
: base(context) {
|
|
this.completion = new Completion();
|
|
this.list = new ArrayList();
|
|
}
|
|
|
|
internal void Append(AST elem){
|
|
this.list.Add(elem);
|
|
}
|
|
|
|
internal void ComplainAboutAnythingOtherThanClassOrPackage(){
|
|
for (int i = 0, n = this.list.Count; i < n; i++){
|
|
Object elem = this.list[i];
|
|
if (elem is Class || elem is Package || elem is Import) continue;
|
|
Block b = elem as Block;
|
|
if (b != null && b.list.Count == 0) continue;
|
|
Expression e = elem as Expression;
|
|
if (e != null && e.operand is AssemblyCustomAttributeList) continue;
|
|
((AST)elem).context.HandleError(JSError.OnlyClassesAndPackagesAllowed);
|
|
return;
|
|
}
|
|
}
|
|
|
|
internal override Object Evaluate(){
|
|
this.completion.Continue = 0;
|
|
this.completion.Exit = 0;
|
|
this.completion.value = null;
|
|
for (int i = 0, n = this.list.Count; i < n; i++){
|
|
AST elem = (AST)(this.list[i]);
|
|
Object val;
|
|
try{
|
|
val = elem.Evaluate();
|
|
}catch(JScriptException e){
|
|
if (e.context == null){
|
|
e.context = elem.context;
|
|
}
|
|
throw e;
|
|
}
|
|
Completion c = (Completion)val;
|
|
if (c.value != null)
|
|
this.completion.value = c.value;
|
|
if (c.Continue > 1){
|
|
this.completion.Continue = c.Continue - 1;
|
|
break;
|
|
}
|
|
if (c.Exit > 0){
|
|
this.completion.Exit = c.Exit - 1;
|
|
break;
|
|
}
|
|
if (c.Return)
|
|
return c;
|
|
}
|
|
return this.completion;
|
|
}
|
|
|
|
internal void EvaluateStaticVariableInitializers(){
|
|
for (int i = 0, n = this.list.Count; i < n; i++){
|
|
Object elem = this.list[i];
|
|
VariableDeclaration vard = elem as VariableDeclaration;
|
|
if (vard != null && vard.field.IsStatic && !vard.field.IsLiteral){
|
|
vard.Evaluate();
|
|
continue;
|
|
}
|
|
StaticInitializer sinit = elem as StaticInitializer;
|
|
if (sinit != null){
|
|
sinit.Evaluate();
|
|
continue;
|
|
}
|
|
Class cl = elem as Class;
|
|
if (cl != null){
|
|
cl.Evaluate();
|
|
continue;
|
|
}
|
|
Constant cnst = elem as Constant;
|
|
if (cnst != null && cnst.field.IsStatic){
|
|
cnst.Evaluate();
|
|
continue;
|
|
}
|
|
Block block = elem as Block;
|
|
if (block != null)
|
|
block.EvaluateStaticVariableInitializers();
|
|
}
|
|
}
|
|
|
|
internal void EvaluateInstanceVariableInitializers(){
|
|
for (int i = 0, n = this.list.Count; i < n; i++){
|
|
Object elem = this.list[i];
|
|
VariableDeclaration vard = elem as VariableDeclaration;
|
|
if (vard != null && !vard.field.IsStatic && !vard.field.IsLiteral){
|
|
vard.Evaluate();
|
|
continue;
|
|
}
|
|
Block block = elem as Block;
|
|
if (block != null)
|
|
block.EvaluateInstanceVariableInitializers();
|
|
}
|
|
}
|
|
|
|
internal override bool HasReturn(){
|
|
for (int i = 0, n = this.list.Count; i < n; i++){
|
|
AST elem = (AST)(this.list[i]);
|
|
if (elem.HasReturn())
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
internal void ProcessAssemblyAttributeLists(){
|
|
for (int i = 0, n = this.list.Count; i < n; i++){
|
|
Expression expr = this.list[i] as Expression;
|
|
if (expr != null){
|
|
AssemblyCustomAttributeList acl = expr.operand as AssemblyCustomAttributeList;
|
|
if (acl != null) acl.Process();
|
|
}
|
|
}
|
|
}
|
|
|
|
internal void MarkSuperOKIfIsFirstStatement(){
|
|
if (this.list.Count > 0 && this.list[0] is ConstructorCall)
|
|
((ConstructorCall)this.list[0]).isOK = true;
|
|
}
|
|
|
|
internal override AST PartiallyEvaluate(){
|
|
for (int i = 0, n = this.list.Count; i < n; i++){
|
|
AST elem = (AST)(this.list[i]);
|
|
this.list[i] = elem.PartiallyEvaluate();
|
|
}
|
|
return this;
|
|
}
|
|
|
|
internal Expression ToExpression(){
|
|
if (this.list.Count == 1 && this.list[0] is Expression)
|
|
return (Expression)this.list[0];
|
|
else
|
|
return null;
|
|
}
|
|
|
|
internal override void TranslateToIL(ILGenerator il, Type rtype){
|
|
//This assumes that rtype == Void.class
|
|
Label lab = il.DefineLabel();
|
|
compilerGlobals.BreakLabelStack.Push(lab);
|
|
compilerGlobals.ContinueLabelStack.Push(lab);
|
|
for (int i = 0, n = this.list.Count; i < n; i++){
|
|
AST elem = (AST)(this.list[i]);
|
|
elem.TranslateToIL(il, Typeob.Void);
|
|
}
|
|
il.MarkLabel(lab);
|
|
compilerGlobals.BreakLabelStack.Pop();
|
|
compilerGlobals.ContinueLabelStack.Pop();
|
|
}
|
|
|
|
internal override void TranslateToILInitializer(ILGenerator il){
|
|
for (int i = 0, n = this.list.Count; i < n; i++){
|
|
AST elem = (AST)(this.list[i]);
|
|
elem.TranslateToILInitializer(il);
|
|
}
|
|
}
|
|
|
|
internal void TranslateToILInitOnlyInitializers(ILGenerator il){
|
|
for (int i = 0, n = this.list.Count; i < n; i++){
|
|
Constant c = this.list[i] as Constant;
|
|
if (c != null) c.TranslateToILInitOnlyInitializers(il);
|
|
}
|
|
}
|
|
|
|
internal void TranslateToILInstanceInitializers(ILGenerator il){
|
|
for (int i = 0, n = this.list.Count; i < n; i++){
|
|
AST elem = (AST)(this.list[i]);
|
|
if (elem is VariableDeclaration && !((VariableDeclaration)elem).field.IsStatic && !((VariableDeclaration)elem).field.IsLiteral){
|
|
elem.TranslateToILInitializer(il);
|
|
elem.TranslateToIL(il, Typeob.Void);
|
|
}else if (elem is FunctionDeclaration && !((FunctionDeclaration)elem).func.isStatic)
|
|
elem.TranslateToILInitializer(il);
|
|
else if (elem is Constant && !((Constant)elem).field.IsStatic)
|
|
elem.TranslateToIL(il, Typeob.Void);
|
|
else if (elem is Block)
|
|
((Block)elem).TranslateToILInstanceInitializers(il);
|
|
}
|
|
}
|
|
|
|
internal void TranslateToILStaticInitializers(ILGenerator il){
|
|
for (int i = 0, n = this.list.Count; i < n; i++){
|
|
AST elem = (AST)(this.list[i]);
|
|
if (elem is VariableDeclaration && ((VariableDeclaration)elem).field.IsStatic){
|
|
elem.TranslateToILInitializer(il);
|
|
elem.TranslateToIL(il, Typeob.Void);
|
|
}else if (elem is StaticInitializer)
|
|
elem.TranslateToIL(il, Typeob.Void);
|
|
else if (elem is FunctionDeclaration && ((FunctionDeclaration)elem).func.isStatic)
|
|
elem.TranslateToILInitializer(il);
|
|
else if (elem is Class)
|
|
elem.TranslateToIL(il, Typeob.Void);
|
|
else if (elem is Constant && ((Constant)elem).field.IsStatic)
|
|
elem.TranslateToIL(il, Typeob.Void);
|
|
else if (elem is Block)
|
|
((Block)elem).TranslateToILStaticInitializers(il);
|
|
}
|
|
}
|
|
|
|
internal override Context GetFirstExecutableContext(){
|
|
for (int i = 0, n = this.list.Count; i < n; i++){
|
|
AST elem = (AST)(this.list[i]);
|
|
Context ctx;
|
|
if ((ctx = elem.GetFirstExecutableContext()) != null)
|
|
return ctx;
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
}
|