internal bool IsPromotableTo(Type other) { Type bakedSuperType = this.GetBakedSuperType(); if (other.IsAssignableFrom(bakedSuperType)) { return(true); } if (other.IsInterface && this.ImplementsInterface(other)) { return(true); } EnumDeclaration owner = this.owner as EnumDeclaration; return((owner != null) && Microsoft.JScript.Convert.IsPromotableTo((IReflect)owner.baseType.ToType(), (IReflect)other)); }
internal bool IsPromotableTo(Type other) { Type st = this.GetBakedSuperType(); if (other.IsAssignableFrom(st)) { return(true); } if (other.IsInterface && this.ImplementsInterface(other)) { return(true); } EnumDeclaration ed = this.owner as EnumDeclaration; if (ed != null && Convert.IsPromotableTo(ed.baseType.ToType(), other)) { return(true); } return(false); }
//--------------------------------------------------------------------------------------- // ParseEnum // // Enum : // 'enum' identifier [':' baseType] EnumBody (in the guise of ClassBody with a param) // //--------------------------------------------------------------------------------------- private AST ParseEnum(FieldAttributes visibilitySpec, Context enumCtx, CustomAttributeList customAttributes){ IdentifierLiteral name = null; AST baseId = null; TypeExpression baseType = null; Block body = null; GetNextToken(); if (JSToken.Identifier == this.currentToken.token){ name = new IdentifierLiteral(this.scanner.GetIdentifier(), this.currentToken.Clone()); }else{ ReportError(JSError.NoIdentifier); if (JSToken.Colon != this.currentToken.token && JSToken.LeftCurly != this.currentToken.token) SkipTokensAndThrow(); // what the is this? name = new IdentifierLiteral("##Missing Enum Name##" + s_cDummyName++, CurrentPositionContext()); } GetNextToken(); if (JSToken.Colon == this.currentToken.token){ this.noSkipTokenSet.Add(NoSkipTokenSet.s_EnumBaseTypeNoSkipTokenSet); try{ baseId = ParseQualifiedIdentifier(JSError.NeedType); }catch(RecoveryTokenException exc){ if (IndexOfToken(NoSkipTokenSet.s_ClassExtendsNoSkipTokenSet, exc) == -1){ exc._partiallyComputedNode = null; throw exc; }else{ baseId = exc._partiallyComputedNode; } }finally{ this.noSkipTokenSet.Remove(NoSkipTokenSet.s_EnumBaseTypeNoSkipTokenSet); } } if (baseId != null) baseType = new TypeExpression(baseId); if (JSToken.LeftCurly != this.currentToken.token) ReportError(JSError.NoLeftCurly); // make a new state and save the old one ArrayList blockType = this.blockType; this.blockType = new ArrayList(16); SimpleHashtable labelTable = this.labelTable; this.labelTable = new SimpleHashtable(16); Globals.ScopeStack.Push(new ClassScope(name, ((IActivationObject)Globals.ScopeStack.Peek()).GetGlobalScope())); //Give declarations a place to go while building AST try{ body = ParseClassBody(true, false); enumCtx.UpdateWith(body.context); EnumDeclaration result = new EnumDeclaration(enumCtx, name, baseType, body, visibilitySpec, customAttributes); if (customAttributes != null) customAttributes.SetTarget(result); return result; }catch(RecoveryTokenException exc){ enumCtx.UpdateWith(exc._partiallyComputedNode.context); exc._partiallyComputedNode = new EnumDeclaration(enumCtx, name, baseType, (Block)exc._partiallyComputedNode, visibilitySpec, customAttributes); if (customAttributes != null) customAttributes.SetTarget(exc._partiallyComputedNode); throw exc; }finally{ Globals.ScopeStack.Pop(); this.blockType = blockType; this.labelTable = labelTable; } }
private AST ParseEnum(FieldAttributes visibilitySpec, Context enumCtx, CustomAttributeList customAttributes) { IdentifierLiteral name = null; AST ast = null; TypeExpression baseType = null; Block body = null; AST ast2; this.GetNextToken(); if (JSToken.Identifier == this.currentToken.token) { name = new IdentifierLiteral(this.scanner.GetIdentifier(), this.currentToken.Clone()); } else { this.ReportError(JSError.NoIdentifier); if ((JSToken.Colon != this.currentToken.token) && (JSToken.LeftCurly != this.currentToken.token)) { this.SkipTokensAndThrow(); } name = new IdentifierLiteral("##Missing Enum Name##" + s_cDummyName++, this.CurrentPositionContext()); } this.GetNextToken(); if (JSToken.Colon == this.currentToken.token) { this.noSkipTokenSet.Add(NoSkipTokenSet.s_EnumBaseTypeNoSkipTokenSet); try { ast = this.ParseQualifiedIdentifier(JSError.NeedType); } catch (RecoveryTokenException exception) { if (this.IndexOfToken(NoSkipTokenSet.s_ClassExtendsNoSkipTokenSet, exception) == -1) { exception._partiallyComputedNode = null; throw exception; } ast = exception._partiallyComputedNode; } finally { this.noSkipTokenSet.Remove(NoSkipTokenSet.s_EnumBaseTypeNoSkipTokenSet); } } if (ast != null) { baseType = new TypeExpression(ast); } if (JSToken.LeftCurly != this.currentToken.token) { this.ReportError(JSError.NoLeftCurly); } ArrayList blockType = this.blockType; this.blockType = new ArrayList(0x10); SimpleHashtable labelTable = this.labelTable; this.labelTable = new SimpleHashtable(0x10); this.Globals.ScopeStack.Push(new ClassScope(name, ((IActivationObject) this.Globals.ScopeStack.Peek()).GetGlobalScope())); try { body = this.ParseClassBody(true, false); enumCtx.UpdateWith(body.context); EnumDeclaration target = new EnumDeclaration(enumCtx, name, baseType, body, visibilitySpec, customAttributes); if (customAttributes != null) { customAttributes.SetTarget(target); } ast2 = target; } catch (RecoveryTokenException exception2) { enumCtx.UpdateWith(exception2._partiallyComputedNode.context); exception2._partiallyComputedNode = new EnumDeclaration(enumCtx, name, baseType, (Block) exception2._partiallyComputedNode, visibilitySpec, customAttributes); if (customAttributes != null) { customAttributes.SetTarget(exception2._partiallyComputedNode); } throw exception2; } finally { this.Globals.ScopeStack.Pop(); this.blockType = blockType; this.labelTable = labelTable; } return ast2; }