/* * Copyright 2013-2017 consulo.io * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package consulo.csharp.lang.psi.impl.resolve.additionalMembersImpl; import org.jetbrains.annotations.NotNull; import consulo.annotations.RequiredReadAction; import consulo.csharp.lang.psi.CSharpConstructorDeclaration; import consulo.csharp.lang.psi.CSharpMethodDeclaration; import consulo.csharp.lang.psi.CSharpModifier; import consulo.csharp.lang.psi.CSharpTypeDeclaration; import consulo.csharp.lang.psi.impl.light.builder.CSharpLightConstructorDeclarationBuilder; import consulo.csharp.lang.psi.impl.light.builder.CSharpLightParameterBuilder; import consulo.csharp.lang.psi.impl.resolve.CSharpAdditionalMemberProvider; import consulo.csharp.lang.psi.impl.source.resolve.type.CSharpLambdaTypeRef; import consulo.csharp.lang.psi.impl.source.resolve.type.wrapper.GenericUnwrapTool; import consulo.csharp.lang.psi.impl.source.resolve.util.CSharpResolveUtil; import consulo.dotnet.psi.DotNetElement; import consulo.dotnet.psi.DotNetGenericParameter; import consulo.dotnet.psi.DotNetNamedElement; import consulo.dotnet.resolve.DotNetGenericExtractor; import com.intellij.openapi.util.Condition; import com.intellij.psi.PsiElement; import com.intellij.util.Consumer; import com.intellij.util.containers.ContainerUtil; /** * @author VISTALL * @since 26.10.14 */ public class StructOrGenericParameterConstructorProvider implements CSharpAdditionalMemberProvider { @RequiredReadAction @Override public void processAdditionalMembers(@NotNull DotNetElement element, @NotNull DotNetGenericExtractor extractor, @NotNull Consumer<PsiElement> consumer) { if(element instanceof CSharpTypeDeclaration && ((CSharpTypeDeclaration) element).isStruct()) { CSharpTypeDeclaration typeDeclaration = (CSharpTypeDeclaration) element; DotNetNamedElement parameterlessConstructor = ContainerUtil.find(typeDeclaration.getMembers(), new Condition<DotNetNamedElement>() { @Override public boolean value(DotNetNamedElement element) { if(element instanceof CSharpConstructorDeclaration && !((CSharpConstructorDeclaration) element).isDeConstructor()) { if(((CSharpConstructorDeclaration) element).getParameters().length == 0) { return true; } } return false; } }); if(parameterlessConstructor == null) { buildDefaultConstructor((DotNetNamedElement) element, CSharpModifier.PUBLIC, extractor, consumer); } } else if(element instanceof CSharpTypeDeclaration) { CSharpTypeDeclaration typeDeclaration = (CSharpTypeDeclaration) element; DotNetNamedElement anyConstructor = ContainerUtil.find(typeDeclaration.getMembers(), new Condition<DotNetNamedElement>() { @Override public boolean value(DotNetNamedElement element) { return element instanceof CSharpConstructorDeclaration && !((CSharpConstructorDeclaration) element).isDeConstructor(); } }); if(anyConstructor == null) { buildDefaultConstructor((DotNetNamedElement) element, CSharpModifier.PUBLIC, extractor, consumer); } } else if(element instanceof DotNetGenericParameter) { // we need always create constructor, it ill check in CS0304 buildDefaultConstructor((DotNetNamedElement) element, CSharpModifier.PUBLIC, extractor, consumer); } } @NotNull @Override public Target getTarget() { return Target.CONSTRUCTOR; } @RequiredReadAction private static void buildDefaultConstructor(@NotNull DotNetNamedElement element, @NotNull CSharpModifier modifier, @NotNull DotNetGenericExtractor extractor, @NotNull Consumer<PsiElement> consumer) { String name = element.getName(); if(name == null) { return; } CSharpLightConstructorDeclarationBuilder builder = new CSharpLightConstructorDeclarationBuilder(element); builder.addModifier(modifier); builder.setNavigationElement(element); builder.withParent(element); builder.withName(name); CSharpMethodDeclaration delegatedMethod = element.getUserData(CSharpResolveUtil.DELEGATE_METHOD_TYPE); if(delegatedMethod != null) { CSharpLightParameterBuilder parameter = new CSharpLightParameterBuilder(element.getProject()); parameter = parameter.withName("p"); CSharpMethodDeclaration extractedMethod = GenericUnwrapTool.extract(delegatedMethod, extractor); parameter = parameter.withTypeRef(new CSharpLambdaTypeRef(extractedMethod)); builder.addParameter(parameter); } consumer.consume(builder); } }