private void setPartialMethodModifiers(MethodDeclarationNode methodDeclaration, MethodBuilder methodBuilder) { foreach (var modifier in methodDeclaration.Modifiers) { switch (modifier) { case Final: break; case Static: methodBuilder.setStatic(true); break; case Synchronized: methodBuilder.setSynchronized(true); break; case Strictfp: methodBuilder.setStrict(true); break; default: context.addError(CompileErrorId.UnexpectedModifier, methodDeclaration, modifier.toString().toLowerCase()); break; } } methodBuilder.setPrivate(true); }
private void defineInterfaceMethod(MethodDeclarationNode methodDeclaration, TypeBuilder typeBuilder) { var packageName = typeBuilder.PackageName; var name = context.getIdentifier(methodDeclaration.NameOffset, methodDeclaration.NameLength); var methodBuilder = lookupMethod(typeBuilder, methodDeclaration.TypeParameters, methodDeclaration.Parameters, name); if (methodBuilder != null) { context.addError(CompileErrorId.AlreadyDefinedMethod, methodDeclaration, BytecodeHelper.getDisplayName(typeBuilder), name); } methodBuilder = typeBuilder.defineMethod(context.getIdentifier(methodDeclaration.NameOffset, methodDeclaration.NameLength)); methodDeclaration.addUserData(methodBuilder); setTypeParameters(methodBuilder, methodDeclaration.TypeParameters, methodDeclaration); context.MemberResolver.enterMethod(methodBuilder); try { methodBuilder.setPublic(true); methodBuilder.setAbstract(true); methodBuilder.setReturnType(CompilerHelper.resolveTypeReference(context, packageName, methodDeclaration.ReturnType)); foreach (var p in methodDeclaration.Parameters) { var pb = methodBuilder.addParameter(CompilerHelper.resolveTypeReference(context, packageName, p.Type)); pb.setName(context.getIdentifier(p.NameOffset, p.NameLength)); if (p.Modifier == ParameterModifier.Params) { methodBuilder.setVarargs(true); } } setMethodConstraints(methodDeclaration.ConstraintsClauses, methodBuilder); } finally { context.MemberResolver.leaveMethod(); } }
private void setMethodModifiers(MethodDeclarationNode methodDeclaration, MethodBuilder methodBuilder) { var isFinal = true; foreach (var modifier in methodDeclaration.Modifiers) { switch (modifier) { case Public: if (methodBuilder.IsPrivate || methodBuilder.IsProtected) { context.addError(CompileErrorId.PublicProtectedPrivate, methodDeclaration); } else { methodBuilder.setPublic(true); } break; case Protected: if (methodBuilder.IsPrivate || methodBuilder.IsPublic) { context.addError(CompileErrorId.PublicProtectedPrivate, methodDeclaration); } else { methodBuilder.setProtected(true); } break; case Private: if (methodBuilder.IsProtected || methodBuilder.IsPublic) { context.addError(CompileErrorId.PublicProtectedPrivate, methodDeclaration); } else { methodBuilder.setPrivate(true); isFinal = false; } break; case Final: if (methodBuilder.IsAbstract) { context.addError(CompileErrorId.FinalAbstractStaticMethod, methodDeclaration); } else { methodBuilder.setFinal(true); } break; case Abstract: if (methodBuilder.IsFinal || methodBuilder.IsStatic) { context.addError(CompileErrorId.FinalAbstractStaticMethod, methodDeclaration); } else { methodBuilder.setAbstract(true); isFinal = false; } break; case Static: if (methodBuilder.IsAbstract) { context.addError(CompileErrorId.FinalAbstractStaticMethod, methodDeclaration); } else { methodBuilder.setStatic(true); } break; case Synchronized: methodBuilder.setSynchronized(true); break; case Native: methodBuilder.setNative(true); break; case Strictfp: methodBuilder.setStrict(true); break; case Virtual: case Override: // TODO: check if not private isFinal = false; break; default: context.addError(CompileErrorId.UnexpectedModifier, methodDeclaration, modifier.toString().toLowerCase()); break; } } methodBuilder.setFinal(isFinal); }
private void defineClassMethod(MethodDeclarationNode methodDeclaration, bool partial, TypeBuilder typeBuilder) { var name = context.getIdentifier(methodDeclaration.NameOffset, methodDeclaration.NameLength); if (name.equals("finalize") && methodDeclaration.Parameters.size() == 0) { context.addError(CompileErrorId.FinalizeMethodOverride, methodDeclaration); } if (methodDeclaration.IsPartial) { if (!partial) { context.addError(CompileErrorId.PartialMethodWithinPartialClass, methodDeclaration); } if (methodDeclaration.ReturnType != context.TypeSystem.VoidType) { context.addError(CompileErrorId.PartialMethodNotVoid, methodDeclaration); } } var methodBuilder = lookupMethod(typeBuilder, methodDeclaration.TypeParameters, methodDeclaration.Parameters, name); if (methodBuilder != null) { if (!methodDeclaration.IsPartial) { context.addError(CompileErrorId.AlreadyDefinedMethod, methodDeclaration, BytecodeHelper.getDisplayName(typeBuilder), name); return; } var partialInfo = partialTypes[typeBuilder.FullName]; if (!partialInfo.partialMethods.containsKey(methodBuilder)) { context.addError(CompileErrorId.AlreadyDefinedMethod, methodDeclaration, BytecodeHelper.getDisplayName(typeBuilder), name); } var partialMethodInfo = partialInfo.partialMethods[methodBuilder]; if (methodDeclaration.Body == null) { if (partialMethodInfo.definingPart != null) { context.addError(CompileErrorId.MultiplePartialDefiningDeclarations, methodDeclaration); } partialMethodInfo.definingPart = methodDeclaration; } else { if (partialMethodInfo.implementingPart != null) { context.addError(CompileErrorId.MultiplePartialImplementingDeclarations, methodDeclaration); } partialMethodInfo.implementingPart = methodDeclaration; } setPartialMethodModifiers(methodDeclaration, methodBuilder); setMethodConstraints(methodDeclaration.ConstraintsClauses, methodBuilder); methodDeclaration.addUserData(methodBuilder); } else { methodBuilder = typeBuilder.defineMethod(name); methodDeclaration.addUserData(methodBuilder); setTypeParameters(methodBuilder, methodDeclaration.TypeParameters, methodDeclaration); context.MemberResolver.enterMethod(methodBuilder); try { setMethodModifiers(methodDeclaration, methodBuilder); var returnType = CompilerHelper.resolveTypeReference(context, typeBuilder.PackageName, methodDeclaration.ReturnType); methodBuilder.setReturnType(returnType); var i = 0; foreach (var parameter in methodDeclaration.Parameters) { var type = CompilerHelper.resolveTypeReference(context, typeBuilder.PackageName, parameter.Type); var paramBuilder = methodBuilder.addParameter(type); paramBuilder.setName(context.getIdentifier(parameter.NameOffset, parameter.NameLength)); if (parameter.Modifier == ParameterModifier.Params) { if (i < methodDeclaration.Parameters.size() - 1) { context.addError(CompileErrorId.ParamsNotLast, parameter); } if (!type.IsArray) { context.addError(CompileErrorId.ParamsNotArray, parameter); } methodBuilder.setVarargs(true); } else if (parameter.Modifier == ParameterModifier.This) { if (!methodBuilder.IsStatic) { context.addError(CompileErrorId.ThisParameterNotStatic, parameter); } if (i > 0) { context.addError(CompileErrorId.ThisNotFirst, parameter); } methodBuilder.addAnnotation(context.getType("stab/lang/ExtensionMethod", parameter), false); } i++; } setMethodConstraints(methodDeclaration.ConstraintsClauses, methodBuilder); if (methodDeclaration.IsPartial) { var partialInfo = partialTypes[typeBuilder.getFullName()]; var partialMethodInfo = new PartialMethodInfo(); if (methodDeclaration.Body == null) { partialMethodInfo.definingPart = methodDeclaration; } else { partialMethodInfo.implementingPart = methodDeclaration; } partialInfo.partialMethods[methodBuilder] = partialMethodInfo; } } finally { context.MemberResolver.leaveMethod(); } } }
public void enterMethod(MethodDeclarationNode declaration) { methodInfos.add(declaration.getUserData(typeof(MethodInfo))); }
private ITypeMember parseFieldOrPropertyOrMethod(List<AnnotationSectionNode> annotations, EnumSet<Modifier> modifiers, bool partial, TypeReferenceNode type, int startPosition) { if (!isIdentifier(lexicalUnit)) { throw error(ParseErrorId.IdentifierExpected); } int sp = scanner.StartPosition; int len = getLexicalUnitLength(); saveScannerState(); var typeParameters = new ArrayList<SimpleNameTypeReferenceNode>(); nextLexicalUnit(true); parseTypeParameters(typeParameters); Modifier setterAccess = checkSetterAccess(); bool forceAsField = false; if (lexicalUnit == LexicalUnit.Multiply) { forceAsField = true; nextLexicalUnit(true); } switch (lexicalUnit) { case OpenParenthesis: if (setterAccess != Modifier.Public || forceAsField) { throw error(ParseErrorId.IdentifierExpected); } var methodDeclaration = new MethodDeclarationNode { IsPartial = partial, ReturnType = type, NameOffset = sp, NameLength = len, StartPosition = startPosition }; if (docCommentEndPosition > 0) { methodDeclaration.DocumentationOffset = docCommentStartPosition; methodDeclaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition; docCommentEndPosition = 0; } setSavedScannerState(methodDeclaration); methodDeclaration.Modifiers.addAll(modifiers); methodDeclaration.Annotations.addAll(annotations); foreach (var t in typeParameters) { if (t.TypeReferenceKind != TypeReferenceKind.SimpleName || t.TypeArguments.size() > 0) { throw error(ParseErrorId.SimpleNameExpected); } methodDeclaration.TypeParameters.add((SimpleNameTypeReferenceNode)t); } if (nextLexicalUnit(true) != LexicalUnit.CloseParenthesis) { parseFormalParameters(methodDeclaration.Parameters, LexicalUnit.CloseParenthesis); } else { nextLexicalUnit(true); } parseTypeParameterConstraintsClauses(methodDeclaration.ConstraintsClauses); switch (lexicalUnit) { case OpenBrace: methodDeclaration.Body = parseBlockStatement(); methodDeclaration.EndPosition = methodDeclaration.Body.EndPosition; break; case SemiColon: methodDeclaration.EndPosition = scanner.EndPosition; nextLexicalUnit(true); break; default: throw error(ParseErrorId.OpenBraceExpected); } return methodDeclaration; case OpenBrace: if (setterAccess != Modifier.Public || forceAsField) { throw error(ParseErrorId.IdentifierExpected); } var propertyDeclaration = new PropertyDeclarationNode { Type = type, NameOffset = sp, NameLength = len, StartPosition = startPosition }; if (docCommentEndPosition > 0) { propertyDeclaration.DocumentationOffset = docCommentStartPosition; propertyDeclaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition; docCommentEndPosition = 0; } setSavedScannerState(propertyDeclaration); propertyDeclaration.Modifiers.addAll(modifiers); nextLexicalUnit(true); parseAccessorDeclaration(propertyDeclaration, false); if (lexicalUnit != LexicalUnit.CloseBrace) { parseAccessorDeclaration(propertyDeclaration, false); } docCommentEndPosition = 0; propertyDeclaration.EndPosition = scanner.EndPosition; nextLexicalUnit(false); return propertyDeclaration; case Assign: { if (setterAccess != Modifier.Public || forceAsField) { throw error(ParseErrorId.IdentifierExpected); } var declaration = new FieldDeclarationNode { Type = type, StartPosition = startPosition }; if (docCommentEndPosition > 0) { declaration.DocumentationOffset = docCommentStartPosition; declaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition; docCommentEndPosition = 0; } setSavedScannerState(declaration); declaration.Modifiers.addAll(modifiers); declaration.Annotations.addAll(annotations); nextLexicalUnit(true); var decl = new VariableDeclaratorNode { NameOffset = sp, NameLength = len }; setSavedScannerState(decl); decl.Value = parseFieldInitializer(); decl.EndPosition = decl.Value.EndPosition; declaration.Declarators.add(decl); while (lexicalUnit == LexicalUnit.Comma) { if (!isIdentifier(nextLexicalUnit(true))) { throw error(ParseErrorId.IdentifierExpected); } decl = new VariableDeclaratorNode { NameOffset = scanner.StartPosition, NameLength = getLexicalUnitLength() }; setScannerState(decl); decl.EndPosition = scanner.EndPosition; declaration.Declarators.add(decl); if (nextLexicalUnit(true) == LexicalUnit.Assign) { nextLexicalUnit(true); decl.Value = parseFieldInitializer(); decl.EndPosition = decl.Value.EndPosition; } } docCommentEndPosition = 0; declaration.EndPosition = parseSemiColon(false, false); return declaration; } case Comma: { if (setterAccess != Modifier.Public || forceAsField) { throw error(ParseErrorId.IdentifierExpected); } var declaration = new FieldDeclarationNode { Type = type, StartPosition = startPosition }; if (docCommentEndPosition > 0) { declaration.DocumentationOffset = docCommentStartPosition; declaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition; docCommentEndPosition = 0; } setSavedScannerState(declaration); declaration.Modifiers.addAll(modifiers); declaration.Annotations.addAll(annotations); var decl = new VariableDeclaratorNode { NameOffset = sp, NameLength = len }; setSavedScannerState(decl); decl.EndPosition = sp + len; declaration.Declarators.add(decl); do { if (!isIdentifier(nextLexicalUnit(true))) { throw error(ParseErrorId.IdentifierExpected); } decl = new VariableDeclaratorNode { NameOffset = scanner.StartPosition, NameLength = getLexicalUnitLength() }; setScannerState(decl); declaration.Declarators.add(decl); decl.EndPosition = scanner.EndPosition; if (nextLexicalUnit(true) == LexicalUnit.Assign) { nextLexicalUnit(true); decl.Value = parseFieldInitializer(); decl.EndPosition = decl.Value.EndPosition; } } while (lexicalUnit == LexicalUnit.Comma); docCommentEndPosition = 0; declaration.EndPosition = parseSemiColon(false, false); return declaration; } case SemiColon: { if ((modifiers.contains(Modifier.Public) || modifiers.contains(Modifier.Protected)) && !forceAsField) { var propertyShortDeclaration = new PropertyDeclarationNode { Type = type, NameOffset = sp, NameLength = len, StartPosition = startPosition }; if (docCommentEndPosition > 0) { propertyShortDeclaration.DocumentationOffset = docCommentStartPosition; propertyShortDeclaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition; docCommentEndPosition = 0; } setSavedScannerState(propertyShortDeclaration); propertyShortDeclaration.Modifiers.addAll(modifiers); fakeParseShortProperty(propertyShortDeclaration, setterAccess, false); docCommentEndPosition = 0; propertyShortDeclaration.EndPosition = scanner.EndPosition; nextLexicalUnit(false); return propertyShortDeclaration; } var declaration = new FieldDeclarationNode { Type = type, StartPosition = startPosition }; if (docCommentEndPosition > 0) { declaration.DocumentationOffset = docCommentStartPosition; declaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition; docCommentEndPosition = 0; } setSavedScannerState(declaration); declaration.Modifiers.addAll(modifiers); declaration.Annotations.addAll(annotations); var decl = new VariableDeclaratorNode { NameOffset = sp, NameLength = len }; setSavedScannerState(decl); decl.EndPosition = sp + len; declaration.Declarators.add(decl); docCommentEndPosition = 0; declaration.EndPosition = scanner.EndPosition; nextLexicalUnit(false); return declaration; } default: throw error(ParseErrorId.UnexpectedLexicalUnit); } }
private IInterfaceMember parseInterfaceMember(List<AnnotationSectionNode> annotations, EnumSet<Modifier> modifiers, int startPosition) { var type = parseType(true, true); if (lexicalUnit == LexicalUnit.Keyword && scanner.Keyword == Keyword.This) { saveScannerState(); nextLexicalUnit(true); return parseIndexerDeclaration(annotations, modifiers, false, type, true, startPosition); } if (!isIdentifier(lexicalUnit)) { throw error(ParseErrorId.IdentifierExpected); } int sp = scanner.StartPosition; int len = getLexicalUnitLength(); saveScannerState(); var lexicalUnitShorter = nextLexicalUnit(true); if (lexicalUnitShorter == LexicalUnit.OpenBrace) { var declaration = new PropertyDeclarationNode { Type = type, NameOffset = sp, NameLength = len, StartPosition = startPosition }; if (docCommentEndPosition > 0) { declaration.DocumentationOffset = docCommentStartPosition; declaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition; docCommentEndPosition = 0; } setSavedScannerState(declaration); declaration.Modifiers.addAll(modifiers); declaration.Annotations.addAll(annotations); nextLexicalUnit(true); parseAccessorDeclaration(declaration, true); if (lexicalUnit != LexicalUnit.CloseBrace) { parseAccessorDeclaration(declaration, true); } declaration.EndPosition = scanner.EndPosition; nextLexicalUnit(false); return declaration; } Modifier setterAccess = Modifier.Public; if (lexicalUnitShorter == LexicalUnit.Xor) { setterAccess = Modifier.Private; lexicalUnitShorter = nextLexicalUnit(true); } if (lexicalUnitShorter == LexicalUnit.SemiColon) { var propertyShortDeclaration = new PropertyDeclarationNode { Type = type, NameOffset = sp, NameLength = len, StartPosition = startPosition }; if (docCommentEndPosition > 0) { propertyShortDeclaration.DocumentationOffset = docCommentStartPosition; propertyShortDeclaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition; docCommentEndPosition = 0; } setSavedScannerState(propertyShortDeclaration); propertyShortDeclaration.Modifiers.addAll(modifiers); propertyShortDeclaration.Annotations.addAll(annotations); fakeParseShortProperty(propertyShortDeclaration, setterAccess, true); docCommentEndPosition = 0; propertyShortDeclaration.EndPosition = scanner.EndPosition; nextLexicalUnit(false); return propertyShortDeclaration; } var declaration = new MethodDeclarationNode { ReturnType = type, NameOffset = sp, NameLength = len, StartPosition = startPosition }; if (docCommentEndPosition > 0) { declaration.DocumentationOffset = docCommentStartPosition; declaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition; docCommentEndPosition = 0; } setSavedScannerState(declaration); declaration.Modifiers.addAll(modifiers); declaration.Annotations.addAll(annotations); parseTypeParameters(declaration.TypeParameters); if (lexicalUnit != LexicalUnit.OpenParenthesis) { throw error(ParseErrorId.OpenParenthesisExpected); } if (nextLexicalUnit(true) != LexicalUnit.CloseParenthesis) { parseFormalParameters(declaration.Parameters, LexicalUnit.CloseParenthesis); } else { nextLexicalUnit(true); } if (lexicalUnit == LexicalUnit.Assign) { nextLexicalUnit(true); declaration.DefaultValue = parseAnnotationValue(); } else { parseTypeParameterConstraintsClauses(declaration.ConstraintsClauses); } docCommentEndPosition = 0; declaration.EndPosition = parseSemiColon(false, false); return declaration; }