sysml-v2-lsp 0.26.0 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.27.0]
6
+
7
+ ### Fixed
8
+
9
+ - Removed the type-dependency cycle heuristic that reported false `circular-containment` errors for valid referential usages and recursive composite type structures (#101). Feature typing does not establish ownership or an instance-composition cycle (SysML v2.0 sections 7.6.3 and 8.3.6.4). Circular-specialization validation remains enabled.
10
+ - Updated vulnerable dependencies to Vitest/mocker 4.1.11, Hono 4.13.7, and js-yaml 4.3.2, addressing reported Dependabot alerts and newly discovered npm advisories.
11
+
5
12
  ## [0.26.0]
6
13
 
7
14
  ### Fixed
@@ -28709,7 +28709,7 @@ Package: \`${info.packageName}\``),info.documentation&&lines.push(`
28709
28709
  ${info.documentation}`),{contents:{kind:import_node7.MarkupKind.Markdown,value:lines.join(`
28710
28710
  `)}}}getWordAtPosition(text,line,character){let lines=text.split(`
28711
28711
  `);if(line>=lines.length)return;let lineText=lines[line];if(!(character>=lineText.length))return extractQualifiedNameAt(lineText,character)}rangeContainsPosition(range,position){let afterStart=position.line>range.start.line||position.line===range.start.line&&position.character>=range.start.character,beforeEnd=position.line<range.end.line||position.line===range.end.line&&position.character<=range.end.character;return afterStart&&beforeEnd}getRepairHint(code){switch(code){case"invalid-redefinition-multiplicity":return"Align the redefined feature multiplicity with its base feature bounds.";case"incompatible-port-types":return"Connect endpoints with matching port types, or update one endpoint type.";case"unresolved-constraint-reference":return"Fix the reference path or add the missing feature in the referenced type.";case"unresolved-type":return"Define/import the missing type or correct the type name.";case"invalid-multiplicity":return"Use a valid bound where lower <= upper and lower is non-negative.";default:return}}};var import_node8=__toESM(require_main3());var DEFINITION_KEYWORDS=new Set(["about","abstract","accept","action","actor","after","alias","all","allocate","allocation","analysis","assert","assign","assume","attribute","bind","binding","calc","case","comment","concern","connect","connection","constraint","decide","def","default","defined","dependency","derived","do","doc","else","end","entry","enum","event","exhibit","exit","expose","feature","filter","first","flow","for","fork","frame","from","if","import","in","include","individual","inout","interface","item","join","language","library","locale","merge","message","meta","metadata","multiplicity","namespace","nonunique","not","null","objective","occurrence","of","ordered","out","package","parallel","part","perform","port","private","protected","public","readonly","redefines","ref","references","render","rendering","rep","require","requirement","return","satisfy","send","snapshot","specializes","stakeholder","state","subject","subsets","succession","then","timeslice","to","transition","type","use","variant","variation","verification","verify","view","viewpoint","when","while","datatype"]);function levenshtein2(a,b){if(a.length<b.length){let t=a;a=b,b=t}let m2=a.length,n2=b.length,prev=new Uint16Array(n2+1),curr=new Uint16Array(n2+1);for(let j=0;j<=n2;j++)prev[j]=j;for(let i=1;i<=m2;i++){curr[0]=i;for(let j=1;j<=n2;j++){let cost=a.charCodeAt(i-1)===b.charCodeAt(j-1)?0:1;curr[j]=Math.min(prev[j]+1,curr[j-1]+1,prev[j-1]+cost)}[prev,curr]=[curr,prev]}return prev[n2]}function findClosestKeyword(identifier,maxDistance=2){let lower=identifier.toLowerCase();if(lower.length<4||DEFINITION_KEYWORDS.has(lower))return;let effectiveMax=lower.length<=5?1:maxDistance,bestMatch,bestDist=effectiveMax+1;for(let keyword of DEFINITION_KEYWORDS){if(Math.abs(keyword.length-lower.length)>maxDistance)continue;let dist=levenshtein2(lower,keyword);dist>0&&dist<bestDist&&(bestDist=dist,bestMatch=keyword)}return bestMatch}var KEYWORD_CONTINUATIONS=new Set([SysMLv2Lexer.IDENTIFIER,SysMLv2Lexer.COLON,SysMLv2Lexer.DEF,SysMLv2Lexer.LBRACE,SysMLv2Lexer.LBRACK,SysMLv2Lexer.ABOUT]),NAME_PRECEDING_KEYWORDS=new Set([SysMLv2Lexer.PART,SysMLv2Lexer.PORT,SysMLv2Lexer.ITEM,SysMLv2Lexer.ATTRIBUTE,SysMLv2Lexer.ACTION,SysMLv2Lexer.CALC,SysMLv2Lexer.STATE,SysMLv2Lexer.CONSTRAINT,SysMLv2Lexer.REQUIREMENT,SysMLv2Lexer.CONCERN,SysMLv2Lexer.CASE,SysMLv2Lexer.ANALYSIS,SysMLv2Lexer.VERIFICATION,SysMLv2Lexer.VIEW,SysMLv2Lexer.VIEWPOINT,SysMLv2Lexer.RENDERING,SysMLv2Lexer.METADATA,SysMLv2Lexer.PACKAGE,SysMLv2Lexer.NAMESPACE,SysMLv2Lexer.ENUM,SysMLv2Lexer.ALLOCATION,SysMLv2Lexer.CONNECTION,SysMLv2Lexer.INTERFACE,SysMLv2Lexer.OCCURRENCE,SysMLv2Lexer.INDIVIDUAL,SysMLv2Lexer.FLOW,SysMLv2Lexer.SUCCESSION,SysMLv2Lexer.BINDING,SysMLv2Lexer.MESSAGE,SysMLv2Lexer.TRANSITION,SysMLv2Lexer.TYPE,SysMLv2Lexer.CLASSIFIER,SysMLv2Lexer.DATATYPE,SysMLv2Lexer.CLASS,SysMLv2Lexer.STRUCT,SysMLv2Lexer.ASSOC,SysMLv2Lexer.METACLASS,SysMLv2Lexer.INTERACTION,SysMLv2Lexer.BEHAVIOR,SysMLv2Lexer.FUNCTION,SysMLv2Lexer.PREDICATE,SysMLv2Lexer.FEATURE,SysMLv2Lexer.CONNECTOR,SysMLv2Lexer.STEP,SysMLv2Lexer.EXPR,SysMLv2Lexer.BOOL,SysMLv2Lexer.INV,SysMLv2Lexer.MULTIPLICITY,SysMLv2Lexer.ALIAS,SysMLv2Lexer.COMMENT,SysMLv2Lexer.DOC,SysMLv2Lexer.REP,SysMLv2Lexer.DEPENDENCY,SysMLv2Lexer.IMPORT,SysMLv2Lexer.DEF,SysMLv2Lexer.REF,SysMLv2Lexer.ALL,SysMLv2Lexer.ABSTRACT,SysMLv2Lexer.VARIATION,SysMLv2Lexer.DERIVED,SysMLv2Lexer.COMPOSITE,SysMLv2Lexer.CONST,SysMLv2Lexer.CONSTANT,SysMLv2Lexer.VAR,SysMLv2Lexer.MEMBER,SysMLv2Lexer.RETURN,SysMLv2Lexer.PUBLIC,SysMLv2Lexer.PRIVATE,SysMLv2Lexer.PROTECTED,SysMLv2Lexer.IN,SysMLv2Lexer.OUT,SysMLv2Lexer.INOUT,SysMLv2Lexer.END,SysMLv2Lexer.ACTOR,SysMLv2Lexer.STAKEHOLDER,SysMLv2Lexer.SUBJECT,SysMLv2Lexer.VARIANT,SysMLv2Lexer.SNAPSHOT,SysMLv2Lexer.TIMESLICE,SysMLv2Lexer.FORK,SysMLv2Lexer.JOIN,SysMLv2Lexer.MERGE,SysMLv2Lexer.DECIDE,SysMLv2Lexer.PERFORM,SysMLv2Lexer.EXHIBIT,SysMLv2Lexer.INCLUDE,SysMLv2Lexer.SATISFY,SysMLv2Lexer.ASSERT,SysMLv2Lexer.VERIFY,SysMLv2Lexer.RENDER,SysMLv2Lexer.CONNECT,SysMLv2Lexer.ALLOCATE,SysMLv2Lexer.BIND,SysMLv2Lexer.EXPOSE,SysMLv2Lexer.EVENT,SysMLv2Lexer.FIRST,SysMLv2Lexer.THEN,SysMLv2Lexer.TO,SysMLv2Lexer.FROM,SysMLv2Lexer.REDEFINES,SysMLv2Lexer.SUBSETS,SysMLv2Lexer.SPECIALIZES,SysMLv2Lexer.REFERENCES,SysMLv2Lexer.CONJUGATES,SysMLv2Lexer.CHAINS,SysMLv2Lexer.CROSSES,SysMLv2Lexer.UNIONS,SysMLv2Lexer.INTERSECTS,SysMLv2Lexer.DIFFERENCES,SysMLv2Lexer.SPECIALIZATION,SysMLv2Lexer.CONJUGATION,SysMLv2Lexer.DISJOINING,SysMLv2Lexer.INVERTING,SysMLv2Lexer.FEATURING,SysMLv2Lexer.TYPING,SysMLv2Lexer.REDEFINITION,SysMLv2Lexer.SUBTYPE,SysMLv2Lexer.SUBCLASSIFIER,SysMLv2Lexer.SUBSET,SysMLv2Lexer.CONJUGATE,SysMLv2Lexer.DISJOINT,SysMLv2Lexer.INVERSE,SysMLv2Lexer.ASSUME,SysMLv2Lexer.REQUIRE,SysMLv2Lexer.FRAME,SysMLv2Lexer.OBJECTIVE,SysMLv2Lexer.ENTRY,SysMLv2Lexer.DO,SysMLv2Lexer.EXIT,SysMLv2Lexer.ACCEPT,SysMLv2Lexer.SEND,SysMLv2Lexer.ASSIGN,SysMLv2Lexer.TERMINATE,SysMLv2Lexer.FOR,SysMLv2Lexer.ABOUT,SysMLv2Lexer.BY,SysMLv2Lexer.FILTER,SysMLv2Lexer.NEW,SysMLv2Lexer.META,SysMLv2Lexer.OF,SysMLv2Lexer.COLON,SysMLv2Lexer.COLON_GT,SysMLv2Lexer.COLON_GT_GT,SysMLv2Lexer.COLON_COLON,SysMLv2Lexer.COLON_COLON_GT,SysMLv2Lexer.GT,SysMLv2Lexer.FAT_ARROW,SysMLv2Lexer.TILDE,SysMLv2Lexer.COMMA,SysMLv2Lexer.HASH,SysMLv2Lexer.AT]);function looksLikeKeywordPosition(visibleTokens,index2){if(index2>0){let prev=visibleTokens[index2-1];if(NAME_PRECEDING_KEYWORDS.has(prev.type)||prev.type===SysMLv2Lexer.DOT||prev.type===SysMLv2Lexer.EQ||prev.type===SysMLv2Lexer.COLON_EQ||prev.text==="->")return!1}if(index2+1<visibleTokens.length){let next=visibleTokens[index2+1];if(KEYWORD_CONTINUATIONS.has(next.type))return!0}return index2===0}function validateKeywords(result){let diagnostics=[];result.tokenStream.fill();let allTokens=result.tokenStream.getTokens(),visibleTokens=[];for(let j=0;j<allTokens.length;j++){let t=allTokens[j];t.channel===0&&t.type!==Token.EOF&&visibleTokens.push(t)}for(let i=0;i<visibleTokens.length;i++){let token=visibleTokens[i];if(token.type!==SysMLv2Lexer.IDENTIFIER)continue;let text=token.text;if(!text||!looksLikeKeywordPosition(visibleTokens,i))continue;let suggestion=findClosestKeyword(text);if(!suggestion)continue;let line=(token.line??1)-1,char=token.column??0,message=`Unknown keyword '${text}'. Did you mean '${suggestion}'?`;diagnostics.push({severity:import_node8.DiagnosticSeverity.Error,range:{start:{line,character:char},end:{line,character:char+text.length}},message,source:"sysml",data:{typo:text,suggestion}})}return diagnostics}var ReferencesProvider=class{constructor(documentManager2){this.documentManager=documentManager2}documentManager;provideReferences(params){if(!this.documentManager.get(params.textDocument.uri))return[];let symbolTable=this.documentManager.getWorkspaceSymbolTable(),symbol=symbolTable.findSymbolAtPosition(params.textDocument.uri,params.position.line,params.position.character);if(!symbol)return[];let references=symbolTable.findReferences(symbol.name),locations=[];for(let ref of references)locations.push({uri:ref.uri,range:ref.selectionRange});return params.context.includeDeclaration,locations}};function findWordOccurrences(line,word){let positions=[],from=0;for(;from<=line.length-word.length;){let idx=line.indexOf(word,from);if(idx<0)break;(idx===0||!isIdentPart(line.charCodeAt(idx-1)))&&(idx+word.length>=line.length||!isIdentPart(line.charCodeAt(idx+word.length)))&&positions.push(idx),from=idx+1}return positions}var RenameProvider=class{constructor(documentManager2){this.documentManager=documentManager2}documentManager;prepareRename(params){let symbolTable=this.documentManager.getSymbolTable(params.textDocument.uri);if(!symbolTable)return null;let symbol=symbolTable.findSymbolAtPosition(params.textDocument.uri,params.position.line,params.position.character);return symbol?symbol.selectionRange:null}provideRename(params){let symbolTable=this.documentManager.getSymbolTable(params.textDocument.uri);if(!symbolTable)return null;let symbol=symbolTable.findSymbolAtPosition(params.textDocument.uri,params.position.line,params.position.character);if(!symbol)return null;let text=this.documentManager.getText(params.textDocument.uri);if(!text)return null;let edits=[],oldName=symbol.name,newName=params.newName,references=symbolTable.findReferences(oldName);for(let ref of references)ref.uri===params.textDocument.uri&&edits.push({range:ref.selectionRange,newText:newName});let lines=text.split(`
28712
- `);for(let i=0;i<lines.length;i++)for(let col of findWordOccurrences(lines[i],oldName)){let range={start:{line:i,character:col},end:{line:i,character:col+oldName.length}};edits.some(e=>e.range.start.line===i&&e.range.start.character===col)||edits.push({range,newText:newName})}return edits.length===0?null:{changes:{[params.textDocument.uri]:edits}}}};var import_node9=__toESM(require_main3());var OPERATOR_TOKENS=new Set([SysMLv2Lexer.BANG_EQ_EQ,SysMLv2Lexer.STAR_STAR,SysMLv2Lexer.COLON_GT,SysMLv2Lexer.COLON_GT_GT,SysMLv2Lexer.AMP,SysMLv2Lexer.COLON_COLON,SysMLv2Lexer.STAR,SysMLv2Lexer.PIPE,SysMLv2Lexer.EQ_EQ,SysMLv2Lexer.BANG_EQ,SysMLv2Lexer.PLUS,SysMLv2Lexer.MINUS,SysMLv2Lexer.ARROW,SysMLv2Lexer.SLASH,SysMLv2Lexer.LT,SysMLv2Lexer.EQ,SysMLv2Lexer.GT,SysMLv2Lexer.CARET,SysMLv2Lexer.TILDE]),PUNCTUATION_TOKENS=new Set([SysMLv2Lexer.LBRACE,SysMLv2Lexer.RBRACE,SysMLv2Lexer.LPAREN,SysMLv2Lexer.RPAREN,SysMLv2Lexer.SEMI,SysMLv2Lexer.COMMA,SysMLv2Lexer.DOT,SysMLv2Lexer.LBRACK,SysMLv2Lexer.RBRACK,SysMLv2Lexer.COLON]),STRUCTURAL_KEYWORDS=new Set(["part","port","item","state","constraint","requirement","concern","case","view","viewpoint","rendering","allocation","connection","interface","occurrence","individual","flow","binding","succession","metadata","enum","actor","subject","ref","use"]),tokenTypes=["namespace","type","class","variable","property","function","keyword","comment","string","number","operator","enum","interface"],tokenModifiers=["declaration","definition","readonly","abstract"],SemanticTokensProvider=class{constructor(documentManager2){this.documentManager=documentManager2}documentManager;tokenCache;provideSemanticTokens(params){let uri=params.textDocument.uri,version=this.documentManager.getVersion(uri);if(this.tokenCache&&this.tokenCache.uri===uri&&this.tokenCache.version===version)return this.tokenCache.tokens;let builder=new import_node9.SemanticTokensBuilder,result=this.documentManager.get(uri);if(!result)return builder.build();result.tokenStream.fill();let tokens=result.tokenStream.getTokens(),prevMeaningful;for(let token of tokens){if(!token.text||token.channel!==0)continue;let text=token.text,tokenType=this.classifyTokenInContext(text,prevMeaningful,token.type);if(prevMeaningful=text,tokenType===void 0)continue;let line=(token.line??1)-1,char=token.column??0,length=text.length;builder.push(line,char,length,tokenType,0)}let built=builder.build();return this.tokenCache={uri,version,tokens:built},built}classifyTokenInContext(text,prev,lexerType){if(lexerType===SysMLv2Lexer.REGULAR_COMMENT||lexerType===SysMLv2Lexer.SINGLE_LINE_NOTE)return 7;if(lexerType===SysMLv2Lexer.STRING||lexerType===SysMLv2Lexer.DOUBLE_STRING)return 8;if(lexerType===SysMLv2Lexer.INTEGER||lexerType===SysMLv2Lexer.REAL)return 9;if(OPERATOR_TOKENS.has(lexerType))return 10;if(!PUNCTUATION_TOKENS.has(lexerType)){if(this.isKeyword(text))return 6;if(lexerType===SysMLv2Lexer.IDENTIFIER)return this.classifyIdentifier(prev)}}classifyIdentifier(prev){return prev?prev==="def"?2:prev==="package"||prev==="namespace"||prev==="library"?0:prev==="action"||prev==="calc"||prev==="analysis"||prev==="verification"?5:prev===":"||prev===":>"||prev===":>>"?1:prev==="attribute"?4:(this.isStructuralKeyword(prev),3):3}isStructuralKeyword(text){return STRUCTURAL_KEYWORDS.has(text)}isKeyword(text){return SYSML_KEYWORDS.has(text)}};var import_node10=__toESM(require_main3());var STANDARD_LIBRARY_TYPES=new Set(["Boolean","String","Integer","Real","Natural","Positive","Complex","Number","Rational","ScalarValues","DataFunctions","Anything","Nothing","Object","Occurrence","Base","Objects","Occurrences","Items","Parts","Ports","Actions","States","Connections","Interfaces","Allocations","Requirements","Constraints","Calculations","Cases","Flows","Transfers","Performances","TransitionPerformances","ISQ","SI","USCustomaryUnits","Quantities","MeasurementReferences","ScalarValues","GeneralView","InterconnectionView","ActionFlowView","StateTransitionView","SequenceView","GeometryView","GridView","BrowserView","StandardViewDefinitions","View","ViewpointCheck","Rendering","TextualRendering","GraphicalRendering","TabularRendering","Views","LengthValue","MassValue","DurationValue","TimeValue","ElectricCurrentValue","ThermodynamicTemperatureValue","TemperatureValue","AmountOfSubstanceValue","LuminousIntensityValue","AreaValue","VolumeValue","SpeedValue","VelocityValue","AccelerationValue","ForceValue","EnergyValue","PowerValue","PressureValue","TorqueValue","MomentOfForceValue","AngularVelocityValue","FrequencyValue","DensityValue","MassFlowRateValue","VolumeFlowRateValue","LengthUnit","MassUnit","DurationUnit","TimeUnit"]),CONSTRAINT_KEYWORDS=new Set(["and","or","not","xor","implies","if","then","else","true","false","null","require","constraint","subject","return","doc","comment","assert","assume"]);function isISQValueType(name){if(!name.endsWith("Value")||name.length<6)return!1;let ch0=name.charCodeAt(0);if(ch0<65||ch0>90)return!1;for(let i=1;i<name.length;i++){let c=name.charCodeAt(i);if(!(c>=65&&c<=90||c>=97&&c<=122))return!1}return!0}var SemanticValidator=class _SemanticValidator{constructor(documentManager2){this.documentManager=documentManager2;this.modelProvider=new SysMLModelProvider(documentManager2)}documentManager;modelProvider;satisfyCache;verifyCache;indexCache;symbolNamesCache;libraryNamesCache;addRequirementNameVariants(out,ref){if(!ref)return;let trimmed=ref.trim();if(!trimmed)return;out.add(trimmed);let lastSeg=trimmed.includes("::")?trimmed.split("::").pop():trimmed;out.add(lastSeg)}collectWorkspaceRequirementRelationshipNames(){let satisfiedNames=new Set,verifiedNames=new Set,uris=this.documentManager.getUris();for(let uri of uris){let version=this.documentManager.getVersion(uri);if(version<0)continue;let rels=this.modelProvider.getModel(uri,version,["relationships"]).relationships??[];for(let rel of rels)rel.type==="satisfy"?this.addRequirementNameVariants(satisfiedNames,rel.target):rel.type==="verify"&&this.addRequirementNameVariants(verifiedNames,rel.target)}return{satisfiedNames,verifiedNames}}validate(uri){let symbolTable=this.documentManager.getWorkspaceSymbolTable(),symbols=symbolTable.getSymbolsForUri(uri);if(symbols.length===0)return[];let allSymbols=symbolTable.getAllSymbols(),allSymbolNames;this.symbolNamesCache&&this.symbolNamesCache.symbols===allSymbols?allSymbolNames=this.symbolNamesCache.names:(allSymbolNames=new Set(allSymbols.map(s=>s.name)),this.symbolNamesCache={symbols:allSymbols,names:allSymbolNames}),this.libraryNamesCache||(this.libraryNamesCache=new Set(getLibraryPackageNames()));let libraryNames=this.libraryNamesCache,text=this.documentManager.getText(uri)??"",indexes=this.getOrBuildIndexes(allSymbols),diagnostics=[];for(let symbol of symbols)diagnostics.push(...this.checkUnresolvedType(symbol,allSymbolNames,libraryNames),...this.checkInvalidMultiplicity(symbol),...this.checkEmptyEnum(symbol,symbols),...this.checkNamingConvention(symbol),...this.checkMissingDocumentation(symbol));return diagnostics.push(...this.checkDuplicateDefinitions(symbols)),diagnostics.push(...this.checkUnusedDefinitions(allSymbols,uri)),diagnostics.push(...this.checkRedefinitionMultiplicity(symbols,indexes,text)),diagnostics.push(...this.checkPortCompatibility(text,uri,indexes)),diagnostics.push(...this.checkConstraintBodyReferences(text,uri,symbols,indexes)),diagnostics.push(...this.checkCircularSpecialization(symbols,indexes)),diagnostics.push(...this.checkCircularContainment(symbols,indexes)),diagnostics.push(...this.checkUnsatisfiedRequirements(symbols,indexes)),diagnostics.push(...this.checkUnverifiedRequirements(symbols,indexes)),diagnostics.push(...this.checkViewpointSatisfaction(symbols,indexes)),this.dedupeDiagnostics(diagnostics)}checkUnresolvedType(symbol,allSymbolNames,libraryNames){if(!symbol.typeName)return[];let typeName=symbol.typeName,kwMatch=typeName.match(/^([A-Z][A-Za-z_0-9]*?)(redefines|subsets|references|connect|bind|default|via|accept|send|flow|allocate|assign|decide|merge|join|fork)([A-Z])/);kwMatch&&(typeName=kwMatch[1]);let rootSegment=typeName.split("::")[0];if(allSymbolNames.has(typeName)||allSymbolNames.has(rootSegment)||STANDARD_LIBRARY_TYPES.has(typeName)||STANDARD_LIBRARY_TYPES.has(rootSegment)||libraryNames.has(rootSegment)||isISQValueType(typeName)||resolveLibraryType(typeName)!==void 0||resolveLibraryType(rootSegment)!==void 0||typeName.charCodeAt(0)>=97&&typeName.charCodeAt(0)<=122)return[];let isMandatory=symbol.multiplicityRange&&symbol.multiplicityRange.lower>=1,severity=isMandatory?import_node10.DiagnosticSeverity.Error:import_node10.DiagnosticSeverity.Warning,message=`Type '${typeName}' is not defined in the current document or standard library`;if(isMandatory){let multStr=symbol.multiplicity??"1";message+=` (feature '${symbol.name}' requires multiplicity [${multStr}])`}return[{severity,range:symbol.selectionRange,message,source:"sysml",code:"unresolved-type",data:{typeName}}]}checkInvalidMultiplicity(symbol){if(!symbol.multiplicityRange||!symbol.multiplicity)return[];let{lower,upper}=symbol.multiplicityRange;return typeof upper=="number"&&lower>upper?[{severity:import_node10.DiagnosticSeverity.Error,range:symbol.selectionRange,message:`Invalid multiplicity [${symbol.multiplicity}]: lower bound (${lower}) exceeds upper bound (${upper})`,source:"sysml",code:"invalid-multiplicity"}]:lower<0?[{severity:import_node10.DiagnosticSeverity.Error,range:symbol.selectionRange,message:`Invalid multiplicity [${symbol.multiplicity}]: lower bound cannot be negative`,source:"sysml",code:"invalid-multiplicity"}]:[]}checkEmptyEnum(symbol,allSymbols){return symbol.kind!=="enum def"?[]:allSymbols.filter(s=>s.parentQualifiedName===symbol.qualifiedName).some(c=>c.kind==="enum"||c.kind==="attribute")?[]:[{severity:import_node10.DiagnosticSeverity.Information,range:symbol.selectionRange,message:`Enumeration '${symbol.name}' has no enum values defined`,source:"sysml",code:"empty-enum"}]}checkNamingConvention(symbol){if(!symbol.name)return[];if(symbol.kind==="package"||symbol.kind==="import"||symbol.kind==="comment"||symbol.kind==="doc"||symbol.kind==="alias"||symbol.kind==="unknown")return[];if(isDefinition(symbol.kind)){let ch=symbol.name[0];if(ch===ch.toLowerCase()&&ch!==ch.toUpperCase())return[{severity:import_node10.DiagnosticSeverity.Hint,range:symbol.selectionRange,message:`Definition '${symbol.name}' should use PascalCase`,source:"sysml",code:"naming-convention",data:{name:symbol.name,convention:"PascalCase"}}]}else{let ch=symbol.name[0];if(ch===ch.toUpperCase()&&ch!==ch.toLowerCase())return[{severity:import_node10.DiagnosticSeverity.Hint,range:symbol.selectionRange,message:`Usage '${symbol.name}' should use camelCase`,source:"sysml",code:"naming-convention",data:{name:symbol.name,convention:"camelCase"}}]}return[]}checkMissingDocumentation(symbol){return isDefinition(symbol.kind)?symbol.documentation?[]:[{severity:import_node10.DiagnosticSeverity.Information,range:symbol.selectionRange,message:`Definition '${symbol.name}' has no documentation`,source:"sysml",code:"missing-doc",data:{name:symbol.name}}]:[]}checkUnusedDefinitions(symbols,targetUri){let defs=symbols.filter(s=>s.kind==="part def"||s.kind==="action def"),defsInScope=targetUri?defs.filter(def=>def.uri===targetUri):defs,referencedTypes=new Set(symbols.filter(s=>s.kind!=="package").flatMap(s=>s.typeNames));for(let s of symbols)if(s.exposeTargets)for(let target of s.exposeTargets){let simpleName=target.replace(/::\*{1,2}$/,"").split("::").pop();simpleName&&referencedTypes.add(simpleName)}let diagnostics=[];for(let def of defsInScope){let isReferenced=referencedTypes.has(def.name),hasBaseType=(def.typeNames?.length??0)>0;!isReferenced&&!hasBaseType&&diagnostics.push({severity:import_node10.DiagnosticSeverity.Warning,range:def.selectionRange,message:`Definition '${def.name}' is not referenced by any usage in the workspace`,source:"sysml",code:"unused-definition",data:{name:def.name}})}return diagnostics}static validateSymbols(symbolsInUri,allNames,opts){let diagnostics=[],instance=Object.create(_SemanticValidator.prototype),allSymbols=opts?.allSymbols??symbolsInUri,includeStyleRules=opts?.includeStyleRules??!0,indexes=instance.buildSymbolIndexes(allSymbols);for(let symbol of symbolsInUri)diagnostics.push(...instance.checkUnresolvedType(symbol,allNames,new Set),...instance.checkInvalidMultiplicity(symbol),...instance.checkEmptyEnum(symbol,symbolsInUri)),includeStyleRules&&diagnostics.push(...instance.checkNamingConvention(symbol),...instance.checkMissingDocumentation(symbol));return diagnostics.push(...instance.checkDuplicateDefinitions(symbolsInUri)),diagnostics.push(...instance.checkUnusedDefinitions(allSymbols)),diagnostics.push(...instance.checkRedefinitionMultiplicity(symbolsInUri,indexes,opts?.text)),diagnostics.push(...instance.checkCircularSpecialization(symbolsInUri,indexes)),diagnostics.push(...instance.checkCircularContainment(symbolsInUri,indexes)),diagnostics.push(...instance.checkUnsatisfiedRequirements(allSymbols,indexes,opts?.text?[opts.text]:[])),diagnostics.push(...instance.checkUnverifiedRequirements(allSymbols,indexes,opts?.text?[opts.text]:[])),opts?.text&&opts.uri&&(diagnostics.push(...instance.checkPortCompatibility(opts.text,opts.uri,indexes)),diagnostics.push(...instance.checkConstraintBodyReferences(opts.text,opts.uri,symbolsInUri,indexes))),instance.dedupeDiagnostics(diagnostics)}checkCircularSpecialization(symbolsInUri,indexes){let diagnostics=[],defsInFile=symbolsInUri.filter(s=>isDefinition(s.kind)&&s.typeNames.length>0);for(let def of defsInFile){let visited=new Set;visited.add(def.name);let cycle=this.followSpecializationChain(def.name,def.typeNames,visited,indexes);cycle&&diagnostics.push({severity:import_node10.DiagnosticSeverity.Error,range:def.selectionRange,message:`Circular specialization: ${cycle.join(" :> ")} :> ${cycle[0]}`,source:"sysml",code:"circular-specialization"})}return diagnostics}followSpecializationChain(originName,typeNames,visited,indexes){for(let tn of typeNames){if(visited.has(tn))return[...visited];let candidates=indexes.definitionsByName.get(tn);if(!candidates||candidates.length===0)continue;let target=candidates[0];if(target.typeNames.length===0)continue;visited.add(tn);let cycle=this.followSpecializationChain(originName,target.typeNames,visited,indexes);if(cycle)return cycle;visited.delete(tn)}}checkCircularContainment(symbolsInUri,indexes){let diagnostics=[],defsInFile=symbolsInUri.filter(s=>isDefinition(s.kind));for(let def of defsInFile){let children=indexes.byParent.get(def.qualifiedName)??[],childTypeNames=children.flatMap(c=>c.typeNames).filter(t=>t.length>0);if(childTypeNames.length!==0)for(let childTypeName of childTypeNames){if(childTypeName===def.name)continue;let visited=new Set;visited.add(def.name);let cycle=this.followContainmentChain(childTypeName,visited,indexes);if(cycle){let range=children.find(c=>c.typeNames.includes(childTypeName))?.selectionRange??def.selectionRange;diagnostics.push({severity:import_node10.DiagnosticSeverity.Error,range,message:`Circular containment: ${cycle.join(" -> ")} -> ${cycle[0]}`,source:"sysml",code:"circular-containment"});break}}}return diagnostics}followContainmentChain(typeName,visited,indexes){if(visited.has(typeName))return[...visited];let candidates=indexes.definitionsByName.get(typeName);if(!candidates||candidates.length===0)return;let target=candidates[0],childTypeNames=(indexes.byParent.get(target.qualifiedName)??[]).flatMap(c=>c.typeNames).filter(t=>t.length>0);if(childTypeNames.length!==0){visited.add(typeName);for(let tn of childTypeNames){let cycle=this.followContainmentChain(tn,visited,indexes);if(cycle)return cycle}visited.delete(typeName)}}checkUnsatisfiedRequirements(allSymbols,indexes,workspaceTexts){let diagnostics=[],satisfiedNames,satisfyBlockRanges;if(workspaceTexts){satisfiedNames=new Set,satisfyBlockRanges=new Map;for(let text of workspaceTexts)this.extractSatisfyReferences(text,satisfiedNames),satisfyBlockRanges.set("__static__",this.extractSatisfyBlockRanges(text))}else if(this.documentManager){let uris=this.documentManager.getUris(),versionKey=uris.map(u=>u+":"+this.documentManager.getVersion(u)).join("|");if(this.satisfyCache&&this.satisfyCache.versionKey===versionKey)satisfiedNames=this.satisfyCache.satisfiedNames,satisfyBlockRanges=this.satisfyCache.satisfyBlockRanges;else{let relNames=this.collectWorkspaceRequirementRelationshipNames();satisfiedNames=relNames.satisfiedNames,satisfyBlockRanges=new Map;for(let uri of uris){let text=this.documentManager.getText(uri);text&&satisfyBlockRanges.set(uri,this.extractSatisfyBlockRanges(text))}this.satisfyCache={versionKey,satisfiedNames,satisfyBlockRanges},(!this.verifyCache||this.verifyCache.versionKey!==versionKey)&&(this.verifyCache={versionKey,verifiedNames:relNames.verifiedNames})}}else satisfiedNames=new Set,satisfyBlockRanges=new Map;let requirementUsages=allSymbols.filter(s=>s.kind==="requirement");for(let req of requirementUsages){if(req.parentQualifiedName&&indexes.byQualifiedName.get(req.parentQualifiedName)?.kind==="requirement")continue;let uriRanges=satisfyBlockRanges.get(req.uri)??satisfyBlockRanges.get("__static__")??[],reqLine=req.selectionRange.start.line;if(uriRanges.some(r=>reqLine>=r.startLine&&reqLine<=r.endLine))continue;satisfiedNames.has(req.name)||satisfiedNames.has(req.qualifiedName)||diagnostics.push({severity:import_node10.DiagnosticSeverity.Warning,range:req.selectionRange,message:`Requirement '${req.name}' is not satisfied by any element`,source:"sysml",code:"unsatisfied-requirement",data:{name:req.name,qualifiedName:req.qualifiedName}})}return diagnostics}extractSatisfyReferences(text,out){let stripped=stripComments(text),re=/\bsatisfy\s+(?:requirement\s+)?([\w]+(?:::[\w]+)*)\s+(?:by\b|;|:)/g,m2;for(;(m2=re.exec(stripped))!==null;){let ref=m2[1];out.add(ref);let lastSeg=ref.includes("::")?ref.split("::").pop():ref;out.add(lastSeg)}}extractSatisfyBlockRanges(text){let ranges=[],stripped=stripComments(text),re=/\bsatisfy\b[^;{]*\{/g,m2,lineOffsets;for(;(m2=re.exec(stripped))!==null;){let open=m2.index+m2[0].length-1,depth=1,i=open+1;for(;i<stripped.length&&depth>0;)stripped[i]==="{"&&depth++,stripped[i]==="}"&&depth--,i++;if(depth===0){if(!lineOffsets){lineOffsets=[0];for(let j=0;j<text.length;j++)text[j]===`
28712
+ `);for(let i=0;i<lines.length;i++)for(let col of findWordOccurrences(lines[i],oldName)){let range={start:{line:i,character:col},end:{line:i,character:col+oldName.length}};edits.some(e=>e.range.start.line===i&&e.range.start.character===col)||edits.push({range,newText:newName})}return edits.length===0?null:{changes:{[params.textDocument.uri]:edits}}}};var import_node9=__toESM(require_main3());var OPERATOR_TOKENS=new Set([SysMLv2Lexer.BANG_EQ_EQ,SysMLv2Lexer.STAR_STAR,SysMLv2Lexer.COLON_GT,SysMLv2Lexer.COLON_GT_GT,SysMLv2Lexer.AMP,SysMLv2Lexer.COLON_COLON,SysMLv2Lexer.STAR,SysMLv2Lexer.PIPE,SysMLv2Lexer.EQ_EQ,SysMLv2Lexer.BANG_EQ,SysMLv2Lexer.PLUS,SysMLv2Lexer.MINUS,SysMLv2Lexer.ARROW,SysMLv2Lexer.SLASH,SysMLv2Lexer.LT,SysMLv2Lexer.EQ,SysMLv2Lexer.GT,SysMLv2Lexer.CARET,SysMLv2Lexer.TILDE]),PUNCTUATION_TOKENS=new Set([SysMLv2Lexer.LBRACE,SysMLv2Lexer.RBRACE,SysMLv2Lexer.LPAREN,SysMLv2Lexer.RPAREN,SysMLv2Lexer.SEMI,SysMLv2Lexer.COMMA,SysMLv2Lexer.DOT,SysMLv2Lexer.LBRACK,SysMLv2Lexer.RBRACK,SysMLv2Lexer.COLON]),STRUCTURAL_KEYWORDS=new Set(["part","port","item","state","constraint","requirement","concern","case","view","viewpoint","rendering","allocation","connection","interface","occurrence","individual","flow","binding","succession","metadata","enum","actor","subject","ref","use"]),tokenTypes=["namespace","type","class","variable","property","function","keyword","comment","string","number","operator","enum","interface"],tokenModifiers=["declaration","definition","readonly","abstract"],SemanticTokensProvider=class{constructor(documentManager2){this.documentManager=documentManager2}documentManager;tokenCache;provideSemanticTokens(params){let uri=params.textDocument.uri,version=this.documentManager.getVersion(uri);if(this.tokenCache&&this.tokenCache.uri===uri&&this.tokenCache.version===version)return this.tokenCache.tokens;let builder=new import_node9.SemanticTokensBuilder,result=this.documentManager.get(uri);if(!result)return builder.build();result.tokenStream.fill();let tokens=result.tokenStream.getTokens(),prevMeaningful;for(let token of tokens){if(!token.text||token.channel!==0)continue;let text=token.text,tokenType=this.classifyTokenInContext(text,prevMeaningful,token.type);if(prevMeaningful=text,tokenType===void 0)continue;let line=(token.line??1)-1,char=token.column??0,length=text.length;builder.push(line,char,length,tokenType,0)}let built=builder.build();return this.tokenCache={uri,version,tokens:built},built}classifyTokenInContext(text,prev,lexerType){if(lexerType===SysMLv2Lexer.REGULAR_COMMENT||lexerType===SysMLv2Lexer.SINGLE_LINE_NOTE)return 7;if(lexerType===SysMLv2Lexer.STRING||lexerType===SysMLv2Lexer.DOUBLE_STRING)return 8;if(lexerType===SysMLv2Lexer.INTEGER||lexerType===SysMLv2Lexer.REAL)return 9;if(OPERATOR_TOKENS.has(lexerType))return 10;if(!PUNCTUATION_TOKENS.has(lexerType)){if(this.isKeyword(text))return 6;if(lexerType===SysMLv2Lexer.IDENTIFIER)return this.classifyIdentifier(prev)}}classifyIdentifier(prev){return prev?prev==="def"?2:prev==="package"||prev==="namespace"||prev==="library"?0:prev==="action"||prev==="calc"||prev==="analysis"||prev==="verification"?5:prev===":"||prev===":>"||prev===":>>"?1:prev==="attribute"?4:(this.isStructuralKeyword(prev),3):3}isStructuralKeyword(text){return STRUCTURAL_KEYWORDS.has(text)}isKeyword(text){return SYSML_KEYWORDS.has(text)}};var import_node10=__toESM(require_main3());var STANDARD_LIBRARY_TYPES=new Set(["Boolean","String","Integer","Real","Natural","Positive","Complex","Number","Rational","ScalarValues","DataFunctions","Anything","Nothing","Object","Occurrence","Base","Objects","Occurrences","Items","Parts","Ports","Actions","States","Connections","Interfaces","Allocations","Requirements","Constraints","Calculations","Cases","Flows","Transfers","Performances","TransitionPerformances","ISQ","SI","USCustomaryUnits","Quantities","MeasurementReferences","ScalarValues","GeneralView","InterconnectionView","ActionFlowView","StateTransitionView","SequenceView","GeometryView","GridView","BrowserView","StandardViewDefinitions","View","ViewpointCheck","Rendering","TextualRendering","GraphicalRendering","TabularRendering","Views","LengthValue","MassValue","DurationValue","TimeValue","ElectricCurrentValue","ThermodynamicTemperatureValue","TemperatureValue","AmountOfSubstanceValue","LuminousIntensityValue","AreaValue","VolumeValue","SpeedValue","VelocityValue","AccelerationValue","ForceValue","EnergyValue","PowerValue","PressureValue","TorqueValue","MomentOfForceValue","AngularVelocityValue","FrequencyValue","DensityValue","MassFlowRateValue","VolumeFlowRateValue","LengthUnit","MassUnit","DurationUnit","TimeUnit"]),CONSTRAINT_KEYWORDS=new Set(["and","or","not","xor","implies","if","then","else","true","false","null","require","constraint","subject","return","doc","comment","assert","assume"]);function isISQValueType(name){if(!name.endsWith("Value")||name.length<6)return!1;let ch0=name.charCodeAt(0);if(ch0<65||ch0>90)return!1;for(let i=1;i<name.length;i++){let c=name.charCodeAt(i);if(!(c>=65&&c<=90||c>=97&&c<=122))return!1}return!0}var SemanticValidator=class _SemanticValidator{constructor(documentManager2){this.documentManager=documentManager2;this.modelProvider=new SysMLModelProvider(documentManager2)}documentManager;modelProvider;satisfyCache;verifyCache;indexCache;symbolNamesCache;libraryNamesCache;addRequirementNameVariants(out,ref){if(!ref)return;let trimmed=ref.trim();if(!trimmed)return;out.add(trimmed);let lastSeg=trimmed.includes("::")?trimmed.split("::").pop():trimmed;out.add(lastSeg)}collectWorkspaceRequirementRelationshipNames(){let satisfiedNames=new Set,verifiedNames=new Set,uris=this.documentManager.getUris();for(let uri of uris){let version=this.documentManager.getVersion(uri);if(version<0)continue;let rels=this.modelProvider.getModel(uri,version,["relationships"]).relationships??[];for(let rel of rels)rel.type==="satisfy"?this.addRequirementNameVariants(satisfiedNames,rel.target):rel.type==="verify"&&this.addRequirementNameVariants(verifiedNames,rel.target)}return{satisfiedNames,verifiedNames}}validate(uri){let symbolTable=this.documentManager.getWorkspaceSymbolTable(),symbols=symbolTable.getSymbolsForUri(uri);if(symbols.length===0)return[];let allSymbols=symbolTable.getAllSymbols(),allSymbolNames;this.symbolNamesCache&&this.symbolNamesCache.symbols===allSymbols?allSymbolNames=this.symbolNamesCache.names:(allSymbolNames=new Set(allSymbols.map(s=>s.name)),this.symbolNamesCache={symbols:allSymbols,names:allSymbolNames}),this.libraryNamesCache||(this.libraryNamesCache=new Set(getLibraryPackageNames()));let libraryNames=this.libraryNamesCache,text=this.documentManager.getText(uri)??"",indexes=this.getOrBuildIndexes(allSymbols),diagnostics=[];for(let symbol of symbols)diagnostics.push(...this.checkUnresolvedType(symbol,allSymbolNames,libraryNames),...this.checkInvalidMultiplicity(symbol),...this.checkEmptyEnum(symbol,symbols),...this.checkNamingConvention(symbol),...this.checkMissingDocumentation(symbol));return diagnostics.push(...this.checkDuplicateDefinitions(symbols)),diagnostics.push(...this.checkUnusedDefinitions(allSymbols,uri)),diagnostics.push(...this.checkRedefinitionMultiplicity(symbols,indexes,text)),diagnostics.push(...this.checkPortCompatibility(text,uri,indexes)),diagnostics.push(...this.checkConstraintBodyReferences(text,uri,symbols,indexes)),diagnostics.push(...this.checkCircularSpecialization(symbols,indexes)),diagnostics.push(...this.checkUnsatisfiedRequirements(symbols,indexes)),diagnostics.push(...this.checkUnverifiedRequirements(symbols,indexes)),diagnostics.push(...this.checkViewpointSatisfaction(symbols,indexes)),this.dedupeDiagnostics(diagnostics)}checkUnresolvedType(symbol,allSymbolNames,libraryNames){if(!symbol.typeName)return[];let typeName=symbol.typeName,kwMatch=typeName.match(/^([A-Z][A-Za-z_0-9]*?)(redefines|subsets|references|connect|bind|default|via|accept|send|flow|allocate|assign|decide|merge|join|fork)([A-Z])/);kwMatch&&(typeName=kwMatch[1]);let rootSegment=typeName.split("::")[0];if(allSymbolNames.has(typeName)||allSymbolNames.has(rootSegment)||STANDARD_LIBRARY_TYPES.has(typeName)||STANDARD_LIBRARY_TYPES.has(rootSegment)||libraryNames.has(rootSegment)||isISQValueType(typeName)||resolveLibraryType(typeName)!==void 0||resolveLibraryType(rootSegment)!==void 0||typeName.charCodeAt(0)>=97&&typeName.charCodeAt(0)<=122)return[];let isMandatory=symbol.multiplicityRange&&symbol.multiplicityRange.lower>=1,severity=isMandatory?import_node10.DiagnosticSeverity.Error:import_node10.DiagnosticSeverity.Warning,message=`Type '${typeName}' is not defined in the current document or standard library`;if(isMandatory){let multStr=symbol.multiplicity??"1";message+=` (feature '${symbol.name}' requires multiplicity [${multStr}])`}return[{severity,range:symbol.selectionRange,message,source:"sysml",code:"unresolved-type",data:{typeName}}]}checkInvalidMultiplicity(symbol){if(!symbol.multiplicityRange||!symbol.multiplicity)return[];let{lower,upper}=symbol.multiplicityRange;return typeof upper=="number"&&lower>upper?[{severity:import_node10.DiagnosticSeverity.Error,range:symbol.selectionRange,message:`Invalid multiplicity [${symbol.multiplicity}]: lower bound (${lower}) exceeds upper bound (${upper})`,source:"sysml",code:"invalid-multiplicity"}]:lower<0?[{severity:import_node10.DiagnosticSeverity.Error,range:symbol.selectionRange,message:`Invalid multiplicity [${symbol.multiplicity}]: lower bound cannot be negative`,source:"sysml",code:"invalid-multiplicity"}]:[]}checkEmptyEnum(symbol,allSymbols){return symbol.kind!=="enum def"?[]:allSymbols.filter(s=>s.parentQualifiedName===symbol.qualifiedName).some(c=>c.kind==="enum"||c.kind==="attribute")?[]:[{severity:import_node10.DiagnosticSeverity.Information,range:symbol.selectionRange,message:`Enumeration '${symbol.name}' has no enum values defined`,source:"sysml",code:"empty-enum"}]}checkNamingConvention(symbol){if(!symbol.name)return[];if(symbol.kind==="package"||symbol.kind==="import"||symbol.kind==="comment"||symbol.kind==="doc"||symbol.kind==="alias"||symbol.kind==="unknown")return[];if(isDefinition(symbol.kind)){let ch=symbol.name[0];if(ch===ch.toLowerCase()&&ch!==ch.toUpperCase())return[{severity:import_node10.DiagnosticSeverity.Hint,range:symbol.selectionRange,message:`Definition '${symbol.name}' should use PascalCase`,source:"sysml",code:"naming-convention",data:{name:symbol.name,convention:"PascalCase"}}]}else{let ch=symbol.name[0];if(ch===ch.toUpperCase()&&ch!==ch.toLowerCase())return[{severity:import_node10.DiagnosticSeverity.Hint,range:symbol.selectionRange,message:`Usage '${symbol.name}' should use camelCase`,source:"sysml",code:"naming-convention",data:{name:symbol.name,convention:"camelCase"}}]}return[]}checkMissingDocumentation(symbol){return isDefinition(symbol.kind)?symbol.documentation?[]:[{severity:import_node10.DiagnosticSeverity.Information,range:symbol.selectionRange,message:`Definition '${symbol.name}' has no documentation`,source:"sysml",code:"missing-doc",data:{name:symbol.name}}]:[]}checkUnusedDefinitions(symbols,targetUri){let defs=symbols.filter(s=>s.kind==="part def"||s.kind==="action def"),defsInScope=targetUri?defs.filter(def=>def.uri===targetUri):defs,referencedTypes=new Set(symbols.filter(s=>s.kind!=="package").flatMap(s=>s.typeNames));for(let s of symbols)if(s.exposeTargets)for(let target of s.exposeTargets){let simpleName=target.replace(/::\*{1,2}$/,"").split("::").pop();simpleName&&referencedTypes.add(simpleName)}let diagnostics=[];for(let def of defsInScope){let isReferenced=referencedTypes.has(def.name),hasBaseType=(def.typeNames?.length??0)>0;!isReferenced&&!hasBaseType&&diagnostics.push({severity:import_node10.DiagnosticSeverity.Warning,range:def.selectionRange,message:`Definition '${def.name}' is not referenced by any usage in the workspace`,source:"sysml",code:"unused-definition",data:{name:def.name}})}return diagnostics}static validateSymbols(symbolsInUri,allNames,opts){let diagnostics=[],instance=Object.create(_SemanticValidator.prototype),allSymbols=opts?.allSymbols??symbolsInUri,includeStyleRules=opts?.includeStyleRules??!0,indexes=instance.buildSymbolIndexes(allSymbols);for(let symbol of symbolsInUri)diagnostics.push(...instance.checkUnresolvedType(symbol,allNames,new Set),...instance.checkInvalidMultiplicity(symbol),...instance.checkEmptyEnum(symbol,symbolsInUri)),includeStyleRules&&diagnostics.push(...instance.checkNamingConvention(symbol),...instance.checkMissingDocumentation(symbol));return diagnostics.push(...instance.checkDuplicateDefinitions(symbolsInUri)),diagnostics.push(...instance.checkUnusedDefinitions(allSymbols)),diagnostics.push(...instance.checkRedefinitionMultiplicity(symbolsInUri,indexes,opts?.text)),diagnostics.push(...instance.checkCircularSpecialization(symbolsInUri,indexes)),diagnostics.push(...instance.checkUnsatisfiedRequirements(allSymbols,indexes,opts?.text?[opts.text]:[])),diagnostics.push(...instance.checkUnverifiedRequirements(allSymbols,indexes,opts?.text?[opts.text]:[])),opts?.text&&opts.uri&&(diagnostics.push(...instance.checkPortCompatibility(opts.text,opts.uri,indexes)),diagnostics.push(...instance.checkConstraintBodyReferences(opts.text,opts.uri,symbolsInUri,indexes))),instance.dedupeDiagnostics(diagnostics)}checkCircularSpecialization(symbolsInUri,indexes){let diagnostics=[],defsInFile=symbolsInUri.filter(s=>isDefinition(s.kind)&&s.typeNames.length>0);for(let def of defsInFile){let visited=new Set;visited.add(def.name);let cycle=this.followSpecializationChain(def.name,def.typeNames,visited,indexes);cycle&&diagnostics.push({severity:import_node10.DiagnosticSeverity.Error,range:def.selectionRange,message:`Circular specialization: ${cycle.join(" :> ")} :> ${cycle[0]}`,source:"sysml",code:"circular-specialization"})}return diagnostics}followSpecializationChain(originName,typeNames,visited,indexes){for(let tn of typeNames){if(visited.has(tn))return[...visited];let candidates=indexes.definitionsByName.get(tn);if(!candidates||candidates.length===0)continue;let target=candidates[0];if(target.typeNames.length===0)continue;visited.add(tn);let cycle=this.followSpecializationChain(originName,target.typeNames,visited,indexes);if(cycle)return cycle;visited.delete(tn)}}checkUnsatisfiedRequirements(allSymbols,indexes,workspaceTexts){let diagnostics=[],satisfiedNames,satisfyBlockRanges;if(workspaceTexts){satisfiedNames=new Set,satisfyBlockRanges=new Map;for(let text of workspaceTexts)this.extractSatisfyReferences(text,satisfiedNames),satisfyBlockRanges.set("__static__",this.extractSatisfyBlockRanges(text))}else if(this.documentManager){let uris=this.documentManager.getUris(),versionKey=uris.map(u=>u+":"+this.documentManager.getVersion(u)).join("|");if(this.satisfyCache&&this.satisfyCache.versionKey===versionKey)satisfiedNames=this.satisfyCache.satisfiedNames,satisfyBlockRanges=this.satisfyCache.satisfyBlockRanges;else{let relNames=this.collectWorkspaceRequirementRelationshipNames();satisfiedNames=relNames.satisfiedNames,satisfyBlockRanges=new Map;for(let uri of uris){let text=this.documentManager.getText(uri);text&&satisfyBlockRanges.set(uri,this.extractSatisfyBlockRanges(text))}this.satisfyCache={versionKey,satisfiedNames,satisfyBlockRanges},(!this.verifyCache||this.verifyCache.versionKey!==versionKey)&&(this.verifyCache={versionKey,verifiedNames:relNames.verifiedNames})}}else satisfiedNames=new Set,satisfyBlockRanges=new Map;let requirementUsages=allSymbols.filter(s=>s.kind==="requirement");for(let req of requirementUsages){if(req.parentQualifiedName&&indexes.byQualifiedName.get(req.parentQualifiedName)?.kind==="requirement")continue;let uriRanges=satisfyBlockRanges.get(req.uri)??satisfyBlockRanges.get("__static__")??[],reqLine=req.selectionRange.start.line;if(uriRanges.some(r=>reqLine>=r.startLine&&reqLine<=r.endLine))continue;satisfiedNames.has(req.name)||satisfiedNames.has(req.qualifiedName)||diagnostics.push({severity:import_node10.DiagnosticSeverity.Warning,range:req.selectionRange,message:`Requirement '${req.name}' is not satisfied by any element`,source:"sysml",code:"unsatisfied-requirement",data:{name:req.name,qualifiedName:req.qualifiedName}})}return diagnostics}extractSatisfyReferences(text,out){let stripped=stripComments(text),re=/\bsatisfy\s+(?:requirement\s+)?([\w]+(?:::[\w]+)*)\s+(?:by\b|;|:)/g,m2;for(;(m2=re.exec(stripped))!==null;){let ref=m2[1];out.add(ref);let lastSeg=ref.includes("::")?ref.split("::").pop():ref;out.add(lastSeg)}}extractSatisfyBlockRanges(text){let ranges=[],stripped=stripComments(text),re=/\bsatisfy\b[^;{]*\{/g,m2,lineOffsets;for(;(m2=re.exec(stripped))!==null;){let open=m2.index+m2[0].length-1,depth=1,i=open+1;for(;i<stripped.length&&depth>0;)stripped[i]==="{"&&depth++,stripped[i]==="}"&&depth--,i++;if(depth===0){if(!lineOffsets){lineOffsets=[0];for(let j=0;j<text.length;j++)text[j]===`
28713
28713
  `&&lineOffsets.push(j+1)}ranges.push({startLine:this.offsetToLine(lineOffsets,open),endLine:this.offsetToLine(lineOffsets,i-1)})}}return ranges}checkUnverifiedRequirements(allSymbols,indexes,workspaceTexts){let diagnostics=[],satisfiedNames,verifiedNames,satisfyBlockRanges;if(workspaceTexts){satisfiedNames=new Set,verifiedNames=new Set,satisfyBlockRanges=new Map;for(let text of workspaceTexts)this.extractSatisfyReferences(text,satisfiedNames),this.extractVerifyReferences(text,verifiedNames),satisfyBlockRanges.set("__static__",this.extractSatisfyBlockRanges(text))}else if(this.documentManager){let uris=this.documentManager.getUris(),versionKey=uris.map(u=>u+":"+this.documentManager.getVersion(u)).join("|"),satisfyCacheValid=this.satisfyCache&&this.satisfyCache.versionKey===versionKey,verifyCacheValid=this.verifyCache&&this.verifyCache.versionKey===versionKey;if(!satisfyCacheValid||!verifyCacheValid){let relNames=this.collectWorkspaceRequirementRelationshipNames();if(!satisfyCacheValid){satisfyBlockRanges=new Map;for(let uri of uris){let text=this.documentManager.getText(uri);text&&satisfyBlockRanges.set(uri,this.extractSatisfyBlockRanges(text))}this.satisfyCache={versionKey,satisfiedNames:relNames.satisfiedNames,satisfyBlockRanges}}verifyCacheValid||(this.verifyCache={versionKey,verifiedNames:relNames.verifiedNames})}satisfiedNames=this.satisfyCache.satisfiedNames,satisfyBlockRanges=this.satisfyCache.satisfyBlockRanges,verifiedNames=this.verifyCache.verifiedNames}else satisfiedNames=new Set,verifiedNames=new Set,satisfyBlockRanges=new Map;let requirementUsages=allSymbols.filter(s=>s.kind==="requirement");for(let req of requirementUsages){if(req.parentQualifiedName&&indexes.byQualifiedName.get(req.parentQualifiedName)?.kind==="requirement")continue;let uriRanges=satisfyBlockRanges.get(req.uri)??satisfyBlockRanges.get("__static__")??[],reqLine=req.selectionRange.start.line;if(uriRanges.some(r=>reqLine>=r.startLine&&reqLine<=r.endLine))continue;let isSatisfied=satisfiedNames.has(req.name)||satisfiedNames.has(req.qualifiedName);if(!(verifiedNames.has(req.name)||verifiedNames.has(req.qualifiedName))){let message=isSatisfied?`Requirement '${req.name}' is satisfied but has no verification case \u2014 consider adding: verify ${req.name} by <VerificationCase>;`:`Requirement '${req.name}' has no verification case \u2014 consider adding: verify ${req.name} by <VerificationCase>;`;diagnostics.push({severity:import_node10.DiagnosticSeverity.Warning,range:req.selectionRange,message,source:"sysml",code:"unverified-requirement",data:{name:req.name,qualifiedName:req.qualifiedName}})}}return diagnostics}extractVerifyReferences(text,out){let stripped=stripComments(text),re=/\bverify\s+(?:requirement\s+)?([\w]+(?:::[\w]+)*)\s*(?:by\b|;|:|\{)/g,m2;for(;(m2=re.exec(stripped))!==null;){let ref=m2[1];out.add(ref);let lastSeg=ref.includes("::")?ref.split("::").pop():ref;out.add(lastSeg)}}offsetToLine(lineOffsets,offset){let lo=0,hi=lineOffsets.length-1;for(;lo<hi;){let mid=lo+hi+1>>>1;lineOffsets[mid]<=offset?lo=mid:hi=mid-1}return lo}checkViewpointSatisfaction(symbols,_indexes){let diagnostics=[],views=symbols.filter(s=>s.kind==="view"),_viewpointNames=new Set(symbols.filter(s=>s.kind==="viewpoint def"||s.kind==="viewpoint").map(s=>s.name));for(let view of views){let hasExpose=view.exposeTargets&&view.exposeTargets.length>0,hasFilter=view.viewFilters&&view.viewFilters.length>0;!hasExpose&&!hasFilter&&diagnostics.push({severity:import_node10.DiagnosticSeverity.Information,range:view.selectionRange,message:`View '${view.name}' has no expose or filter directives \u2014 it will show all elements`,source:"sysml",code:"view-no-scope"})}return diagnostics}checkRedefinitionMultiplicity(symbolsInUri,indexes,text){let diagnostics=[],lines=text?.split(`
28714
28714
  `);for(let s of symbolsInUri){if(!s.typeName||!s.multiplicityRange)continue;let c0=s.typeName.charCodeAt(0);if(!(c0>=97&&c0<=122))continue;if(lines){let lineIdx=s.selectionRange.start.line,line=lines[lineIdx]||"";if(!/:>>/.test(line)&&!/\bredefines\b/.test(line))continue}let base=(indexes.byName.get(s.typeName)??[]).find(c=>!!c.multiplicityRange);if(!base?.multiplicityRange)continue;let baseLower=base.multiplicityRange.lower,baseUpper=base.multiplicityRange.upper,curLower=s.multiplicityRange.lower,curUpper=s.multiplicityRange.upper,lowerOk=curLower>=baseLower,upperOk=baseUpper==="*"||curUpper!=="*"&&curUpper<=baseUpper;lowerOk&&upperOk||diagnostics.push({severity:import_node10.DiagnosticSeverity.Error,range:s.selectionRange,message:`Redefinition multiplicity [${s.multiplicity??"?"}] is incompatible with base '${base.name}' multiplicity [${base.multiplicity??"?"}]`,source:"sysml",code:"invalid-redefinition-multiplicity"})}return diagnostics}checkPortCompatibility(text,uri,indexes){if(!text)return[];let diagnostics=[],lines=text.split(`
28715
28715
  `),re=/\bconnect\s+([A-Za-z_][\w.]*)\s+to\s+([A-Za-z_][\w.]*)/g,m2;for(;(m2=re.exec(text))!==null;){let left=m2[1].split(".").pop(),right=m2[2].split(".").pop(),lSym=(indexes.portsByName.get(left)??[])[0],rSym=(indexes.portsByName.get(right)??[])[0];if(!lSym||!rSym)continue;let lType=lSym.typeNames[0]??lSym.typeName,rType=rSym.typeNames[0]??rSym.typeName;if(!lType||!rType||lType===rType||lType==="~"+rType||rType==="~"+lType||lType.startsWith("~")&&lType.slice(1)===rType||rType.startsWith("~")&&rType.slice(1)===lType)continue;let matchLine=text.substring(0,m2.index).split(`
@@ -135,7 +135,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
135
135
  `),standaloneSatisfy=this.extractStandaloneSatisfyVerify(stripComments(fullText));for(let rel of standaloneSatisfy)relationships.some(r=>r.type===rel.type&&r.source===rel.source&&r.target===rel.target)||relationships.push(rel);return relationships}extractSequenceDiagrams(symbolTable,uri,lines){let symbols=symbolTable.getSymbolsForUri(uri),diagrams=[],seen=new Set;for(let symbol2 of symbols){if(symbol2.kind!=="action def"&&symbol2.kind!=="action")continue;let children=this.getChildSymbols(symbol2,symbolTable),participants=[],messages=[];for(let child of children)(child.kind==="part"||child.kind==="item")&&participants.push({name:child.name,type:child.typeNames.join(", ")||child.kind,range:this.rangeToDTO(child.range)});let fullText=this.getFullElementText(symbol2,lines),occurrence=1;for(let{afterPos}of findWordPositionsCI(fullText,"send")){let sigStart=skipWS(fullText,afterPos),[signal,afterSig]=readIdent(fullText,sigStart,!0);if(!signal)continue;let kwStart=skipWS(fullText,afterSig),[kw,afterKw]=readIdent(fullText,kwStart);if(kw!=="via"&&kw!=="to")continue;let tgtStart=skipWS(fullText,afterKw),[target]=readIdent(fullText,tgtStart,!0);target&&messages.push({name:`send_${occurrence}`,from:symbol2.name,to:target,payload:signal,occurrence:occurrence++,range:this.rangeToDTO(symbol2.range)})}for(let{afterPos}of findWordPositionsCI(fullText,"accept")){let sigStart=skipWS(fullText,afterPos),[signal,afterSig]=readIdent(fullText,sigStart,!0);if(!signal)continue;let kwStart=skipWS(fullText,afterSig),[kw,afterKw]=readIdent(fullText,kwStart);if(kw!=="via"&&kw!=="from")continue;let srcStart=skipWS(fullText,afterKw),[source]=readIdent(fullText,srcStart,!0);source&&messages.push({name:`accept_${occurrence}`,from:source,to:symbol2.name,payload:signal,occurrence:occurrence++,range:this.rangeToDTO(symbol2.range)})}for(let child of children)if(child.kind==="action"){let childText=this.getFullElementText(child,lines);for(let{afterPos}of findWordPositionsCI(childText,"send")){let sigStart=skipWS(childText,afterPos),[signal,afterSig]=readIdent(childText,sigStart,!0);if(!signal)continue;let kwStart=skipWS(childText,afterSig),[kw,afterKw]=readIdent(childText,kwStart);if(kw!=="via"&&kw!=="to")continue;let tgtStart=skipWS(childText,afterKw),[target]=readIdent(childText,tgtStart,!0);target&&messages.push({name:child.name,from:target??symbol2.name,to:signal??"",payload:signal??"",occurrence:occurrence++,range:this.rangeToDTO(child.range)})}for(let{afterPos}of findWordPositionsCI(childText,"accept")){let sigStart=skipWS(childText,afterPos),[signal,afterSig]=readIdent(childText,sigStart,!0);if(!signal)continue;let kwStart=skipWS(childText,afterSig),[kw,afterKw]=readIdent(childText,kwStart);if(kw!=="via"&&kw!=="from")continue;let srcStart=skipWS(childText,afterKw),[source]=readIdent(childText,srcStart,!0);source&&messages.push({name:child.name,from:source??"",to:symbol2.name,payload:signal??"",occurrence:occurrence++,range:this.rangeToDTO(child.range)})}}(participants.length>0||messages.length>0)&&(diagrams.push({name:symbol2.name,participants,messages,range:this.rangeToDTO(symbol2.range)}),messages.length>0&&seen.add(symbol2.qualifiedName))}for(let symbol2 of symbols){if(seen.has(symbol2.qualifiedName)||symbol2.kind!=="action def"&&symbol2.kind!=="action")continue;let children=this.getChildSymbols(symbol2,symbolTable);if(!children.some(c=>c.kind==="action"||c.kind==="action def"))continue;let flows=this.extractSuccessions(symbol2,lines);if(flows.length===0)continue;let participants=children.filter(c=>c.kind==="action"||c.kind==="action def").map(c=>({name:c.name,type:c.typeNames.join(", ")||"action",range:this.rangeToDTO(c.range)})),messages=[],occ=1;for(let flow of flows){if(flow.from==="start"||flow.to==="done")continue;let label=flow.guard??flow.to;messages.push({name:label,from:flow.from,to:flow.to,payload:flow.guard??"",occurrence:occ++,range:flow.range})}if(participants.length>0||messages.length>0){let existingIdx=diagrams.findIndex(d=>d.name===symbol2.name);existingIdx>=0&&diagrams.splice(existingIdx,1),diagrams.push({name:symbol2.name,participants,messages,range:this.rangeToDTO(symbol2.range)})}}let containerKinds=new Set(["part def","part","item def","item","interface def","interface","connection def","connection","occurrence def","occurrence"]),rootName=qualified=>{if(!qualified)return qualified;let dotIdx=qualified.indexOf("."),head=dotIdx>=0?qualified.substring(0,dotIdx):qualified,ccIdx=head.lastIndexOf("::");return ccIdx>=0?head.substring(ccIdx+2):head};for(let symbol2 of symbols){if(seen.has(symbol2.qualifiedName)||!containerKinds.has(symbol2.kind))continue;let children=this.getChildSymbols(symbol2,symbolTable),fullText=this.getFullElementText(symbol2,lines),parsedMessages=[],occ=1;for(let keyword of["flow","message"])for(let{afterPos}of findWordPositionsCI(fullText,keyword)){let nameStart=skipWS(fullText,afterPos),[name,afterName]=readIdent(fullText,nameStart);if(!name||name==="def")continue;let fromStart=skipWS(fullText,afterName),[fromKw,afterFromKw]=readIdent(fullText,fromStart);if(fromKw!=="from")continue;let srcStart=skipWS(fullText,afterFromKw),[srcRaw,afterSrc]=readIdent(fullText,srcStart,!0);if(!srcRaw)continue;let toStart=skipWS(fullText,afterSrc),[toKw,afterToKw]=readIdent(fullText,toStart);if(toKw!=="to")continue;let tgtStart=skipWS(fullText,afterToKw),[tgtRaw]=readIdent(fullText,tgtStart,!0);tgtRaw&&parsedMessages.push({name,from:rootName(srcRaw),to:rootName(tgtRaw),payload:name,occurrence:occ++,range:this.rangeToDTO(symbol2.range)})}if(parsedMessages.length===0)continue;let participants=[];for(let child of children)(child.kind==="part"||child.kind==="item"||child.kind==="part def"||child.kind==="item def"||child.kind==="ref")&&(participants.find(p=>p.name===child.name)||participants.push({name:child.name,type:child.typeNames.join(", ")||child.kind,range:this.rangeToDTO(child.range)}));for(let msg of parsedMessages)for(let endpoint of[msg.from,msg.to])endpoint&&!participants.find(p=>p.name===endpoint)&&participants.push({name:endpoint,type:"participant",range:this.rangeToDTO(symbol2.range)});let existingIdx=diagrams.findIndex(d=>d.name===symbol2.name);existingIdx>=0&&diagrams.splice(existingIdx,1),diagrams.push({name:symbol2.name,participants,messages:parsedMessages,range:this.rangeToDTO(symbol2.range)}),seen.add(symbol2.qualifiedName)}return diagrams}extractActivityDiagrams(symbolTable,uri,lines){let symbols=symbolTable.getSymbolsForUri(uri),diagrams=[];for(let symbol2 of symbols){if(symbol2.kind!=="action def"&&symbol2.kind!=="action")continue;let children=this.getChildSymbols(symbol2,symbolTable),hasChildActions=children.some(c=>c.kind==="action"||c.kind==="action def"||CONTROL_NODE_TYPE.has(c.kind));if(symbol2.kind==="action"&&!hasChildActions)continue;let actions=[],decisions=[],flows=[],states=[];for(let child of children){let childText=this.getElementText(child,lines),controlType=CONTROL_NODE_TYPE.get(child.kind);if(child.kind==="action"||child.kind==="action def"||controlType!==void 0){let actionType=controlType??"action";if(controlType===void 0){let lowerText=childText.toLowerCase();lowerText.includes("fork")?actionType="fork":lowerText.includes("join")?actionType="join":lowerText.includes("merge")?actionType="merge":lowerText.includes("decide")&&(actionType="decision")}let subActions=this.getChildSymbols(child,symbolTable).filter(c=>c.kind==="action"||c.kind==="action def").map(c=>this.symbolToActionDTO(c,symbolTable,lines));if(actions.push({name:child.name,type:actionType,kind:actionType,isDefinition:child.kind==="action def",range:this.rangeToDTO(child.range),parent:symbol2.name,children:subActions.map(a=>a.name),subActions:subActions.length>0?subActions:void 0}),actionType==="decision"){let branches=this.extractDecisionBranches(child,lines);decisions.push({name:child.name,condition:"",branches,range:this.rangeToDTO(child.range)})}}if(child.kind==="state"||child.kind==="state def"){let stateType=childText.toLowerCase().includes("initial")?"initial":childText.toLowerCase().includes("final")?"final":"intermediate";states.push({name:child.name,type:stateType,range:this.rangeToDTO(child.range)})}}let parsedFlows=symbol2.controlFlows?.map(flow=>({from:flow.source,to:flow.target,range:this.rangeToDTO(symbol2.range),...flow.guard?{guard:flow.guard}:{}}))??[],shorthandFlows=this.extractSuccessions(symbol2,lines),parsedKeys=new Set(parsedFlows.map(flow=>`${flow.from}->${flow.to}`));flows.push(...parsedFlows),flows.push(...shorthandFlows.filter(flow=>!parsedKeys.has(`${flow.from}->${flow.to}`)));let fullText=this.getFullElementText(symbol2,lines);if(findWordPositions(fullText,"decide").some(({afterPos})=>{let p=skipWS(fullText,afterPos);return p<fullText.length&&fullText[p]===";"})){let branches=[];for(let{afterPos:ifAfter}of findWordPositions(fullText,"if")){let thenIdx=fullText.indexOf("then",ifAfter);if(thenIdx<0)continue;let bBefore=thenIdx>0?fullText.charCodeAt(thenIdx-1):32,bAfter=thenIdx+4<fullText.length?fullText.charCodeAt(thenIdx+4):32;if(isIdentPart(bBefore)||isIdentPart(bAfter))continue;let condition=fullText.substring(ifAfter,thenIdx).trim(),[target]=readWordAfterKeyword(fullText,thenIdx+4);target&&branches.push({condition,target})}branches.length>0&&decisions.push({name:"decide",condition:"",branches,range:this.rangeToDTO(symbol2.range)})}if(flows.length>0){let hasStartFlow=flows.some(f=>f.from==="start"),hasDoneFlow=flows.some(f=>f.to==="done");hasStartFlow&&actions.unshift({name:"start",type:"initial",isDefinition:!1,range:this.rangeToDTO(symbol2.range)}),hasDoneFlow&&actions.push({name:"done",type:"final",isDefinition:!1,range:this.rangeToDTO(symbol2.range)}),flows.some(f=>f.from==="decide")&&actions.push({name:"decide",type:"decision",isDefinition:!1,range:this.rangeToDTO(symbol2.range)})}(actions.length>0||flows.length>0||states.length>0)&&diagrams.push({name:symbol2.name,actions,decisions,flows,states,range:this.rangeToDTO(symbol2.range)})}return diagrams}extractResolvedTypes(symbolTable,uri,lines){let symbols=symbolTable.getSymbolsForUri(uri),result={};for(let symbol2 of symbols){if(!isDefinition(symbol2.kind)&&symbol2.typeNames.length===0)continue;let specializes=[],specList=this.extractSpecializations(symbol2,lines);for(let s of specList)specializes.includes(s)||specializes.push(s);for(let tn of symbol2.typeNames)specializes.includes(tn)||specializes.push(tn);let specializationChain=[...specializes],features=this.getChildSymbols(symbol2,symbolTable).filter(c=>isUsage(c.kind)).map(c=>{let modifier=this.extractModifier(c,lines),direction=this.extractDirection(c,lines);return{name:c.name,kind:toMetaclassName(c.kind),type:c.typeNames.join(", ")||void 0,multiplicity:c.multiplicity??this.extractMultiplicity(c,lines),direction,visibility:c.visibility,isDerived:modifier?.split(", ").includes("derived")??!1,isReadonly:modifier?.split(", ").includes("readonly")??!1}});result[symbol2.qualifiedName]={qualifiedName:symbol2.qualifiedName,simpleName:symbol2.name,kind:symbol2.kind,isLibraryType:!1,specializationChain,specializes,features}}return result}extractSemanticDiagnostics(symbolTable,uri){let symbols=symbolTable.getSymbolsForUri(uri),diagnostics=[],allSymbolNames=new Set(symbolTable.getAllSymbols().map(s=>s.name));for(let symbol2 of symbols){for(let tn of symbol2.typeNames)allSymbolNames.has(tn)||diagnostics.push({code:"unresolved-type",message:`Type '${tn}' could not be resolved in the current scope`,severity:"warning",range:this.rangeToDTO(symbol2.selectionRange),elementName:symbol2.name});symbol2.kind==="enum def"&&(this.getChildSymbols(symbol2,symbolTable).some(c=>c.kind==="enum"||c.kind==="attribute")||diagnostics.push({code:"empty-enum",message:`Enumeration '${symbol2.name}' has no enum values defined`,severity:"info",range:this.rangeToDTO(symbol2.range),elementName:symbol2.name}))}return diagnostics}rangeToDTO(range){return{start:{line:range.start.line,character:range.start.character},end:{line:range.end.line,character:range.end.character}}}getChildSymbols(parent,symbolTable){return symbolTable.getSymbolsForUri(parent.uri).filter(s=>s.parentQualifiedName===parent.qualifiedName)}getElementText(symbol2,lines){let startLine=symbol2.range.start.line,endLine=Math.min(startLine+2,symbol2.range.end.line,lines.length-1);return lines.slice(startLine,endLine+1).join(`
136
136
  `)}getFullElementText(symbol2,lines){let startLine=symbol2.range.start.line,endLine=Math.min(symbol2.range.end.line,lines.length-1);return lines.slice(startLine,endLine+1).join(`
137
137
  `)}extractDirection(symbol2,lines){if(symbol2.kind!=="port"&&symbol2.kind!=="port def")return;let elementText=this.getElementText(symbol2,lines);if(containsWord(elementText,"inout"))return"inout";if(containsWord(elementText,"in"))return"in";if(containsWord(elementText,"out"))return"out"}extractMultiplicity(symbol2,lines){let elementText=this.getElementText(symbol2,lines),open=elementText.indexOf("[");if(open<0)return;let close=elementText.indexOf("]",open+1);if(!(close<0))return elementText.substring(open+1,close)}extractModifier(symbol2,lines){let elementText=this.getElementText(symbol2,lines),modifiers=[];return containsWord(elementText,"abstract")&&modifiers.push("abstract"),containsWord(elementText,"readonly")&&modifiers.push("readonly"),containsWord(elementText,"derived")&&modifiers.push("derived"),containsWord(elementText,"variation")&&modifiers.push("variation"),containsWord(elementText,"individual")&&modifiers.push("individual"),modifiers.length>0?modifiers.join(", "):void 0}extractValue(symbol2,lines){if(symbol2.kind!=="attribute")return;let elementText=this.getElementText(symbol2,lines),eqIdx=elementText.indexOf("=");if(eqIdx<0)return;let start=eqIdx+1;if(start<elementText.length&&elementText[start]==="=")return;start=skipWS(elementText,start);let end=start;for(;end<elementText.length;){let ch=elementText[end];if(ch===";"||ch==="{"||ch==="}"||ch===`
138
- `)break;end++}let val=elementText.substring(start,end).trim();if(val&&!val.includes("def")&&val.length<100)return val}extractSpecializations(symbol2,lines){let elementText=this.getElementText(symbol2,lines),colonGtIdx=elementText.indexOf(":>");if(colonGtIdx>=0&&!(colonGtIdx+2<elementText.length&&elementText[colonGtIdx+2]===">"))return readCommaSeparatedIdents(elementText,colonGtIdx+2);let specPositions=findWordPositions(elementText,"specializes");return specPositions.length>0?readCommaSeparatedIdents(elementText,specPositions[0].afterPos):[]}extractConnectionEndpoints(symbol2,lines){let elementText=this.getElementText(symbol2,lines),endpoints=[],connectPositions=findWordPositions(elementText,"connect");for(let{afterPos}of connectPositions){let[name1,end1]=readWordAfterKeyword(elementText,afterPos,!0);if(!name1)continue;let toPos=skipWS(elementText,end1);if(elementText.substring(toPos,toPos+2)==="to"){let afterTo=toPos+2,[name2]=readWordAfterKeyword(elementText,afterTo,!0);if(name2)return endpoints.push(name1,name2),endpoints}}let endPositions=findWordPositions(elementText,"end");for(let{afterPos}of endPositions){let[name]=readWordAfterKeyword(elementText,afterPos,!0);name&&endpoints.push(name)}return endpoints}extractStandaloneSatisfyVerify(text){let rels=[],keywords=["satisfy","verify"];for(let kw of keywords){let positions=findWordPositions(text,kw);for(let{afterPos}of positions){let pos=skipWS(text,afterPos),[nextWord,afterWord]=readNameOrQuoted(text,pos);nextWord==="requirement"?pos=skipWS(text,afterWord):pos=skipWS(text,afterPos);let[reqName,afterReq]=readNameOrQuoted(text,pos);if(!reqName||reqName==="requirement")continue;let byPos=skipWS(text,afterReq),[byWord,afterBy]=readIdent(text,byPos),source;if(byWord==="by"){let[byTarget]=readNameOrQuoted(text,skipWS(text,afterBy));if(!byTarget)continue;source=byTarget}rels.push({type:kw,source,target:reqName})}}return rels}extractKeywordRelationships(elementName,elementText){elementText=stripComments(elementText);let rels=[],subsetsPositions=findWordPositions(elementText,"subsets");if(subsetsPositions.length>0){let[target]=readWordAfterKeyword(elementText,subsetsPositions[0].afterPos);target&&rels.push({type:"subsetting",source:elementName,target})}let redefPositions=findWordPositions(elementText,"redefines");if(redefPositions.length>0){let[target]=readWordAfterKeyword(elementText,redefPositions[0].afterPos);target&&rels.push({type:"redefinition",source:elementName,target})}let satisfyPositions=findWordPositions(elementText,"satisfy");if(satisfyPositions.length>0){let pos=skipWS(elementText,satisfyPositions[0].afterPos),[nextWord,afterWord]=readNameOrQuoted(elementText,pos);nextWord==="requirement"&&(pos=skipWS(elementText,afterWord));let[reqName,afterReq]=readNameOrQuoted(elementText,pos);if(reqName&&reqName!=="requirement"){let satisfier=elementName,byPos=skipWS(elementText,afterReq),[byWord,afterBy]=readIdent(elementText,byPos);if(byWord==="by"){let[byTarget]=readNameOrQuoted(elementText,skipWS(elementText,afterBy));byTarget&&(satisfier=byTarget)}rels.push({type:"satisfy",source:satisfier,target:reqName})}}let verifyPositions=findWordPositions(elementText,"verify");if(verifyPositions.length>0){let pos=skipWS(elementText,verifyPositions[0].afterPos),[nextWord,afterWord]=readNameOrQuoted(elementText,pos);nextWord==="requirement"&&(pos=skipWS(elementText,afterWord));let[reqName,afterReq]=readNameOrQuoted(elementText,pos);if(reqName&&reqName!=="requirement"){let verifier=elementName,byPos=skipWS(elementText,afterReq),[byWord,afterBy]=readIdent(elementText,byPos);if(byWord==="by"){let[byTarget]=readNameOrQuoted(elementText,skipWS(elementText,afterBy));byTarget&&(verifier=byTarget)}rels.push({type:"verify",source:verifier,target:reqName})}}return rels}extractDecisionBranches(symbol2,lines){let elementText=this.getElementText(symbol2,lines),branches=[],ifPositions=findWordPositions(elementText,"if");for(let{afterPos}of ifPositions){let thenIdx=elementText.indexOf("then",afterPos);if(thenIdx<0)continue;let beforeThen=thenIdx>0?elementText.charCodeAt(thenIdx-1):32,afterThen=thenIdx+4<elementText.length?elementText.charCodeAt(thenIdx+4):32;if(isIdentPart(beforeThen)||isIdentPart(afterThen))continue;let condition=elementText.substring(afterPos,thenIdx).trim(),[target]=readWordAfterKeyword(elementText,thenIdx+4);target&&branches.push({condition,target})}let elsePositions=findWordPositions(elementText,"else");if(elsePositions.length>0){let[target]=readWordAfterKeyword(elementText,elsePositions[0].afterPos);target&&branches.push({condition:"else",target})}return branches}extractSuccessions(parent,lines){let elementText=this.getFullElementText(parent,lines),flows=[],seen=new Set,range=this.rangeToDTO(parent.range),addFlow=(from,to,guard)=>{if(from===to)return;let key=`${from}->${to}`;if(seen.has(key))return;seen.add(key);let f={from,to,range};guard&&(f.guard=guard),flows.push(f)};function braceDepthAt(text,pos){let depth=0;for(let i=0;i<pos&&i<text.length;i++)text[i]==="{"?depth++:text[i]==="}"&&depth--;return depth}let firstBrace=elementText.indexOf("{"),topDepth=firstBrace>=0?braceDepthAt(elementText,firstBrace+1):1,stripQualifier=name=>{let idx=name.lastIndexOf("::");return idx>=0?name.substring(idx+2):name},tokens=[];for(let{pos,afterPos}of findWordPositions(elementText,"first")){if(braceDepthAt(elementText,pos)!==topDepth)continue;let nameStart=skipWS(elementText,afterPos),[name]=readNameOrQuoted(elementText,nameStart);name&&tokens.push({type:"first",name:stripQualifier(name),index:pos})}for(let{pos,afterPos}of findWordPositions(elementText,"then")){if(braceDepthAt(elementText,pos)!==topDepth)continue;let lookbackStart=Math.max(0,pos-100),preceding=elementText.substring(lookbackStart,pos);if(containsWord(preceding,"if")&&!preceding.includes(";"))continue;let nameStart=skipWS(elementText,afterPos),[maybeAction,afterAction]=readIdent(elementText,nameStart);maybeAction==="action"&&(nameStart=skipWS(elementText,afterAction));let[name]=readNameOrQuoted(elementText,nameStart);!name||name==="if"||tokens.push({type:"then",name:stripQualifier(name),index:pos})}tokens.sort((a,b)=>a.index-b.index);let coveredIndices=new Set;for(let i=0;i<tokens.length;i++)if(tokens[i].type==="first"){let chain=[tokens[i].name];coveredIndices.add(i);for(let j=i+1;j<tokens.length&&tokens[j].type==="then";j++)chain.push(tokens[j].name),coveredIndices.add(j);for(let k=0;k<chain.length-1;k++)addFlow(chain[k],chain[k+1])}let uncoveredThens=tokens.filter((t,i)=>!coveredIndices.has(i)&&t.type==="then");if(uncoveredThens.length>0)for(let i=0;i<uncoveredThens.length-1;i++)addFlow(uncoveredThens[i].name,uncoveredThens[i+1].name);if(flows.length>0){let allTargets=new Set(flows.map(f=>f.to)),allSources=new Set(flows.map(f=>f.from)),entryActions=flows.map(f=>f.from).filter(name=>name!=="start"&&name!=="done"&&!allTargets.has(name)),exitActions=flows.map(f=>f.to).filter(name=>name!=="start"&&name!=="done"&&!allSources.has(name));entryActions.length>0&&addFlow("start",entryActions[0]),exitActions.length>0&&addFlow(exitActions[exitActions.length-1],"done")}for(let{afterPos}of findWordPositions(elementText,"succession")){let p=skipWS(elementText,afterPos),[word1,afterWord1]=readIdent(elementText,p);if(word1==="flow"){p=skipWS(elementText,afterWord1);let[fromKw,afterFrom]=readIdent(elementText,p);if(fromKw==="from"){p=skipWS(elementText,afterFrom);let[srcFull,afterSrc]=readIdent(elementText,p,!0),src=srcFull.includes(".")?srcFull.substring(0,srcFull.indexOf(".")):srcFull;p=skipWS(elementText,afterSrc);let[toKw,afterTo]=readIdent(elementText,p);if(toKw==="to"){p=skipWS(elementText,afterTo);let[dstFull]=readIdent(elementText,p,!0),dst=dstFull.includes(".")?dstFull.substring(0,dstFull.indexOf(".")):dstFull;src&&dst&&addFlow(src,dst)}}continue}let nameStart=p;word1==="first"&&(nameStart=skipWS(elementText,afterWord1));let[name1]=readNameOrQuoted(elementText,nameStart);if(!name1)continue;let afterName1=nameStart+name1.length+(elementText[nameStart]==="'"?2:0),thenCheck=skipWS(elementText,afterName1),[thenKw,afterThen]=readIdent(elementText,thenCheck);if(thenKw==="then"){let name2Start=skipWS(elementText,afterThen),[name2]=readNameOrQuoted(elementText,name2Start);name2&&addFlow(stripQualifier(name1),stripQualifier(name2))}}if(findWordPositions(elementText,"decide").some(({afterPos})=>{let p=skipWS(elementText,afterPos);return p<elementText.length&&elementText[p]===";"})){for(let fi=flows.length-1;fi>=0;fi--)flows[fi].from==="decide"&&(seen.delete(`decide->${flows[fi].to}`),flows.splice(fi,1));let branchTargets=[];for(let{afterPos:ifAfter}of findWordPositions(elementText,"if")){let thenIdx=elementText.indexOf("then",ifAfter);if(thenIdx<0)continue;let bBefore=thenIdx>0?elementText.charCodeAt(thenIdx-1):32,bAfter=thenIdx+4<elementText.length?elementText.charCodeAt(thenIdx+4):32;if(isIdentPart(bBefore)||isIdentPart(bAfter))continue;let condition=elementText.substring(ifAfter,thenIdx).trim(),targetStart=skipWS(elementText,thenIdx+4),[target]=readNameOrQuoted(elementText,targetStart);if(target){let afterTarget=targetStart+target.length+(elementText[targetStart]==="'"?2:0),semi=skipWS(elementText,afterTarget);semi<elementText.length&&elementText[semi]===";"&&(addFlow("decide",target,condition),branchTargets.push(target))}}for(let{pos:mergePos,afterPos:mergeAfter}of findWordPositions(elementText,"merge")){let mStart=skipWS(elementText,mergeAfter),[mergeTarget]=readNameOrQuoted(elementText,mStart);if(!mergeTarget)continue;let afterMT=mStart+mergeTarget.length+(elementText[mStart]==="'"?2:0),semiP=skipWS(elementText,afterMT);if(semiP>=elementText.length||elementText[semiP]!==";")continue;for(let branch of branchTargets)addFlow(branch,mergeTarget);let afterMerge=tokens.filter(t=>t.type==="then"&&t.index>mergePos);afterMerge.length>0?addFlow(mergeTarget,afterMerge[0].name):mergeTarget!=="done"&&addFlow(mergeTarget,"done")}}return flows}symbolToActionDTO(symbol2,symbolTable,lines){let controlType=CONTROL_NODE_TYPE.get(symbol2.kind),actionType=controlType??"action";if(controlType===void 0){let lowerText=this.getElementText(symbol2,lines).toLowerCase();lowerText.includes("fork")?actionType="fork":lowerText.includes("join")?actionType="join":lowerText.includes("merge")?actionType="merge":lowerText.includes("decide")&&(actionType="decision")}return{name:symbol2.name,type:actionType,kind:actionType,isDefinition:symbol2.kind==="action def",range:this.rangeToDTO(symbol2.range)}}};var STANDARD_LIBRARY_TYPES=new Set(["Boolean","String","Integer","Real","Natural","Positive","Complex","Number","Rational","ScalarValues","DataFunctions","Anything","Nothing","Object","Occurrence","Base","Objects","Occurrences","Items","Parts","Ports","Actions","States","Connections","Interfaces","Allocations","Requirements","Constraints","Calculations","Cases","Flows","Transfers","Performances","TransitionPerformances","ISQ","SI","USCustomaryUnits","Quantities","MeasurementReferences","ScalarValues","GeneralView","InterconnectionView","ActionFlowView","StateTransitionView","SequenceView","GeometryView","GridView","BrowserView","StandardViewDefinitions","View","ViewpointCheck","Rendering","TextualRendering","GraphicalRendering","TabularRendering","Views","LengthValue","MassValue","DurationValue","TimeValue","ElectricCurrentValue","ThermodynamicTemperatureValue","TemperatureValue","AmountOfSubstanceValue","LuminousIntensityValue","AreaValue","VolumeValue","SpeedValue","VelocityValue","AccelerationValue","ForceValue","EnergyValue","PowerValue","PressureValue","TorqueValue","MomentOfForceValue","AngularVelocityValue","FrequencyValue","DensityValue","MassFlowRateValue","VolumeFlowRateValue","LengthUnit","MassUnit","DurationUnit","TimeUnit"]),CONSTRAINT_KEYWORDS=new Set(["and","or","not","xor","implies","if","then","else","true","false","null","require","constraint","subject","return","doc","comment","assert","assume"]);function isISQValueType(name){if(!name.endsWith("Value")||name.length<6)return!1;let ch0=name.charCodeAt(0);if(ch0<65||ch0>90)return!1;for(let i=1;i<name.length;i++){let c=name.charCodeAt(i);if(!(c>=65&&c<=90||c>=97&&c<=122))return!1}return!0}var SemanticValidator=class _SemanticValidator{constructor(documentManager){this.documentManager=documentManager;this.modelProvider=new SysMLModelProvider(documentManager)}documentManager;modelProvider;satisfyCache;verifyCache;indexCache;symbolNamesCache;libraryNamesCache;addRequirementNameVariants(out,ref){if(!ref)return;let trimmed=ref.trim();if(!trimmed)return;out.add(trimmed);let lastSeg=trimmed.includes("::")?trimmed.split("::").pop():trimmed;out.add(lastSeg)}collectWorkspaceRequirementRelationshipNames(){let satisfiedNames=new Set,verifiedNames=new Set,uris=this.documentManager.getUris();for(let uri of uris){let version2=this.documentManager.getVersion(uri);if(version2<0)continue;let rels=this.modelProvider.getModel(uri,version2,["relationships"]).relationships??[];for(let rel of rels)rel.type==="satisfy"?this.addRequirementNameVariants(satisfiedNames,rel.target):rel.type==="verify"&&this.addRequirementNameVariants(verifiedNames,rel.target)}return{satisfiedNames,verifiedNames}}validate(uri){let symbolTable=this.documentManager.getWorkspaceSymbolTable(),symbols=symbolTable.getSymbolsForUri(uri);if(symbols.length===0)return[];let allSymbols=symbolTable.getAllSymbols(),allSymbolNames;this.symbolNamesCache&&this.symbolNamesCache.symbols===allSymbols?allSymbolNames=this.symbolNamesCache.names:(allSymbolNames=new Set(allSymbols.map(s=>s.name)),this.symbolNamesCache={symbols:allSymbols,names:allSymbolNames}),this.libraryNamesCache||(this.libraryNamesCache=new Set(getLibraryPackageNames()));let libraryNames=this.libraryNamesCache,text=this.documentManager.getText(uri)??"",indexes=this.getOrBuildIndexes(allSymbols),diagnostics=[];for(let symbol2 of symbols)diagnostics.push(...this.checkUnresolvedType(symbol2,allSymbolNames,libraryNames),...this.checkInvalidMultiplicity(symbol2),...this.checkEmptyEnum(symbol2,symbols),...this.checkNamingConvention(symbol2),...this.checkMissingDocumentation(symbol2));return diagnostics.push(...this.checkDuplicateDefinitions(symbols)),diagnostics.push(...this.checkUnusedDefinitions(allSymbols,uri)),diagnostics.push(...this.checkRedefinitionMultiplicity(symbols,indexes,text)),diagnostics.push(...this.checkPortCompatibility(text,uri,indexes)),diagnostics.push(...this.checkConstraintBodyReferences(text,uri,symbols,indexes)),diagnostics.push(...this.checkCircularSpecialization(symbols,indexes)),diagnostics.push(...this.checkCircularContainment(symbols,indexes)),diagnostics.push(...this.checkUnsatisfiedRequirements(symbols,indexes)),diagnostics.push(...this.checkUnverifiedRequirements(symbols,indexes)),diagnostics.push(...this.checkViewpointSatisfaction(symbols,indexes)),this.dedupeDiagnostics(diagnostics)}checkUnresolvedType(symbol2,allSymbolNames,libraryNames){if(!symbol2.typeName)return[];let typeName=symbol2.typeName,kwMatch=typeName.match(/^([A-Z][A-Za-z_0-9]*?)(redefines|subsets|references|connect|bind|default|via|accept|send|flow|allocate|assign|decide|merge|join|fork)([A-Z])/);kwMatch&&(typeName=kwMatch[1]);let rootSegment=typeName.split("::")[0];if(allSymbolNames.has(typeName)||allSymbolNames.has(rootSegment)||STANDARD_LIBRARY_TYPES.has(typeName)||STANDARD_LIBRARY_TYPES.has(rootSegment)||libraryNames.has(rootSegment)||isISQValueType(typeName)||resolveLibraryType(typeName)!==void 0||resolveLibraryType(rootSegment)!==void 0||typeName.charCodeAt(0)>=97&&typeName.charCodeAt(0)<=122)return[];let isMandatory=symbol2.multiplicityRange&&symbol2.multiplicityRange.lower>=1,severity=isMandatory?import_node.DiagnosticSeverity.Error:import_node.DiagnosticSeverity.Warning,message=`Type '${typeName}' is not defined in the current document or standard library`;if(isMandatory){let multStr=symbol2.multiplicity??"1";message+=` (feature '${symbol2.name}' requires multiplicity [${multStr}])`}return[{severity,range:symbol2.selectionRange,message,source:"sysml",code:"unresolved-type",data:{typeName}}]}checkInvalidMultiplicity(symbol2){if(!symbol2.multiplicityRange||!symbol2.multiplicity)return[];let{lower,upper}=symbol2.multiplicityRange;return typeof upper=="number"&&lower>upper?[{severity:import_node.DiagnosticSeverity.Error,range:symbol2.selectionRange,message:`Invalid multiplicity [${symbol2.multiplicity}]: lower bound (${lower}) exceeds upper bound (${upper})`,source:"sysml",code:"invalid-multiplicity"}]:lower<0?[{severity:import_node.DiagnosticSeverity.Error,range:symbol2.selectionRange,message:`Invalid multiplicity [${symbol2.multiplicity}]: lower bound cannot be negative`,source:"sysml",code:"invalid-multiplicity"}]:[]}checkEmptyEnum(symbol2,allSymbols){return symbol2.kind!=="enum def"?[]:allSymbols.filter(s=>s.parentQualifiedName===symbol2.qualifiedName).some(c=>c.kind==="enum"||c.kind==="attribute")?[]:[{severity:import_node.DiagnosticSeverity.Information,range:symbol2.selectionRange,message:`Enumeration '${symbol2.name}' has no enum values defined`,source:"sysml",code:"empty-enum"}]}checkNamingConvention(symbol2){if(!symbol2.name)return[];if(symbol2.kind==="package"||symbol2.kind==="import"||symbol2.kind==="comment"||symbol2.kind==="doc"||symbol2.kind==="alias"||symbol2.kind==="unknown")return[];if(isDefinition(symbol2.kind)){let ch=symbol2.name[0];if(ch===ch.toLowerCase()&&ch!==ch.toUpperCase())return[{severity:import_node.DiagnosticSeverity.Hint,range:symbol2.selectionRange,message:`Definition '${symbol2.name}' should use PascalCase`,source:"sysml",code:"naming-convention",data:{name:symbol2.name,convention:"PascalCase"}}]}else{let ch=symbol2.name[0];if(ch===ch.toUpperCase()&&ch!==ch.toLowerCase())return[{severity:import_node.DiagnosticSeverity.Hint,range:symbol2.selectionRange,message:`Usage '${symbol2.name}' should use camelCase`,source:"sysml",code:"naming-convention",data:{name:symbol2.name,convention:"camelCase"}}]}return[]}checkMissingDocumentation(symbol2){return isDefinition(symbol2.kind)?symbol2.documentation?[]:[{severity:import_node.DiagnosticSeverity.Information,range:symbol2.selectionRange,message:`Definition '${symbol2.name}' has no documentation`,source:"sysml",code:"missing-doc",data:{name:symbol2.name}}]:[]}checkUnusedDefinitions(symbols,targetUri){let defs=symbols.filter(s=>s.kind==="part def"||s.kind==="action def"),defsInScope=targetUri?defs.filter(def=>def.uri===targetUri):defs,referencedTypes=new Set(symbols.filter(s=>s.kind!=="package").flatMap(s=>s.typeNames));for(let s of symbols)if(s.exposeTargets)for(let target of s.exposeTargets){let simpleName=target.replace(/::\*{1,2}$/,"").split("::").pop();simpleName&&referencedTypes.add(simpleName)}let diagnostics=[];for(let def of defsInScope){let isReferenced=referencedTypes.has(def.name),hasBaseType=(def.typeNames?.length??0)>0;!isReferenced&&!hasBaseType&&diagnostics.push({severity:import_node.DiagnosticSeverity.Warning,range:def.selectionRange,message:`Definition '${def.name}' is not referenced by any usage in the workspace`,source:"sysml",code:"unused-definition",data:{name:def.name}})}return diagnostics}static validateSymbols(symbolsInUri,allNames,opts){let diagnostics=[],instance=Object.create(_SemanticValidator.prototype),allSymbols=opts?.allSymbols??symbolsInUri,includeStyleRules=opts?.includeStyleRules??!0,indexes=instance.buildSymbolIndexes(allSymbols);for(let symbol2 of symbolsInUri)diagnostics.push(...instance.checkUnresolvedType(symbol2,allNames,new Set),...instance.checkInvalidMultiplicity(symbol2),...instance.checkEmptyEnum(symbol2,symbolsInUri)),includeStyleRules&&diagnostics.push(...instance.checkNamingConvention(symbol2),...instance.checkMissingDocumentation(symbol2));return diagnostics.push(...instance.checkDuplicateDefinitions(symbolsInUri)),diagnostics.push(...instance.checkUnusedDefinitions(allSymbols)),diagnostics.push(...instance.checkRedefinitionMultiplicity(symbolsInUri,indexes,opts?.text)),diagnostics.push(...instance.checkCircularSpecialization(symbolsInUri,indexes)),diagnostics.push(...instance.checkCircularContainment(symbolsInUri,indexes)),diagnostics.push(...instance.checkUnsatisfiedRequirements(allSymbols,indexes,opts?.text?[opts.text]:[])),diagnostics.push(...instance.checkUnverifiedRequirements(allSymbols,indexes,opts?.text?[opts.text]:[])),opts?.text&&opts.uri&&(diagnostics.push(...instance.checkPortCompatibility(opts.text,opts.uri,indexes)),diagnostics.push(...instance.checkConstraintBodyReferences(opts.text,opts.uri,symbolsInUri,indexes))),instance.dedupeDiagnostics(diagnostics)}checkCircularSpecialization(symbolsInUri,indexes){let diagnostics=[],defsInFile=symbolsInUri.filter(s=>isDefinition(s.kind)&&s.typeNames.length>0);for(let def of defsInFile){let visited=new Set;visited.add(def.name);let cycle=this.followSpecializationChain(def.name,def.typeNames,visited,indexes);cycle&&diagnostics.push({severity:import_node.DiagnosticSeverity.Error,range:def.selectionRange,message:`Circular specialization: ${cycle.join(" :> ")} :> ${cycle[0]}`,source:"sysml",code:"circular-specialization"})}return diagnostics}followSpecializationChain(originName,typeNames,visited,indexes){for(let tn of typeNames){if(visited.has(tn))return[...visited];let candidates=indexes.definitionsByName.get(tn);if(!candidates||candidates.length===0)continue;let target=candidates[0];if(target.typeNames.length===0)continue;visited.add(tn);let cycle=this.followSpecializationChain(originName,target.typeNames,visited,indexes);if(cycle)return cycle;visited.delete(tn)}}checkCircularContainment(symbolsInUri,indexes){let diagnostics=[],defsInFile=symbolsInUri.filter(s=>isDefinition(s.kind));for(let def of defsInFile){let children=indexes.byParent.get(def.qualifiedName)??[],childTypeNames=children.flatMap(c=>c.typeNames).filter(t=>t.length>0);if(childTypeNames.length!==0)for(let childTypeName of childTypeNames){if(childTypeName===def.name)continue;let visited=new Set;visited.add(def.name);let cycle=this.followContainmentChain(childTypeName,visited,indexes);if(cycle){let range=children.find(c=>c.typeNames.includes(childTypeName))?.selectionRange??def.selectionRange;diagnostics.push({severity:import_node.DiagnosticSeverity.Error,range,message:`Circular containment: ${cycle.join(" -> ")} -> ${cycle[0]}`,source:"sysml",code:"circular-containment"});break}}}return diagnostics}followContainmentChain(typeName,visited,indexes){if(visited.has(typeName))return[...visited];let candidates=indexes.definitionsByName.get(typeName);if(!candidates||candidates.length===0)return;let target=candidates[0],childTypeNames=(indexes.byParent.get(target.qualifiedName)??[]).flatMap(c=>c.typeNames).filter(t=>t.length>0);if(childTypeNames.length!==0){visited.add(typeName);for(let tn of childTypeNames){let cycle=this.followContainmentChain(tn,visited,indexes);if(cycle)return cycle}visited.delete(typeName)}}checkUnsatisfiedRequirements(allSymbols,indexes,workspaceTexts){let diagnostics=[],satisfiedNames,satisfyBlockRanges;if(workspaceTexts){satisfiedNames=new Set,satisfyBlockRanges=new Map;for(let text of workspaceTexts)this.extractSatisfyReferences(text,satisfiedNames),satisfyBlockRanges.set("__static__",this.extractSatisfyBlockRanges(text))}else if(this.documentManager){let uris=this.documentManager.getUris(),versionKey=uris.map(u=>u+":"+this.documentManager.getVersion(u)).join("|");if(this.satisfyCache&&this.satisfyCache.versionKey===versionKey)satisfiedNames=this.satisfyCache.satisfiedNames,satisfyBlockRanges=this.satisfyCache.satisfyBlockRanges;else{let relNames=this.collectWorkspaceRequirementRelationshipNames();satisfiedNames=relNames.satisfiedNames,satisfyBlockRanges=new Map;for(let uri of uris){let text=this.documentManager.getText(uri);text&&satisfyBlockRanges.set(uri,this.extractSatisfyBlockRanges(text))}this.satisfyCache={versionKey,satisfiedNames,satisfyBlockRanges},(!this.verifyCache||this.verifyCache.versionKey!==versionKey)&&(this.verifyCache={versionKey,verifiedNames:relNames.verifiedNames})}}else satisfiedNames=new Set,satisfyBlockRanges=new Map;let requirementUsages=allSymbols.filter(s=>s.kind==="requirement");for(let req of requirementUsages){if(req.parentQualifiedName&&indexes.byQualifiedName.get(req.parentQualifiedName)?.kind==="requirement")continue;let uriRanges=satisfyBlockRanges.get(req.uri)??satisfyBlockRanges.get("__static__")??[],reqLine=req.selectionRange.start.line;if(uriRanges.some(r=>reqLine>=r.startLine&&reqLine<=r.endLine))continue;satisfiedNames.has(req.name)||satisfiedNames.has(req.qualifiedName)||diagnostics.push({severity:import_node.DiagnosticSeverity.Warning,range:req.selectionRange,message:`Requirement '${req.name}' is not satisfied by any element`,source:"sysml",code:"unsatisfied-requirement",data:{name:req.name,qualifiedName:req.qualifiedName}})}return diagnostics}extractSatisfyReferences(text,out){let stripped=stripComments(text),re=/\bsatisfy\s+(?:requirement\s+)?([\w]+(?:::[\w]+)*)\s+(?:by\b|;|:)/g,m2;for(;(m2=re.exec(stripped))!==null;){let ref=m2[1];out.add(ref);let lastSeg=ref.includes("::")?ref.split("::").pop():ref;out.add(lastSeg)}}extractSatisfyBlockRanges(text){let ranges=[],stripped=stripComments(text),re=/\bsatisfy\b[^;{]*\{/g,m2,lineOffsets;for(;(m2=re.exec(stripped))!==null;){let open=m2.index+m2[0].length-1,depth=1,i=open+1;for(;i<stripped.length&&depth>0;)stripped[i]==="{"&&depth++,stripped[i]==="}"&&depth--,i++;if(depth===0){if(!lineOffsets){lineOffsets=[0];for(let j=0;j<text.length;j++)text[j]===`
138
+ `)break;end++}let val=elementText.substring(start,end).trim();if(val&&!val.includes("def")&&val.length<100)return val}extractSpecializations(symbol2,lines){let elementText=this.getElementText(symbol2,lines),colonGtIdx=elementText.indexOf(":>");if(colonGtIdx>=0&&!(colonGtIdx+2<elementText.length&&elementText[colonGtIdx+2]===">"))return readCommaSeparatedIdents(elementText,colonGtIdx+2);let specPositions=findWordPositions(elementText,"specializes");return specPositions.length>0?readCommaSeparatedIdents(elementText,specPositions[0].afterPos):[]}extractConnectionEndpoints(symbol2,lines){let elementText=this.getElementText(symbol2,lines),endpoints=[],connectPositions=findWordPositions(elementText,"connect");for(let{afterPos}of connectPositions){let[name1,end1]=readWordAfterKeyword(elementText,afterPos,!0);if(!name1)continue;let toPos=skipWS(elementText,end1);if(elementText.substring(toPos,toPos+2)==="to"){let afterTo=toPos+2,[name2]=readWordAfterKeyword(elementText,afterTo,!0);if(name2)return endpoints.push(name1,name2),endpoints}}let endPositions=findWordPositions(elementText,"end");for(let{afterPos}of endPositions){let[name]=readWordAfterKeyword(elementText,afterPos,!0);name&&endpoints.push(name)}return endpoints}extractStandaloneSatisfyVerify(text){let rels=[],keywords=["satisfy","verify"];for(let kw of keywords){let positions=findWordPositions(text,kw);for(let{afterPos}of positions){let pos=skipWS(text,afterPos),[nextWord,afterWord]=readNameOrQuoted(text,pos);nextWord==="requirement"?pos=skipWS(text,afterWord):pos=skipWS(text,afterPos);let[reqName,afterReq]=readNameOrQuoted(text,pos);if(!reqName||reqName==="requirement")continue;let byPos=skipWS(text,afterReq),[byWord,afterBy]=readIdent(text,byPos),source;if(byWord==="by"){let[byTarget]=readNameOrQuoted(text,skipWS(text,afterBy));if(!byTarget)continue;source=byTarget}rels.push({type:kw,source,target:reqName})}}return rels}extractKeywordRelationships(elementName,elementText){elementText=stripComments(elementText);let rels=[],subsetsPositions=findWordPositions(elementText,"subsets");if(subsetsPositions.length>0){let[target]=readWordAfterKeyword(elementText,subsetsPositions[0].afterPos);target&&rels.push({type:"subsetting",source:elementName,target})}let redefPositions=findWordPositions(elementText,"redefines");if(redefPositions.length>0){let[target]=readWordAfterKeyword(elementText,redefPositions[0].afterPos);target&&rels.push({type:"redefinition",source:elementName,target})}let satisfyPositions=findWordPositions(elementText,"satisfy");if(satisfyPositions.length>0){let pos=skipWS(elementText,satisfyPositions[0].afterPos),[nextWord,afterWord]=readNameOrQuoted(elementText,pos);nextWord==="requirement"&&(pos=skipWS(elementText,afterWord));let[reqName,afterReq]=readNameOrQuoted(elementText,pos);if(reqName&&reqName!=="requirement"){let satisfier=elementName,byPos=skipWS(elementText,afterReq),[byWord,afterBy]=readIdent(elementText,byPos);if(byWord==="by"){let[byTarget]=readNameOrQuoted(elementText,skipWS(elementText,afterBy));byTarget&&(satisfier=byTarget)}rels.push({type:"satisfy",source:satisfier,target:reqName})}}let verifyPositions=findWordPositions(elementText,"verify");if(verifyPositions.length>0){let pos=skipWS(elementText,verifyPositions[0].afterPos),[nextWord,afterWord]=readNameOrQuoted(elementText,pos);nextWord==="requirement"&&(pos=skipWS(elementText,afterWord));let[reqName,afterReq]=readNameOrQuoted(elementText,pos);if(reqName&&reqName!=="requirement"){let verifier=elementName,byPos=skipWS(elementText,afterReq),[byWord,afterBy]=readIdent(elementText,byPos);if(byWord==="by"){let[byTarget]=readNameOrQuoted(elementText,skipWS(elementText,afterBy));byTarget&&(verifier=byTarget)}rels.push({type:"verify",source:verifier,target:reqName})}}return rels}extractDecisionBranches(symbol2,lines){let elementText=this.getElementText(symbol2,lines),branches=[],ifPositions=findWordPositions(elementText,"if");for(let{afterPos}of ifPositions){let thenIdx=elementText.indexOf("then",afterPos);if(thenIdx<0)continue;let beforeThen=thenIdx>0?elementText.charCodeAt(thenIdx-1):32,afterThen=thenIdx+4<elementText.length?elementText.charCodeAt(thenIdx+4):32;if(isIdentPart(beforeThen)||isIdentPart(afterThen))continue;let condition=elementText.substring(afterPos,thenIdx).trim(),[target]=readWordAfterKeyword(elementText,thenIdx+4);target&&branches.push({condition,target})}let elsePositions=findWordPositions(elementText,"else");if(elsePositions.length>0){let[target]=readWordAfterKeyword(elementText,elsePositions[0].afterPos);target&&branches.push({condition:"else",target})}return branches}extractSuccessions(parent,lines){let elementText=this.getFullElementText(parent,lines),flows=[],seen=new Set,range=this.rangeToDTO(parent.range),addFlow=(from,to,guard)=>{if(from===to)return;let key=`${from}->${to}`;if(seen.has(key))return;seen.add(key);let f={from,to,range};guard&&(f.guard=guard),flows.push(f)};function braceDepthAt(text,pos){let depth=0;for(let i=0;i<pos&&i<text.length;i++)text[i]==="{"?depth++:text[i]==="}"&&depth--;return depth}let firstBrace=elementText.indexOf("{"),topDepth=firstBrace>=0?braceDepthAt(elementText,firstBrace+1):1,stripQualifier=name=>{let idx=name.lastIndexOf("::");return idx>=0?name.substring(idx+2):name},tokens=[];for(let{pos,afterPos}of findWordPositions(elementText,"first")){if(braceDepthAt(elementText,pos)!==topDepth)continue;let nameStart=skipWS(elementText,afterPos),[name]=readNameOrQuoted(elementText,nameStart);name&&tokens.push({type:"first",name:stripQualifier(name),index:pos})}for(let{pos,afterPos}of findWordPositions(elementText,"then")){if(braceDepthAt(elementText,pos)!==topDepth)continue;let lookbackStart=Math.max(0,pos-100),preceding=elementText.substring(lookbackStart,pos);if(containsWord(preceding,"if")&&!preceding.includes(";"))continue;let nameStart=skipWS(elementText,afterPos),[maybeAction,afterAction]=readIdent(elementText,nameStart);maybeAction==="action"&&(nameStart=skipWS(elementText,afterAction));let[name]=readNameOrQuoted(elementText,nameStart);!name||name==="if"||tokens.push({type:"then",name:stripQualifier(name),index:pos})}tokens.sort((a,b)=>a.index-b.index);let coveredIndices=new Set;for(let i=0;i<tokens.length;i++)if(tokens[i].type==="first"){let chain=[tokens[i].name];coveredIndices.add(i);for(let j=i+1;j<tokens.length&&tokens[j].type==="then";j++)chain.push(tokens[j].name),coveredIndices.add(j);for(let k=0;k<chain.length-1;k++)addFlow(chain[k],chain[k+1])}let uncoveredThens=tokens.filter((t,i)=>!coveredIndices.has(i)&&t.type==="then");if(uncoveredThens.length>0)for(let i=0;i<uncoveredThens.length-1;i++)addFlow(uncoveredThens[i].name,uncoveredThens[i+1].name);if(flows.length>0){let allTargets=new Set(flows.map(f=>f.to)),allSources=new Set(flows.map(f=>f.from)),entryActions=flows.map(f=>f.from).filter(name=>name!=="start"&&name!=="done"&&!allTargets.has(name)),exitActions=flows.map(f=>f.to).filter(name=>name!=="start"&&name!=="done"&&!allSources.has(name));entryActions.length>0&&addFlow("start",entryActions[0]),exitActions.length>0&&addFlow(exitActions[exitActions.length-1],"done")}for(let{afterPos}of findWordPositions(elementText,"succession")){let p=skipWS(elementText,afterPos),[word1,afterWord1]=readIdent(elementText,p);if(word1==="flow"){p=skipWS(elementText,afterWord1);let[fromKw,afterFrom]=readIdent(elementText,p);if(fromKw==="from"){p=skipWS(elementText,afterFrom);let[srcFull,afterSrc]=readIdent(elementText,p,!0),src=srcFull.includes(".")?srcFull.substring(0,srcFull.indexOf(".")):srcFull;p=skipWS(elementText,afterSrc);let[toKw,afterTo]=readIdent(elementText,p);if(toKw==="to"){p=skipWS(elementText,afterTo);let[dstFull]=readIdent(elementText,p,!0),dst=dstFull.includes(".")?dstFull.substring(0,dstFull.indexOf(".")):dstFull;src&&dst&&addFlow(src,dst)}}continue}let nameStart=p;word1==="first"&&(nameStart=skipWS(elementText,afterWord1));let[name1]=readNameOrQuoted(elementText,nameStart);if(!name1)continue;let afterName1=nameStart+name1.length+(elementText[nameStart]==="'"?2:0),thenCheck=skipWS(elementText,afterName1),[thenKw,afterThen]=readIdent(elementText,thenCheck);if(thenKw==="then"){let name2Start=skipWS(elementText,afterThen),[name2]=readNameOrQuoted(elementText,name2Start);name2&&addFlow(stripQualifier(name1),stripQualifier(name2))}}if(findWordPositions(elementText,"decide").some(({afterPos})=>{let p=skipWS(elementText,afterPos);return p<elementText.length&&elementText[p]===";"})){for(let fi=flows.length-1;fi>=0;fi--)flows[fi].from==="decide"&&(seen.delete(`decide->${flows[fi].to}`),flows.splice(fi,1));let branchTargets=[];for(let{afterPos:ifAfter}of findWordPositions(elementText,"if")){let thenIdx=elementText.indexOf("then",ifAfter);if(thenIdx<0)continue;let bBefore=thenIdx>0?elementText.charCodeAt(thenIdx-1):32,bAfter=thenIdx+4<elementText.length?elementText.charCodeAt(thenIdx+4):32;if(isIdentPart(bBefore)||isIdentPart(bAfter))continue;let condition=elementText.substring(ifAfter,thenIdx).trim(),targetStart=skipWS(elementText,thenIdx+4),[target]=readNameOrQuoted(elementText,targetStart);if(target){let afterTarget=targetStart+target.length+(elementText[targetStart]==="'"?2:0),semi=skipWS(elementText,afterTarget);semi<elementText.length&&elementText[semi]===";"&&(addFlow("decide",target,condition),branchTargets.push(target))}}for(let{pos:mergePos,afterPos:mergeAfter}of findWordPositions(elementText,"merge")){let mStart=skipWS(elementText,mergeAfter),[mergeTarget]=readNameOrQuoted(elementText,mStart);if(!mergeTarget)continue;let afterMT=mStart+mergeTarget.length+(elementText[mStart]==="'"?2:0),semiP=skipWS(elementText,afterMT);if(semiP>=elementText.length||elementText[semiP]!==";")continue;for(let branch of branchTargets)addFlow(branch,mergeTarget);let afterMerge=tokens.filter(t=>t.type==="then"&&t.index>mergePos);afterMerge.length>0?addFlow(mergeTarget,afterMerge[0].name):mergeTarget!=="done"&&addFlow(mergeTarget,"done")}}return flows}symbolToActionDTO(symbol2,symbolTable,lines){let controlType=CONTROL_NODE_TYPE.get(symbol2.kind),actionType=controlType??"action";if(controlType===void 0){let lowerText=this.getElementText(symbol2,lines).toLowerCase();lowerText.includes("fork")?actionType="fork":lowerText.includes("join")?actionType="join":lowerText.includes("merge")?actionType="merge":lowerText.includes("decide")&&(actionType="decision")}return{name:symbol2.name,type:actionType,kind:actionType,isDefinition:symbol2.kind==="action def",range:this.rangeToDTO(symbol2.range)}}};var STANDARD_LIBRARY_TYPES=new Set(["Boolean","String","Integer","Real","Natural","Positive","Complex","Number","Rational","ScalarValues","DataFunctions","Anything","Nothing","Object","Occurrence","Base","Objects","Occurrences","Items","Parts","Ports","Actions","States","Connections","Interfaces","Allocations","Requirements","Constraints","Calculations","Cases","Flows","Transfers","Performances","TransitionPerformances","ISQ","SI","USCustomaryUnits","Quantities","MeasurementReferences","ScalarValues","GeneralView","InterconnectionView","ActionFlowView","StateTransitionView","SequenceView","GeometryView","GridView","BrowserView","StandardViewDefinitions","View","ViewpointCheck","Rendering","TextualRendering","GraphicalRendering","TabularRendering","Views","LengthValue","MassValue","DurationValue","TimeValue","ElectricCurrentValue","ThermodynamicTemperatureValue","TemperatureValue","AmountOfSubstanceValue","LuminousIntensityValue","AreaValue","VolumeValue","SpeedValue","VelocityValue","AccelerationValue","ForceValue","EnergyValue","PowerValue","PressureValue","TorqueValue","MomentOfForceValue","AngularVelocityValue","FrequencyValue","DensityValue","MassFlowRateValue","VolumeFlowRateValue","LengthUnit","MassUnit","DurationUnit","TimeUnit"]),CONSTRAINT_KEYWORDS=new Set(["and","or","not","xor","implies","if","then","else","true","false","null","require","constraint","subject","return","doc","comment","assert","assume"]);function isISQValueType(name){if(!name.endsWith("Value")||name.length<6)return!1;let ch0=name.charCodeAt(0);if(ch0<65||ch0>90)return!1;for(let i=1;i<name.length;i++){let c=name.charCodeAt(i);if(!(c>=65&&c<=90||c>=97&&c<=122))return!1}return!0}var SemanticValidator=class _SemanticValidator{constructor(documentManager){this.documentManager=documentManager;this.modelProvider=new SysMLModelProvider(documentManager)}documentManager;modelProvider;satisfyCache;verifyCache;indexCache;symbolNamesCache;libraryNamesCache;addRequirementNameVariants(out,ref){if(!ref)return;let trimmed=ref.trim();if(!trimmed)return;out.add(trimmed);let lastSeg=trimmed.includes("::")?trimmed.split("::").pop():trimmed;out.add(lastSeg)}collectWorkspaceRequirementRelationshipNames(){let satisfiedNames=new Set,verifiedNames=new Set,uris=this.documentManager.getUris();for(let uri of uris){let version2=this.documentManager.getVersion(uri);if(version2<0)continue;let rels=this.modelProvider.getModel(uri,version2,["relationships"]).relationships??[];for(let rel of rels)rel.type==="satisfy"?this.addRequirementNameVariants(satisfiedNames,rel.target):rel.type==="verify"&&this.addRequirementNameVariants(verifiedNames,rel.target)}return{satisfiedNames,verifiedNames}}validate(uri){let symbolTable=this.documentManager.getWorkspaceSymbolTable(),symbols=symbolTable.getSymbolsForUri(uri);if(symbols.length===0)return[];let allSymbols=symbolTable.getAllSymbols(),allSymbolNames;this.symbolNamesCache&&this.symbolNamesCache.symbols===allSymbols?allSymbolNames=this.symbolNamesCache.names:(allSymbolNames=new Set(allSymbols.map(s=>s.name)),this.symbolNamesCache={symbols:allSymbols,names:allSymbolNames}),this.libraryNamesCache||(this.libraryNamesCache=new Set(getLibraryPackageNames()));let libraryNames=this.libraryNamesCache,text=this.documentManager.getText(uri)??"",indexes=this.getOrBuildIndexes(allSymbols),diagnostics=[];for(let symbol2 of symbols)diagnostics.push(...this.checkUnresolvedType(symbol2,allSymbolNames,libraryNames),...this.checkInvalidMultiplicity(symbol2),...this.checkEmptyEnum(symbol2,symbols),...this.checkNamingConvention(symbol2),...this.checkMissingDocumentation(symbol2));return diagnostics.push(...this.checkDuplicateDefinitions(symbols)),diagnostics.push(...this.checkUnusedDefinitions(allSymbols,uri)),diagnostics.push(...this.checkRedefinitionMultiplicity(symbols,indexes,text)),diagnostics.push(...this.checkPortCompatibility(text,uri,indexes)),diagnostics.push(...this.checkConstraintBodyReferences(text,uri,symbols,indexes)),diagnostics.push(...this.checkCircularSpecialization(symbols,indexes)),diagnostics.push(...this.checkUnsatisfiedRequirements(symbols,indexes)),diagnostics.push(...this.checkUnverifiedRequirements(symbols,indexes)),diagnostics.push(...this.checkViewpointSatisfaction(symbols,indexes)),this.dedupeDiagnostics(diagnostics)}checkUnresolvedType(symbol2,allSymbolNames,libraryNames){if(!symbol2.typeName)return[];let typeName=symbol2.typeName,kwMatch=typeName.match(/^([A-Z][A-Za-z_0-9]*?)(redefines|subsets|references|connect|bind|default|via|accept|send|flow|allocate|assign|decide|merge|join|fork)([A-Z])/);kwMatch&&(typeName=kwMatch[1]);let rootSegment=typeName.split("::")[0];if(allSymbolNames.has(typeName)||allSymbolNames.has(rootSegment)||STANDARD_LIBRARY_TYPES.has(typeName)||STANDARD_LIBRARY_TYPES.has(rootSegment)||libraryNames.has(rootSegment)||isISQValueType(typeName)||resolveLibraryType(typeName)!==void 0||resolveLibraryType(rootSegment)!==void 0||typeName.charCodeAt(0)>=97&&typeName.charCodeAt(0)<=122)return[];let isMandatory=symbol2.multiplicityRange&&symbol2.multiplicityRange.lower>=1,severity=isMandatory?import_node.DiagnosticSeverity.Error:import_node.DiagnosticSeverity.Warning,message=`Type '${typeName}' is not defined in the current document or standard library`;if(isMandatory){let multStr=symbol2.multiplicity??"1";message+=` (feature '${symbol2.name}' requires multiplicity [${multStr}])`}return[{severity,range:symbol2.selectionRange,message,source:"sysml",code:"unresolved-type",data:{typeName}}]}checkInvalidMultiplicity(symbol2){if(!symbol2.multiplicityRange||!symbol2.multiplicity)return[];let{lower,upper}=symbol2.multiplicityRange;return typeof upper=="number"&&lower>upper?[{severity:import_node.DiagnosticSeverity.Error,range:symbol2.selectionRange,message:`Invalid multiplicity [${symbol2.multiplicity}]: lower bound (${lower}) exceeds upper bound (${upper})`,source:"sysml",code:"invalid-multiplicity"}]:lower<0?[{severity:import_node.DiagnosticSeverity.Error,range:symbol2.selectionRange,message:`Invalid multiplicity [${symbol2.multiplicity}]: lower bound cannot be negative`,source:"sysml",code:"invalid-multiplicity"}]:[]}checkEmptyEnum(symbol2,allSymbols){return symbol2.kind!=="enum def"?[]:allSymbols.filter(s=>s.parentQualifiedName===symbol2.qualifiedName).some(c=>c.kind==="enum"||c.kind==="attribute")?[]:[{severity:import_node.DiagnosticSeverity.Information,range:symbol2.selectionRange,message:`Enumeration '${symbol2.name}' has no enum values defined`,source:"sysml",code:"empty-enum"}]}checkNamingConvention(symbol2){if(!symbol2.name)return[];if(symbol2.kind==="package"||symbol2.kind==="import"||symbol2.kind==="comment"||symbol2.kind==="doc"||symbol2.kind==="alias"||symbol2.kind==="unknown")return[];if(isDefinition(symbol2.kind)){let ch=symbol2.name[0];if(ch===ch.toLowerCase()&&ch!==ch.toUpperCase())return[{severity:import_node.DiagnosticSeverity.Hint,range:symbol2.selectionRange,message:`Definition '${symbol2.name}' should use PascalCase`,source:"sysml",code:"naming-convention",data:{name:symbol2.name,convention:"PascalCase"}}]}else{let ch=symbol2.name[0];if(ch===ch.toUpperCase()&&ch!==ch.toLowerCase())return[{severity:import_node.DiagnosticSeverity.Hint,range:symbol2.selectionRange,message:`Usage '${symbol2.name}' should use camelCase`,source:"sysml",code:"naming-convention",data:{name:symbol2.name,convention:"camelCase"}}]}return[]}checkMissingDocumentation(symbol2){return isDefinition(symbol2.kind)?symbol2.documentation?[]:[{severity:import_node.DiagnosticSeverity.Information,range:symbol2.selectionRange,message:`Definition '${symbol2.name}' has no documentation`,source:"sysml",code:"missing-doc",data:{name:symbol2.name}}]:[]}checkUnusedDefinitions(symbols,targetUri){let defs=symbols.filter(s=>s.kind==="part def"||s.kind==="action def"),defsInScope=targetUri?defs.filter(def=>def.uri===targetUri):defs,referencedTypes=new Set(symbols.filter(s=>s.kind!=="package").flatMap(s=>s.typeNames));for(let s of symbols)if(s.exposeTargets)for(let target of s.exposeTargets){let simpleName=target.replace(/::\*{1,2}$/,"").split("::").pop();simpleName&&referencedTypes.add(simpleName)}let diagnostics=[];for(let def of defsInScope){let isReferenced=referencedTypes.has(def.name),hasBaseType=(def.typeNames?.length??0)>0;!isReferenced&&!hasBaseType&&diagnostics.push({severity:import_node.DiagnosticSeverity.Warning,range:def.selectionRange,message:`Definition '${def.name}' is not referenced by any usage in the workspace`,source:"sysml",code:"unused-definition",data:{name:def.name}})}return diagnostics}static validateSymbols(symbolsInUri,allNames,opts){let diagnostics=[],instance=Object.create(_SemanticValidator.prototype),allSymbols=opts?.allSymbols??symbolsInUri,includeStyleRules=opts?.includeStyleRules??!0,indexes=instance.buildSymbolIndexes(allSymbols);for(let symbol2 of symbolsInUri)diagnostics.push(...instance.checkUnresolvedType(symbol2,allNames,new Set),...instance.checkInvalidMultiplicity(symbol2),...instance.checkEmptyEnum(symbol2,symbolsInUri)),includeStyleRules&&diagnostics.push(...instance.checkNamingConvention(symbol2),...instance.checkMissingDocumentation(symbol2));return diagnostics.push(...instance.checkDuplicateDefinitions(symbolsInUri)),diagnostics.push(...instance.checkUnusedDefinitions(allSymbols)),diagnostics.push(...instance.checkRedefinitionMultiplicity(symbolsInUri,indexes,opts?.text)),diagnostics.push(...instance.checkCircularSpecialization(symbolsInUri,indexes)),diagnostics.push(...instance.checkUnsatisfiedRequirements(allSymbols,indexes,opts?.text?[opts.text]:[])),diagnostics.push(...instance.checkUnverifiedRequirements(allSymbols,indexes,opts?.text?[opts.text]:[])),opts?.text&&opts.uri&&(diagnostics.push(...instance.checkPortCompatibility(opts.text,opts.uri,indexes)),diagnostics.push(...instance.checkConstraintBodyReferences(opts.text,opts.uri,symbolsInUri,indexes))),instance.dedupeDiagnostics(diagnostics)}checkCircularSpecialization(symbolsInUri,indexes){let diagnostics=[],defsInFile=symbolsInUri.filter(s=>isDefinition(s.kind)&&s.typeNames.length>0);for(let def of defsInFile){let visited=new Set;visited.add(def.name);let cycle=this.followSpecializationChain(def.name,def.typeNames,visited,indexes);cycle&&diagnostics.push({severity:import_node.DiagnosticSeverity.Error,range:def.selectionRange,message:`Circular specialization: ${cycle.join(" :> ")} :> ${cycle[0]}`,source:"sysml",code:"circular-specialization"})}return diagnostics}followSpecializationChain(originName,typeNames,visited,indexes){for(let tn of typeNames){if(visited.has(tn))return[...visited];let candidates=indexes.definitionsByName.get(tn);if(!candidates||candidates.length===0)continue;let target=candidates[0];if(target.typeNames.length===0)continue;visited.add(tn);let cycle=this.followSpecializationChain(originName,target.typeNames,visited,indexes);if(cycle)return cycle;visited.delete(tn)}}checkUnsatisfiedRequirements(allSymbols,indexes,workspaceTexts){let diagnostics=[],satisfiedNames,satisfyBlockRanges;if(workspaceTexts){satisfiedNames=new Set,satisfyBlockRanges=new Map;for(let text of workspaceTexts)this.extractSatisfyReferences(text,satisfiedNames),satisfyBlockRanges.set("__static__",this.extractSatisfyBlockRanges(text))}else if(this.documentManager){let uris=this.documentManager.getUris(),versionKey=uris.map(u=>u+":"+this.documentManager.getVersion(u)).join("|");if(this.satisfyCache&&this.satisfyCache.versionKey===versionKey)satisfiedNames=this.satisfyCache.satisfiedNames,satisfyBlockRanges=this.satisfyCache.satisfyBlockRanges;else{let relNames=this.collectWorkspaceRequirementRelationshipNames();satisfiedNames=relNames.satisfiedNames,satisfyBlockRanges=new Map;for(let uri of uris){let text=this.documentManager.getText(uri);text&&satisfyBlockRanges.set(uri,this.extractSatisfyBlockRanges(text))}this.satisfyCache={versionKey,satisfiedNames,satisfyBlockRanges},(!this.verifyCache||this.verifyCache.versionKey!==versionKey)&&(this.verifyCache={versionKey,verifiedNames:relNames.verifiedNames})}}else satisfiedNames=new Set,satisfyBlockRanges=new Map;let requirementUsages=allSymbols.filter(s=>s.kind==="requirement");for(let req of requirementUsages){if(req.parentQualifiedName&&indexes.byQualifiedName.get(req.parentQualifiedName)?.kind==="requirement")continue;let uriRanges=satisfyBlockRanges.get(req.uri)??satisfyBlockRanges.get("__static__")??[],reqLine=req.selectionRange.start.line;if(uriRanges.some(r=>reqLine>=r.startLine&&reqLine<=r.endLine))continue;satisfiedNames.has(req.name)||satisfiedNames.has(req.qualifiedName)||diagnostics.push({severity:import_node.DiagnosticSeverity.Warning,range:req.selectionRange,message:`Requirement '${req.name}' is not satisfied by any element`,source:"sysml",code:"unsatisfied-requirement",data:{name:req.name,qualifiedName:req.qualifiedName}})}return diagnostics}extractSatisfyReferences(text,out){let stripped=stripComments(text),re=/\bsatisfy\s+(?:requirement\s+)?([\w]+(?:::[\w]+)*)\s+(?:by\b|;|:)/g,m2;for(;(m2=re.exec(stripped))!==null;){let ref=m2[1];out.add(ref);let lastSeg=ref.includes("::")?ref.split("::").pop():ref;out.add(lastSeg)}}extractSatisfyBlockRanges(text){let ranges=[],stripped=stripComments(text),re=/\bsatisfy\b[^;{]*\{/g,m2,lineOffsets;for(;(m2=re.exec(stripped))!==null;){let open=m2.index+m2[0].length-1,depth=1,i=open+1;for(;i<stripped.length&&depth>0;)stripped[i]==="{"&&depth++,stripped[i]==="}"&&depth--,i++;if(depth===0){if(!lineOffsets){lineOffsets=[0];for(let j=0;j<text.length;j++)text[j]===`
139
139
  `&&lineOffsets.push(j+1)}ranges.push({startLine:this.offsetToLine(lineOffsets,open),endLine:this.offsetToLine(lineOffsets,i-1)})}}return ranges}checkUnverifiedRequirements(allSymbols,indexes,workspaceTexts){let diagnostics=[],satisfiedNames,verifiedNames,satisfyBlockRanges;if(workspaceTexts){satisfiedNames=new Set,verifiedNames=new Set,satisfyBlockRanges=new Map;for(let text of workspaceTexts)this.extractSatisfyReferences(text,satisfiedNames),this.extractVerifyReferences(text,verifiedNames),satisfyBlockRanges.set("__static__",this.extractSatisfyBlockRanges(text))}else if(this.documentManager){let uris=this.documentManager.getUris(),versionKey=uris.map(u=>u+":"+this.documentManager.getVersion(u)).join("|"),satisfyCacheValid=this.satisfyCache&&this.satisfyCache.versionKey===versionKey,verifyCacheValid=this.verifyCache&&this.verifyCache.versionKey===versionKey;if(!satisfyCacheValid||!verifyCacheValid){let relNames=this.collectWorkspaceRequirementRelationshipNames();if(!satisfyCacheValid){satisfyBlockRanges=new Map;for(let uri of uris){let text=this.documentManager.getText(uri);text&&satisfyBlockRanges.set(uri,this.extractSatisfyBlockRanges(text))}this.satisfyCache={versionKey,satisfiedNames:relNames.satisfiedNames,satisfyBlockRanges}}verifyCacheValid||(this.verifyCache={versionKey,verifiedNames:relNames.verifiedNames})}satisfiedNames=this.satisfyCache.satisfiedNames,satisfyBlockRanges=this.satisfyCache.satisfyBlockRanges,verifiedNames=this.verifyCache.verifiedNames}else satisfiedNames=new Set,verifiedNames=new Set,satisfyBlockRanges=new Map;let requirementUsages=allSymbols.filter(s=>s.kind==="requirement");for(let req of requirementUsages){if(req.parentQualifiedName&&indexes.byQualifiedName.get(req.parentQualifiedName)?.kind==="requirement")continue;let uriRanges=satisfyBlockRanges.get(req.uri)??satisfyBlockRanges.get("__static__")??[],reqLine=req.selectionRange.start.line;if(uriRanges.some(r=>reqLine>=r.startLine&&reqLine<=r.endLine))continue;let isSatisfied=satisfiedNames.has(req.name)||satisfiedNames.has(req.qualifiedName);if(!(verifiedNames.has(req.name)||verifiedNames.has(req.qualifiedName))){let message=isSatisfied?`Requirement '${req.name}' is satisfied but has no verification case \u2014 consider adding: verify ${req.name} by <VerificationCase>;`:`Requirement '${req.name}' has no verification case \u2014 consider adding: verify ${req.name} by <VerificationCase>;`;diagnostics.push({severity:import_node.DiagnosticSeverity.Warning,range:req.selectionRange,message,source:"sysml",code:"unverified-requirement",data:{name:req.name,qualifiedName:req.qualifiedName}})}}return diagnostics}extractVerifyReferences(text,out){let stripped=stripComments(text),re=/\bverify\s+(?:requirement\s+)?([\w]+(?:::[\w]+)*)\s*(?:by\b|;|:|\{)/g,m2;for(;(m2=re.exec(stripped))!==null;){let ref=m2[1];out.add(ref);let lastSeg=ref.includes("::")?ref.split("::").pop():ref;out.add(lastSeg)}}offsetToLine(lineOffsets,offset){let lo=0,hi=lineOffsets.length-1;for(;lo<hi;){let mid=lo+hi+1>>>1;lineOffsets[mid]<=offset?lo=mid:hi=mid-1}return lo}checkViewpointSatisfaction(symbols,_indexes){let diagnostics=[],views=symbols.filter(s=>s.kind==="view"),_viewpointNames=new Set(symbols.filter(s=>s.kind==="viewpoint def"||s.kind==="viewpoint").map(s=>s.name));for(let view of views){let hasExpose=view.exposeTargets&&view.exposeTargets.length>0,hasFilter=view.viewFilters&&view.viewFilters.length>0;!hasExpose&&!hasFilter&&diagnostics.push({severity:import_node.DiagnosticSeverity.Information,range:view.selectionRange,message:`View '${view.name}' has no expose or filter directives \u2014 it will show all elements`,source:"sysml",code:"view-no-scope"})}return diagnostics}checkRedefinitionMultiplicity(symbolsInUri,indexes,text){let diagnostics=[],lines=text?.split(`
140
140
  `);for(let s of symbolsInUri){if(!s.typeName||!s.multiplicityRange)continue;let c0=s.typeName.charCodeAt(0);if(!(c0>=97&&c0<=122))continue;if(lines){let lineIdx=s.selectionRange.start.line,line=lines[lineIdx]||"";if(!/:>>/.test(line)&&!/\bredefines\b/.test(line))continue}let base=(indexes.byName.get(s.typeName)??[]).find(c=>!!c.multiplicityRange);if(!base?.multiplicityRange)continue;let baseLower=base.multiplicityRange.lower,baseUpper=base.multiplicityRange.upper,curLower=s.multiplicityRange.lower,curUpper=s.multiplicityRange.upper,lowerOk=curLower>=baseLower,upperOk=baseUpper==="*"||curUpper!=="*"&&curUpper<=baseUpper;lowerOk&&upperOk||diagnostics.push({severity:import_node.DiagnosticSeverity.Error,range:s.selectionRange,message:`Redefinition multiplicity [${s.multiplicity??"?"}] is incompatible with base '${base.name}' multiplicity [${base.multiplicity??"?"}]`,source:"sysml",code:"invalid-redefinition-multiplicity"})}return diagnostics}checkPortCompatibility(text,uri,indexes){if(!text)return[];let diagnostics=[],lines=text.split(`
141
141
  `),re=/\bconnect\s+([A-Za-z_][\w.]*)\s+to\s+([A-Za-z_][\w.]*)/g,m2;for(;(m2=re.exec(text))!==null;){let left=m2[1].split(".").pop(),right=m2[2].split(".").pop(),lSym=(indexes.portsByName.get(left)??[])[0],rSym=(indexes.portsByName.get(right)??[])[0];if(!lSym||!rSym)continue;let lType=lSym.typeNames[0]??lSym.typeName,rType=rSym.typeNames[0]??rSym.typeName;if(!lType||!rType||lType===rType||lType==="~"+rType||rType==="~"+lType||lType.startsWith("~")&&lType.slice(1)===rType||rType.startsWith("~")&&rType.slice(1)===lType)continue;let matchLine=text.substring(0,m2.index).split(`
@@ -141,7 +141,7 @@ Package: \`${info.packageName}\``),info.documentation&&lines.push(`
141
141
  ${info.documentation}`),{contents:{kind:import_node8.MarkupKind.Markdown,value:lines.join(`
142
142
  `)}}}getWordAtPosition(text,line,character){let lines=text.split(`
143
143
  `);if(line>=lines.length)return;let lineText=lines[line];if(!(character>=lineText.length))return extractQualifiedNameAt(lineText,character)}rangeContainsPosition(range,position){let afterStart=position.line>range.start.line||position.line===range.start.line&&position.character>=range.start.character,beforeEnd=position.line<range.end.line||position.line===range.end.line&&position.character<=range.end.character;return afterStart&&beforeEnd}getRepairHint(code){switch(code){case"invalid-redefinition-multiplicity":return"Align the redefined feature multiplicity with its base feature bounds.";case"incompatible-port-types":return"Connect endpoints with matching port types, or update one endpoint type.";case"unresolved-constraint-reference":return"Fix the reference path or add the missing feature in the referenced type.";case"unresolved-type":return"Define/import the missing type or correct the type name.";case"invalid-multiplicity":return"Use a valid bound where lower <= upper and lower is non-negative.";default:return}}};var import_node9=__toESM(require_node3());var DEFINITION_KEYWORDS=new Set(["about","abstract","accept","action","actor","after","alias","all","allocate","allocation","analysis","assert","assign","assume","attribute","bind","binding","calc","case","comment","concern","connect","connection","constraint","decide","def","default","defined","dependency","derived","do","doc","else","end","entry","enum","event","exhibit","exit","expose","feature","filter","first","flow","for","fork","frame","from","if","import","in","include","individual","inout","interface","item","join","language","library","locale","merge","message","meta","metadata","multiplicity","namespace","nonunique","not","null","objective","occurrence","of","ordered","out","package","parallel","part","perform","port","private","protected","public","readonly","redefines","ref","references","render","rendering","rep","require","requirement","return","satisfy","send","snapshot","specializes","stakeholder","state","subject","subsets","succession","then","timeslice","to","transition","type","use","variant","variation","verification","verify","view","viewpoint","when","while","datatype"]);function levenshtein2(a,b){if(a.length<b.length){let t=a;a=b,b=t}let m2=a.length,n2=b.length,prev=new Uint16Array(n2+1),curr=new Uint16Array(n2+1);for(let j=0;j<=n2;j++)prev[j]=j;for(let i=1;i<=m2;i++){curr[0]=i;for(let j=1;j<=n2;j++){let cost=a.charCodeAt(i-1)===b.charCodeAt(j-1)?0:1;curr[j]=Math.min(prev[j]+1,curr[j-1]+1,prev[j-1]+cost)}[prev,curr]=[curr,prev]}return prev[n2]}function findClosestKeyword(identifier,maxDistance=2){let lower=identifier.toLowerCase();if(lower.length<4||DEFINITION_KEYWORDS.has(lower))return;let effectiveMax=lower.length<=5?1:maxDistance,bestMatch,bestDist=effectiveMax+1;for(let keyword of DEFINITION_KEYWORDS){if(Math.abs(keyword.length-lower.length)>maxDistance)continue;let dist=levenshtein2(lower,keyword);dist>0&&dist<bestDist&&(bestDist=dist,bestMatch=keyword)}return bestMatch}var KEYWORD_CONTINUATIONS=new Set([SysMLv2Lexer.IDENTIFIER,SysMLv2Lexer.COLON,SysMLv2Lexer.DEF,SysMLv2Lexer.LBRACE,SysMLv2Lexer.LBRACK,SysMLv2Lexer.ABOUT]),NAME_PRECEDING_KEYWORDS=new Set([SysMLv2Lexer.PART,SysMLv2Lexer.PORT,SysMLv2Lexer.ITEM,SysMLv2Lexer.ATTRIBUTE,SysMLv2Lexer.ACTION,SysMLv2Lexer.CALC,SysMLv2Lexer.STATE,SysMLv2Lexer.CONSTRAINT,SysMLv2Lexer.REQUIREMENT,SysMLv2Lexer.CONCERN,SysMLv2Lexer.CASE,SysMLv2Lexer.ANALYSIS,SysMLv2Lexer.VERIFICATION,SysMLv2Lexer.VIEW,SysMLv2Lexer.VIEWPOINT,SysMLv2Lexer.RENDERING,SysMLv2Lexer.METADATA,SysMLv2Lexer.PACKAGE,SysMLv2Lexer.NAMESPACE,SysMLv2Lexer.ENUM,SysMLv2Lexer.ALLOCATION,SysMLv2Lexer.CONNECTION,SysMLv2Lexer.INTERFACE,SysMLv2Lexer.OCCURRENCE,SysMLv2Lexer.INDIVIDUAL,SysMLv2Lexer.FLOW,SysMLv2Lexer.SUCCESSION,SysMLv2Lexer.BINDING,SysMLv2Lexer.MESSAGE,SysMLv2Lexer.TRANSITION,SysMLv2Lexer.TYPE,SysMLv2Lexer.CLASSIFIER,SysMLv2Lexer.DATATYPE,SysMLv2Lexer.CLASS,SysMLv2Lexer.STRUCT,SysMLv2Lexer.ASSOC,SysMLv2Lexer.METACLASS,SysMLv2Lexer.INTERACTION,SysMLv2Lexer.BEHAVIOR,SysMLv2Lexer.FUNCTION,SysMLv2Lexer.PREDICATE,SysMLv2Lexer.FEATURE,SysMLv2Lexer.CONNECTOR,SysMLv2Lexer.STEP,SysMLv2Lexer.EXPR,SysMLv2Lexer.BOOL,SysMLv2Lexer.INV,SysMLv2Lexer.MULTIPLICITY,SysMLv2Lexer.ALIAS,SysMLv2Lexer.COMMENT,SysMLv2Lexer.DOC,SysMLv2Lexer.REP,SysMLv2Lexer.DEPENDENCY,SysMLv2Lexer.IMPORT,SysMLv2Lexer.DEF,SysMLv2Lexer.REF,SysMLv2Lexer.ALL,SysMLv2Lexer.ABSTRACT,SysMLv2Lexer.VARIATION,SysMLv2Lexer.DERIVED,SysMLv2Lexer.COMPOSITE,SysMLv2Lexer.CONST,SysMLv2Lexer.CONSTANT,SysMLv2Lexer.VAR,SysMLv2Lexer.MEMBER,SysMLv2Lexer.RETURN,SysMLv2Lexer.PUBLIC,SysMLv2Lexer.PRIVATE,SysMLv2Lexer.PROTECTED,SysMLv2Lexer.IN,SysMLv2Lexer.OUT,SysMLv2Lexer.INOUT,SysMLv2Lexer.END,SysMLv2Lexer.ACTOR,SysMLv2Lexer.STAKEHOLDER,SysMLv2Lexer.SUBJECT,SysMLv2Lexer.VARIANT,SysMLv2Lexer.SNAPSHOT,SysMLv2Lexer.TIMESLICE,SysMLv2Lexer.FORK,SysMLv2Lexer.JOIN,SysMLv2Lexer.MERGE,SysMLv2Lexer.DECIDE,SysMLv2Lexer.PERFORM,SysMLv2Lexer.EXHIBIT,SysMLv2Lexer.INCLUDE,SysMLv2Lexer.SATISFY,SysMLv2Lexer.ASSERT,SysMLv2Lexer.VERIFY,SysMLv2Lexer.RENDER,SysMLv2Lexer.CONNECT,SysMLv2Lexer.ALLOCATE,SysMLv2Lexer.BIND,SysMLv2Lexer.EXPOSE,SysMLv2Lexer.EVENT,SysMLv2Lexer.FIRST,SysMLv2Lexer.THEN,SysMLv2Lexer.TO,SysMLv2Lexer.FROM,SysMLv2Lexer.REDEFINES,SysMLv2Lexer.SUBSETS,SysMLv2Lexer.SPECIALIZES,SysMLv2Lexer.REFERENCES,SysMLv2Lexer.CONJUGATES,SysMLv2Lexer.CHAINS,SysMLv2Lexer.CROSSES,SysMLv2Lexer.UNIONS,SysMLv2Lexer.INTERSECTS,SysMLv2Lexer.DIFFERENCES,SysMLv2Lexer.SPECIALIZATION,SysMLv2Lexer.CONJUGATION,SysMLv2Lexer.DISJOINING,SysMLv2Lexer.INVERTING,SysMLv2Lexer.FEATURING,SysMLv2Lexer.TYPING,SysMLv2Lexer.REDEFINITION,SysMLv2Lexer.SUBTYPE,SysMLv2Lexer.SUBCLASSIFIER,SysMLv2Lexer.SUBSET,SysMLv2Lexer.CONJUGATE,SysMLv2Lexer.DISJOINT,SysMLv2Lexer.INVERSE,SysMLv2Lexer.ASSUME,SysMLv2Lexer.REQUIRE,SysMLv2Lexer.FRAME,SysMLv2Lexer.OBJECTIVE,SysMLv2Lexer.ENTRY,SysMLv2Lexer.DO,SysMLv2Lexer.EXIT,SysMLv2Lexer.ACCEPT,SysMLv2Lexer.SEND,SysMLv2Lexer.ASSIGN,SysMLv2Lexer.TERMINATE,SysMLv2Lexer.FOR,SysMLv2Lexer.ABOUT,SysMLv2Lexer.BY,SysMLv2Lexer.FILTER,SysMLv2Lexer.NEW,SysMLv2Lexer.META,SysMLv2Lexer.OF,SysMLv2Lexer.COLON,SysMLv2Lexer.COLON_GT,SysMLv2Lexer.COLON_GT_GT,SysMLv2Lexer.COLON_COLON,SysMLv2Lexer.COLON_COLON_GT,SysMLv2Lexer.GT,SysMLv2Lexer.FAT_ARROW,SysMLv2Lexer.TILDE,SysMLv2Lexer.COMMA,SysMLv2Lexer.HASH,SysMLv2Lexer.AT]);function looksLikeKeywordPosition(visibleTokens,index2){if(index2>0){let prev=visibleTokens[index2-1];if(NAME_PRECEDING_KEYWORDS.has(prev.type)||prev.type===SysMLv2Lexer.DOT||prev.type===SysMLv2Lexer.EQ||prev.type===SysMLv2Lexer.COLON_EQ||prev.text==="->")return!1}if(index2+1<visibleTokens.length){let next=visibleTokens[index2+1];if(KEYWORD_CONTINUATIONS.has(next.type))return!0}return index2===0}function validateKeywords(result){let diagnostics=[];result.tokenStream.fill();let allTokens=result.tokenStream.getTokens(),visibleTokens=[];for(let j=0;j<allTokens.length;j++){let t=allTokens[j];t.channel===0&&t.type!==Token.EOF&&visibleTokens.push(t)}for(let i=0;i<visibleTokens.length;i++){let token=visibleTokens[i];if(token.type!==SysMLv2Lexer.IDENTIFIER)continue;let text=token.text;if(!text||!looksLikeKeywordPosition(visibleTokens,i))continue;let suggestion=findClosestKeyword(text);if(!suggestion)continue;let line=(token.line??1)-1,char=token.column??0,message=`Unknown keyword '${text}'. Did you mean '${suggestion}'?`;diagnostics.push({severity:import_node9.DiagnosticSeverity.Error,range:{start:{line,character:char},end:{line,character:char+text.length}},message,source:"sysml",data:{typo:text,suggestion}})}return diagnostics}var ReferencesProvider=class{constructor(documentManager2){this.documentManager=documentManager2}documentManager;provideReferences(params){if(!this.documentManager.get(params.textDocument.uri))return[];let symbolTable=this.documentManager.getWorkspaceSymbolTable(),symbol=symbolTable.findSymbolAtPosition(params.textDocument.uri,params.position.line,params.position.character);if(!symbol)return[];let references=symbolTable.findReferences(symbol.name),locations=[];for(let ref of references)locations.push({uri:ref.uri,range:ref.selectionRange});return params.context.includeDeclaration,locations}};function findWordOccurrences(line,word){let positions=[],from=0;for(;from<=line.length-word.length;){let idx=line.indexOf(word,from);if(idx<0)break;(idx===0||!isIdentPart(line.charCodeAt(idx-1)))&&(idx+word.length>=line.length||!isIdentPart(line.charCodeAt(idx+word.length)))&&positions.push(idx),from=idx+1}return positions}var RenameProvider=class{constructor(documentManager2){this.documentManager=documentManager2}documentManager;prepareRename(params){let symbolTable=this.documentManager.getSymbolTable(params.textDocument.uri);if(!symbolTable)return null;let symbol=symbolTable.findSymbolAtPosition(params.textDocument.uri,params.position.line,params.position.character);return symbol?symbol.selectionRange:null}provideRename(params){let symbolTable=this.documentManager.getSymbolTable(params.textDocument.uri);if(!symbolTable)return null;let symbol=symbolTable.findSymbolAtPosition(params.textDocument.uri,params.position.line,params.position.character);if(!symbol)return null;let text=this.documentManager.getText(params.textDocument.uri);if(!text)return null;let edits=[],oldName=symbol.name,newName=params.newName,references=symbolTable.findReferences(oldName);for(let ref of references)ref.uri===params.textDocument.uri&&edits.push({range:ref.selectionRange,newText:newName});let lines=text.split(`
144
- `);for(let i=0;i<lines.length;i++)for(let col of findWordOccurrences(lines[i],oldName)){let range={start:{line:i,character:col},end:{line:i,character:col+oldName.length}};edits.some(e=>e.range.start.line===i&&e.range.start.character===col)||edits.push({range,newText:newName})}return edits.length===0?null:{changes:{[params.textDocument.uri]:edits}}}};var import_node10=__toESM(require_node3());var OPERATOR_TOKENS=new Set([SysMLv2Lexer.BANG_EQ_EQ,SysMLv2Lexer.STAR_STAR,SysMLv2Lexer.COLON_GT,SysMLv2Lexer.COLON_GT_GT,SysMLv2Lexer.AMP,SysMLv2Lexer.COLON_COLON,SysMLv2Lexer.STAR,SysMLv2Lexer.PIPE,SysMLv2Lexer.EQ_EQ,SysMLv2Lexer.BANG_EQ,SysMLv2Lexer.PLUS,SysMLv2Lexer.MINUS,SysMLv2Lexer.ARROW,SysMLv2Lexer.SLASH,SysMLv2Lexer.LT,SysMLv2Lexer.EQ,SysMLv2Lexer.GT,SysMLv2Lexer.CARET,SysMLv2Lexer.TILDE]),PUNCTUATION_TOKENS=new Set([SysMLv2Lexer.LBRACE,SysMLv2Lexer.RBRACE,SysMLv2Lexer.LPAREN,SysMLv2Lexer.RPAREN,SysMLv2Lexer.SEMI,SysMLv2Lexer.COMMA,SysMLv2Lexer.DOT,SysMLv2Lexer.LBRACK,SysMLv2Lexer.RBRACK,SysMLv2Lexer.COLON]),STRUCTURAL_KEYWORDS=new Set(["part","port","item","state","constraint","requirement","concern","case","view","viewpoint","rendering","allocation","connection","interface","occurrence","individual","flow","binding","succession","metadata","enum","actor","subject","ref","use"]),tokenTypes=["namespace","type","class","variable","property","function","keyword","comment","string","number","operator","enum","interface"],tokenModifiers=["declaration","definition","readonly","abstract"],SemanticTokensProvider=class{constructor(documentManager2){this.documentManager=documentManager2}documentManager;tokenCache;provideSemanticTokens(params){let uri=params.textDocument.uri,version=this.documentManager.getVersion(uri);if(this.tokenCache&&this.tokenCache.uri===uri&&this.tokenCache.version===version)return this.tokenCache.tokens;let builder=new import_node10.SemanticTokensBuilder,result=this.documentManager.get(uri);if(!result)return builder.build();result.tokenStream.fill();let tokens=result.tokenStream.getTokens(),prevMeaningful;for(let token of tokens){if(!token.text||token.channel!==0)continue;let text=token.text,tokenType=this.classifyTokenInContext(text,prevMeaningful,token.type);if(prevMeaningful=text,tokenType===void 0)continue;let line=(token.line??1)-1,char=token.column??0,length=text.length;builder.push(line,char,length,tokenType,0)}let built=builder.build();return this.tokenCache={uri,version,tokens:built},built}classifyTokenInContext(text,prev,lexerType){if(lexerType===SysMLv2Lexer.REGULAR_COMMENT||lexerType===SysMLv2Lexer.SINGLE_LINE_NOTE)return 7;if(lexerType===SysMLv2Lexer.STRING||lexerType===SysMLv2Lexer.DOUBLE_STRING)return 8;if(lexerType===SysMLv2Lexer.INTEGER||lexerType===SysMLv2Lexer.REAL)return 9;if(OPERATOR_TOKENS.has(lexerType))return 10;if(!PUNCTUATION_TOKENS.has(lexerType)){if(this.isKeyword(text))return 6;if(lexerType===SysMLv2Lexer.IDENTIFIER)return this.classifyIdentifier(prev)}}classifyIdentifier(prev){return prev?prev==="def"?2:prev==="package"||prev==="namespace"||prev==="library"?0:prev==="action"||prev==="calc"||prev==="analysis"||prev==="verification"?5:prev===":"||prev===":>"||prev===":>>"?1:prev==="attribute"?4:(this.isStructuralKeyword(prev),3):3}isStructuralKeyword(text){return STRUCTURAL_KEYWORDS.has(text)}isKeyword(text){return SYSML_KEYWORDS.has(text)}};var import_node11=__toESM(require_node3());var STANDARD_LIBRARY_TYPES=new Set(["Boolean","String","Integer","Real","Natural","Positive","Complex","Number","Rational","ScalarValues","DataFunctions","Anything","Nothing","Object","Occurrence","Base","Objects","Occurrences","Items","Parts","Ports","Actions","States","Connections","Interfaces","Allocations","Requirements","Constraints","Calculations","Cases","Flows","Transfers","Performances","TransitionPerformances","ISQ","SI","USCustomaryUnits","Quantities","MeasurementReferences","ScalarValues","GeneralView","InterconnectionView","ActionFlowView","StateTransitionView","SequenceView","GeometryView","GridView","BrowserView","StandardViewDefinitions","View","ViewpointCheck","Rendering","TextualRendering","GraphicalRendering","TabularRendering","Views","LengthValue","MassValue","DurationValue","TimeValue","ElectricCurrentValue","ThermodynamicTemperatureValue","TemperatureValue","AmountOfSubstanceValue","LuminousIntensityValue","AreaValue","VolumeValue","SpeedValue","VelocityValue","AccelerationValue","ForceValue","EnergyValue","PowerValue","PressureValue","TorqueValue","MomentOfForceValue","AngularVelocityValue","FrequencyValue","DensityValue","MassFlowRateValue","VolumeFlowRateValue","LengthUnit","MassUnit","DurationUnit","TimeUnit"]),CONSTRAINT_KEYWORDS=new Set(["and","or","not","xor","implies","if","then","else","true","false","null","require","constraint","subject","return","doc","comment","assert","assume"]);function isISQValueType(name){if(!name.endsWith("Value")||name.length<6)return!1;let ch0=name.charCodeAt(0);if(ch0<65||ch0>90)return!1;for(let i=1;i<name.length;i++){let c=name.charCodeAt(i);if(!(c>=65&&c<=90||c>=97&&c<=122))return!1}return!0}var SemanticValidator=class _SemanticValidator{constructor(documentManager2){this.documentManager=documentManager2;this.modelProvider=new SysMLModelProvider(documentManager2)}documentManager;modelProvider;satisfyCache;verifyCache;indexCache;symbolNamesCache;libraryNamesCache;addRequirementNameVariants(out,ref){if(!ref)return;let trimmed=ref.trim();if(!trimmed)return;out.add(trimmed);let lastSeg=trimmed.includes("::")?trimmed.split("::").pop():trimmed;out.add(lastSeg)}collectWorkspaceRequirementRelationshipNames(){let satisfiedNames=new Set,verifiedNames=new Set,uris=this.documentManager.getUris();for(let uri of uris){let version=this.documentManager.getVersion(uri);if(version<0)continue;let rels=this.modelProvider.getModel(uri,version,["relationships"]).relationships??[];for(let rel of rels)rel.type==="satisfy"?this.addRequirementNameVariants(satisfiedNames,rel.target):rel.type==="verify"&&this.addRequirementNameVariants(verifiedNames,rel.target)}return{satisfiedNames,verifiedNames}}validate(uri){let symbolTable=this.documentManager.getWorkspaceSymbolTable(),symbols=symbolTable.getSymbolsForUri(uri);if(symbols.length===0)return[];let allSymbols=symbolTable.getAllSymbols(),allSymbolNames;this.symbolNamesCache&&this.symbolNamesCache.symbols===allSymbols?allSymbolNames=this.symbolNamesCache.names:(allSymbolNames=new Set(allSymbols.map(s=>s.name)),this.symbolNamesCache={symbols:allSymbols,names:allSymbolNames}),this.libraryNamesCache||(this.libraryNamesCache=new Set(getLibraryPackageNames()));let libraryNames=this.libraryNamesCache,text=this.documentManager.getText(uri)??"",indexes=this.getOrBuildIndexes(allSymbols),diagnostics=[];for(let symbol of symbols)diagnostics.push(...this.checkUnresolvedType(symbol,allSymbolNames,libraryNames),...this.checkInvalidMultiplicity(symbol),...this.checkEmptyEnum(symbol,symbols),...this.checkNamingConvention(symbol),...this.checkMissingDocumentation(symbol));return diagnostics.push(...this.checkDuplicateDefinitions(symbols)),diagnostics.push(...this.checkUnusedDefinitions(allSymbols,uri)),diagnostics.push(...this.checkRedefinitionMultiplicity(symbols,indexes,text)),diagnostics.push(...this.checkPortCompatibility(text,uri,indexes)),diagnostics.push(...this.checkConstraintBodyReferences(text,uri,symbols,indexes)),diagnostics.push(...this.checkCircularSpecialization(symbols,indexes)),diagnostics.push(...this.checkCircularContainment(symbols,indexes)),diagnostics.push(...this.checkUnsatisfiedRequirements(symbols,indexes)),diagnostics.push(...this.checkUnverifiedRequirements(symbols,indexes)),diagnostics.push(...this.checkViewpointSatisfaction(symbols,indexes)),this.dedupeDiagnostics(diagnostics)}checkUnresolvedType(symbol,allSymbolNames,libraryNames){if(!symbol.typeName)return[];let typeName=symbol.typeName,kwMatch=typeName.match(/^([A-Z][A-Za-z_0-9]*?)(redefines|subsets|references|connect|bind|default|via|accept|send|flow|allocate|assign|decide|merge|join|fork)([A-Z])/);kwMatch&&(typeName=kwMatch[1]);let rootSegment=typeName.split("::")[0];if(allSymbolNames.has(typeName)||allSymbolNames.has(rootSegment)||STANDARD_LIBRARY_TYPES.has(typeName)||STANDARD_LIBRARY_TYPES.has(rootSegment)||libraryNames.has(rootSegment)||isISQValueType(typeName)||resolveLibraryType(typeName)!==void 0||resolveLibraryType(rootSegment)!==void 0||typeName.charCodeAt(0)>=97&&typeName.charCodeAt(0)<=122)return[];let isMandatory=symbol.multiplicityRange&&symbol.multiplicityRange.lower>=1,severity=isMandatory?import_node11.DiagnosticSeverity.Error:import_node11.DiagnosticSeverity.Warning,message=`Type '${typeName}' is not defined in the current document or standard library`;if(isMandatory){let multStr=symbol.multiplicity??"1";message+=` (feature '${symbol.name}' requires multiplicity [${multStr}])`}return[{severity,range:symbol.selectionRange,message,source:"sysml",code:"unresolved-type",data:{typeName}}]}checkInvalidMultiplicity(symbol){if(!symbol.multiplicityRange||!symbol.multiplicity)return[];let{lower,upper}=symbol.multiplicityRange;return typeof upper=="number"&&lower>upper?[{severity:import_node11.DiagnosticSeverity.Error,range:symbol.selectionRange,message:`Invalid multiplicity [${symbol.multiplicity}]: lower bound (${lower}) exceeds upper bound (${upper})`,source:"sysml",code:"invalid-multiplicity"}]:lower<0?[{severity:import_node11.DiagnosticSeverity.Error,range:symbol.selectionRange,message:`Invalid multiplicity [${symbol.multiplicity}]: lower bound cannot be negative`,source:"sysml",code:"invalid-multiplicity"}]:[]}checkEmptyEnum(symbol,allSymbols){return symbol.kind!=="enum def"?[]:allSymbols.filter(s=>s.parentQualifiedName===symbol.qualifiedName).some(c=>c.kind==="enum"||c.kind==="attribute")?[]:[{severity:import_node11.DiagnosticSeverity.Information,range:symbol.selectionRange,message:`Enumeration '${symbol.name}' has no enum values defined`,source:"sysml",code:"empty-enum"}]}checkNamingConvention(symbol){if(!symbol.name)return[];if(symbol.kind==="package"||symbol.kind==="import"||symbol.kind==="comment"||symbol.kind==="doc"||symbol.kind==="alias"||symbol.kind==="unknown")return[];if(isDefinition(symbol.kind)){let ch=symbol.name[0];if(ch===ch.toLowerCase()&&ch!==ch.toUpperCase())return[{severity:import_node11.DiagnosticSeverity.Hint,range:symbol.selectionRange,message:`Definition '${symbol.name}' should use PascalCase`,source:"sysml",code:"naming-convention",data:{name:symbol.name,convention:"PascalCase"}}]}else{let ch=symbol.name[0];if(ch===ch.toUpperCase()&&ch!==ch.toLowerCase())return[{severity:import_node11.DiagnosticSeverity.Hint,range:symbol.selectionRange,message:`Usage '${symbol.name}' should use camelCase`,source:"sysml",code:"naming-convention",data:{name:symbol.name,convention:"camelCase"}}]}return[]}checkMissingDocumentation(symbol){return isDefinition(symbol.kind)?symbol.documentation?[]:[{severity:import_node11.DiagnosticSeverity.Information,range:symbol.selectionRange,message:`Definition '${symbol.name}' has no documentation`,source:"sysml",code:"missing-doc",data:{name:symbol.name}}]:[]}checkUnusedDefinitions(symbols,targetUri){let defs=symbols.filter(s=>s.kind==="part def"||s.kind==="action def"),defsInScope=targetUri?defs.filter(def=>def.uri===targetUri):defs,referencedTypes=new Set(symbols.filter(s=>s.kind!=="package").flatMap(s=>s.typeNames));for(let s of symbols)if(s.exposeTargets)for(let target of s.exposeTargets){let simpleName=target.replace(/::\*{1,2}$/,"").split("::").pop();simpleName&&referencedTypes.add(simpleName)}let diagnostics=[];for(let def of defsInScope){let isReferenced=referencedTypes.has(def.name),hasBaseType=(def.typeNames?.length??0)>0;!isReferenced&&!hasBaseType&&diagnostics.push({severity:import_node11.DiagnosticSeverity.Warning,range:def.selectionRange,message:`Definition '${def.name}' is not referenced by any usage in the workspace`,source:"sysml",code:"unused-definition",data:{name:def.name}})}return diagnostics}static validateSymbols(symbolsInUri,allNames,opts){let diagnostics=[],instance=Object.create(_SemanticValidator.prototype),allSymbols=opts?.allSymbols??symbolsInUri,includeStyleRules=opts?.includeStyleRules??!0,indexes=instance.buildSymbolIndexes(allSymbols);for(let symbol of symbolsInUri)diagnostics.push(...instance.checkUnresolvedType(symbol,allNames,new Set),...instance.checkInvalidMultiplicity(symbol),...instance.checkEmptyEnum(symbol,symbolsInUri)),includeStyleRules&&diagnostics.push(...instance.checkNamingConvention(symbol),...instance.checkMissingDocumentation(symbol));return diagnostics.push(...instance.checkDuplicateDefinitions(symbolsInUri)),diagnostics.push(...instance.checkUnusedDefinitions(allSymbols)),diagnostics.push(...instance.checkRedefinitionMultiplicity(symbolsInUri,indexes,opts?.text)),diagnostics.push(...instance.checkCircularSpecialization(symbolsInUri,indexes)),diagnostics.push(...instance.checkCircularContainment(symbolsInUri,indexes)),diagnostics.push(...instance.checkUnsatisfiedRequirements(allSymbols,indexes,opts?.text?[opts.text]:[])),diagnostics.push(...instance.checkUnverifiedRequirements(allSymbols,indexes,opts?.text?[opts.text]:[])),opts?.text&&opts.uri&&(diagnostics.push(...instance.checkPortCompatibility(opts.text,opts.uri,indexes)),diagnostics.push(...instance.checkConstraintBodyReferences(opts.text,opts.uri,symbolsInUri,indexes))),instance.dedupeDiagnostics(diagnostics)}checkCircularSpecialization(symbolsInUri,indexes){let diagnostics=[],defsInFile=symbolsInUri.filter(s=>isDefinition(s.kind)&&s.typeNames.length>0);for(let def of defsInFile){let visited=new Set;visited.add(def.name);let cycle=this.followSpecializationChain(def.name,def.typeNames,visited,indexes);cycle&&diagnostics.push({severity:import_node11.DiagnosticSeverity.Error,range:def.selectionRange,message:`Circular specialization: ${cycle.join(" :> ")} :> ${cycle[0]}`,source:"sysml",code:"circular-specialization"})}return diagnostics}followSpecializationChain(originName,typeNames,visited,indexes){for(let tn of typeNames){if(visited.has(tn))return[...visited];let candidates=indexes.definitionsByName.get(tn);if(!candidates||candidates.length===0)continue;let target=candidates[0];if(target.typeNames.length===0)continue;visited.add(tn);let cycle=this.followSpecializationChain(originName,target.typeNames,visited,indexes);if(cycle)return cycle;visited.delete(tn)}}checkCircularContainment(symbolsInUri,indexes){let diagnostics=[],defsInFile=symbolsInUri.filter(s=>isDefinition(s.kind));for(let def of defsInFile){let children=indexes.byParent.get(def.qualifiedName)??[],childTypeNames=children.flatMap(c=>c.typeNames).filter(t=>t.length>0);if(childTypeNames.length!==0)for(let childTypeName of childTypeNames){if(childTypeName===def.name)continue;let visited=new Set;visited.add(def.name);let cycle=this.followContainmentChain(childTypeName,visited,indexes);if(cycle){let range=children.find(c=>c.typeNames.includes(childTypeName))?.selectionRange??def.selectionRange;diagnostics.push({severity:import_node11.DiagnosticSeverity.Error,range,message:`Circular containment: ${cycle.join(" -> ")} -> ${cycle[0]}`,source:"sysml",code:"circular-containment"});break}}}return diagnostics}followContainmentChain(typeName,visited,indexes){if(visited.has(typeName))return[...visited];let candidates=indexes.definitionsByName.get(typeName);if(!candidates||candidates.length===0)return;let target=candidates[0],childTypeNames=(indexes.byParent.get(target.qualifiedName)??[]).flatMap(c=>c.typeNames).filter(t=>t.length>0);if(childTypeNames.length!==0){visited.add(typeName);for(let tn of childTypeNames){let cycle=this.followContainmentChain(tn,visited,indexes);if(cycle)return cycle}visited.delete(typeName)}}checkUnsatisfiedRequirements(allSymbols,indexes,workspaceTexts){let diagnostics=[],satisfiedNames,satisfyBlockRanges;if(workspaceTexts){satisfiedNames=new Set,satisfyBlockRanges=new Map;for(let text of workspaceTexts)this.extractSatisfyReferences(text,satisfiedNames),satisfyBlockRanges.set("__static__",this.extractSatisfyBlockRanges(text))}else if(this.documentManager){let uris=this.documentManager.getUris(),versionKey=uris.map(u=>u+":"+this.documentManager.getVersion(u)).join("|");if(this.satisfyCache&&this.satisfyCache.versionKey===versionKey)satisfiedNames=this.satisfyCache.satisfiedNames,satisfyBlockRanges=this.satisfyCache.satisfyBlockRanges;else{let relNames=this.collectWorkspaceRequirementRelationshipNames();satisfiedNames=relNames.satisfiedNames,satisfyBlockRanges=new Map;for(let uri of uris){let text=this.documentManager.getText(uri);text&&satisfyBlockRanges.set(uri,this.extractSatisfyBlockRanges(text))}this.satisfyCache={versionKey,satisfiedNames,satisfyBlockRanges},(!this.verifyCache||this.verifyCache.versionKey!==versionKey)&&(this.verifyCache={versionKey,verifiedNames:relNames.verifiedNames})}}else satisfiedNames=new Set,satisfyBlockRanges=new Map;let requirementUsages=allSymbols.filter(s=>s.kind==="requirement");for(let req of requirementUsages){if(req.parentQualifiedName&&indexes.byQualifiedName.get(req.parentQualifiedName)?.kind==="requirement")continue;let uriRanges=satisfyBlockRanges.get(req.uri)??satisfyBlockRanges.get("__static__")??[],reqLine=req.selectionRange.start.line;if(uriRanges.some(r=>reqLine>=r.startLine&&reqLine<=r.endLine))continue;satisfiedNames.has(req.name)||satisfiedNames.has(req.qualifiedName)||diagnostics.push({severity:import_node11.DiagnosticSeverity.Warning,range:req.selectionRange,message:`Requirement '${req.name}' is not satisfied by any element`,source:"sysml",code:"unsatisfied-requirement",data:{name:req.name,qualifiedName:req.qualifiedName}})}return diagnostics}extractSatisfyReferences(text,out){let stripped=stripComments(text),re=/\bsatisfy\s+(?:requirement\s+)?([\w]+(?:::[\w]+)*)\s+(?:by\b|;|:)/g,m2;for(;(m2=re.exec(stripped))!==null;){let ref=m2[1];out.add(ref);let lastSeg=ref.includes("::")?ref.split("::").pop():ref;out.add(lastSeg)}}extractSatisfyBlockRanges(text){let ranges=[],stripped=stripComments(text),re=/\bsatisfy\b[^;{]*\{/g,m2,lineOffsets;for(;(m2=re.exec(stripped))!==null;){let open=m2.index+m2[0].length-1,depth=1,i=open+1;for(;i<stripped.length&&depth>0;)stripped[i]==="{"&&depth++,stripped[i]==="}"&&depth--,i++;if(depth===0){if(!lineOffsets){lineOffsets=[0];for(let j=0;j<text.length;j++)text[j]===`
144
+ `);for(let i=0;i<lines.length;i++)for(let col of findWordOccurrences(lines[i],oldName)){let range={start:{line:i,character:col},end:{line:i,character:col+oldName.length}};edits.some(e=>e.range.start.line===i&&e.range.start.character===col)||edits.push({range,newText:newName})}return edits.length===0?null:{changes:{[params.textDocument.uri]:edits}}}};var import_node10=__toESM(require_node3());var OPERATOR_TOKENS=new Set([SysMLv2Lexer.BANG_EQ_EQ,SysMLv2Lexer.STAR_STAR,SysMLv2Lexer.COLON_GT,SysMLv2Lexer.COLON_GT_GT,SysMLv2Lexer.AMP,SysMLv2Lexer.COLON_COLON,SysMLv2Lexer.STAR,SysMLv2Lexer.PIPE,SysMLv2Lexer.EQ_EQ,SysMLv2Lexer.BANG_EQ,SysMLv2Lexer.PLUS,SysMLv2Lexer.MINUS,SysMLv2Lexer.ARROW,SysMLv2Lexer.SLASH,SysMLv2Lexer.LT,SysMLv2Lexer.EQ,SysMLv2Lexer.GT,SysMLv2Lexer.CARET,SysMLv2Lexer.TILDE]),PUNCTUATION_TOKENS=new Set([SysMLv2Lexer.LBRACE,SysMLv2Lexer.RBRACE,SysMLv2Lexer.LPAREN,SysMLv2Lexer.RPAREN,SysMLv2Lexer.SEMI,SysMLv2Lexer.COMMA,SysMLv2Lexer.DOT,SysMLv2Lexer.LBRACK,SysMLv2Lexer.RBRACK,SysMLv2Lexer.COLON]),STRUCTURAL_KEYWORDS=new Set(["part","port","item","state","constraint","requirement","concern","case","view","viewpoint","rendering","allocation","connection","interface","occurrence","individual","flow","binding","succession","metadata","enum","actor","subject","ref","use"]),tokenTypes=["namespace","type","class","variable","property","function","keyword","comment","string","number","operator","enum","interface"],tokenModifiers=["declaration","definition","readonly","abstract"],SemanticTokensProvider=class{constructor(documentManager2){this.documentManager=documentManager2}documentManager;tokenCache;provideSemanticTokens(params){let uri=params.textDocument.uri,version=this.documentManager.getVersion(uri);if(this.tokenCache&&this.tokenCache.uri===uri&&this.tokenCache.version===version)return this.tokenCache.tokens;let builder=new import_node10.SemanticTokensBuilder,result=this.documentManager.get(uri);if(!result)return builder.build();result.tokenStream.fill();let tokens=result.tokenStream.getTokens(),prevMeaningful;for(let token of tokens){if(!token.text||token.channel!==0)continue;let text=token.text,tokenType=this.classifyTokenInContext(text,prevMeaningful,token.type);if(prevMeaningful=text,tokenType===void 0)continue;let line=(token.line??1)-1,char=token.column??0,length=text.length;builder.push(line,char,length,tokenType,0)}let built=builder.build();return this.tokenCache={uri,version,tokens:built},built}classifyTokenInContext(text,prev,lexerType){if(lexerType===SysMLv2Lexer.REGULAR_COMMENT||lexerType===SysMLv2Lexer.SINGLE_LINE_NOTE)return 7;if(lexerType===SysMLv2Lexer.STRING||lexerType===SysMLv2Lexer.DOUBLE_STRING)return 8;if(lexerType===SysMLv2Lexer.INTEGER||lexerType===SysMLv2Lexer.REAL)return 9;if(OPERATOR_TOKENS.has(lexerType))return 10;if(!PUNCTUATION_TOKENS.has(lexerType)){if(this.isKeyword(text))return 6;if(lexerType===SysMLv2Lexer.IDENTIFIER)return this.classifyIdentifier(prev)}}classifyIdentifier(prev){return prev?prev==="def"?2:prev==="package"||prev==="namespace"||prev==="library"?0:prev==="action"||prev==="calc"||prev==="analysis"||prev==="verification"?5:prev===":"||prev===":>"||prev===":>>"?1:prev==="attribute"?4:(this.isStructuralKeyword(prev),3):3}isStructuralKeyword(text){return STRUCTURAL_KEYWORDS.has(text)}isKeyword(text){return SYSML_KEYWORDS.has(text)}};var import_node11=__toESM(require_node3());var STANDARD_LIBRARY_TYPES=new Set(["Boolean","String","Integer","Real","Natural","Positive","Complex","Number","Rational","ScalarValues","DataFunctions","Anything","Nothing","Object","Occurrence","Base","Objects","Occurrences","Items","Parts","Ports","Actions","States","Connections","Interfaces","Allocations","Requirements","Constraints","Calculations","Cases","Flows","Transfers","Performances","TransitionPerformances","ISQ","SI","USCustomaryUnits","Quantities","MeasurementReferences","ScalarValues","GeneralView","InterconnectionView","ActionFlowView","StateTransitionView","SequenceView","GeometryView","GridView","BrowserView","StandardViewDefinitions","View","ViewpointCheck","Rendering","TextualRendering","GraphicalRendering","TabularRendering","Views","LengthValue","MassValue","DurationValue","TimeValue","ElectricCurrentValue","ThermodynamicTemperatureValue","TemperatureValue","AmountOfSubstanceValue","LuminousIntensityValue","AreaValue","VolumeValue","SpeedValue","VelocityValue","AccelerationValue","ForceValue","EnergyValue","PowerValue","PressureValue","TorqueValue","MomentOfForceValue","AngularVelocityValue","FrequencyValue","DensityValue","MassFlowRateValue","VolumeFlowRateValue","LengthUnit","MassUnit","DurationUnit","TimeUnit"]),CONSTRAINT_KEYWORDS=new Set(["and","or","not","xor","implies","if","then","else","true","false","null","require","constraint","subject","return","doc","comment","assert","assume"]);function isISQValueType(name){if(!name.endsWith("Value")||name.length<6)return!1;let ch0=name.charCodeAt(0);if(ch0<65||ch0>90)return!1;for(let i=1;i<name.length;i++){let c=name.charCodeAt(i);if(!(c>=65&&c<=90||c>=97&&c<=122))return!1}return!0}var SemanticValidator=class _SemanticValidator{constructor(documentManager2){this.documentManager=documentManager2;this.modelProvider=new SysMLModelProvider(documentManager2)}documentManager;modelProvider;satisfyCache;verifyCache;indexCache;symbolNamesCache;libraryNamesCache;addRequirementNameVariants(out,ref){if(!ref)return;let trimmed=ref.trim();if(!trimmed)return;out.add(trimmed);let lastSeg=trimmed.includes("::")?trimmed.split("::").pop():trimmed;out.add(lastSeg)}collectWorkspaceRequirementRelationshipNames(){let satisfiedNames=new Set,verifiedNames=new Set,uris=this.documentManager.getUris();for(let uri of uris){let version=this.documentManager.getVersion(uri);if(version<0)continue;let rels=this.modelProvider.getModel(uri,version,["relationships"]).relationships??[];for(let rel of rels)rel.type==="satisfy"?this.addRequirementNameVariants(satisfiedNames,rel.target):rel.type==="verify"&&this.addRequirementNameVariants(verifiedNames,rel.target)}return{satisfiedNames,verifiedNames}}validate(uri){let symbolTable=this.documentManager.getWorkspaceSymbolTable(),symbols=symbolTable.getSymbolsForUri(uri);if(symbols.length===0)return[];let allSymbols=symbolTable.getAllSymbols(),allSymbolNames;this.symbolNamesCache&&this.symbolNamesCache.symbols===allSymbols?allSymbolNames=this.symbolNamesCache.names:(allSymbolNames=new Set(allSymbols.map(s=>s.name)),this.symbolNamesCache={symbols:allSymbols,names:allSymbolNames}),this.libraryNamesCache||(this.libraryNamesCache=new Set(getLibraryPackageNames()));let libraryNames=this.libraryNamesCache,text=this.documentManager.getText(uri)??"",indexes=this.getOrBuildIndexes(allSymbols),diagnostics=[];for(let symbol of symbols)diagnostics.push(...this.checkUnresolvedType(symbol,allSymbolNames,libraryNames),...this.checkInvalidMultiplicity(symbol),...this.checkEmptyEnum(symbol,symbols),...this.checkNamingConvention(symbol),...this.checkMissingDocumentation(symbol));return diagnostics.push(...this.checkDuplicateDefinitions(symbols)),diagnostics.push(...this.checkUnusedDefinitions(allSymbols,uri)),diagnostics.push(...this.checkRedefinitionMultiplicity(symbols,indexes,text)),diagnostics.push(...this.checkPortCompatibility(text,uri,indexes)),diagnostics.push(...this.checkConstraintBodyReferences(text,uri,symbols,indexes)),diagnostics.push(...this.checkCircularSpecialization(symbols,indexes)),diagnostics.push(...this.checkUnsatisfiedRequirements(symbols,indexes)),diagnostics.push(...this.checkUnverifiedRequirements(symbols,indexes)),diagnostics.push(...this.checkViewpointSatisfaction(symbols,indexes)),this.dedupeDiagnostics(diagnostics)}checkUnresolvedType(symbol,allSymbolNames,libraryNames){if(!symbol.typeName)return[];let typeName=symbol.typeName,kwMatch=typeName.match(/^([A-Z][A-Za-z_0-9]*?)(redefines|subsets|references|connect|bind|default|via|accept|send|flow|allocate|assign|decide|merge|join|fork)([A-Z])/);kwMatch&&(typeName=kwMatch[1]);let rootSegment=typeName.split("::")[0];if(allSymbolNames.has(typeName)||allSymbolNames.has(rootSegment)||STANDARD_LIBRARY_TYPES.has(typeName)||STANDARD_LIBRARY_TYPES.has(rootSegment)||libraryNames.has(rootSegment)||isISQValueType(typeName)||resolveLibraryType(typeName)!==void 0||resolveLibraryType(rootSegment)!==void 0||typeName.charCodeAt(0)>=97&&typeName.charCodeAt(0)<=122)return[];let isMandatory=symbol.multiplicityRange&&symbol.multiplicityRange.lower>=1,severity=isMandatory?import_node11.DiagnosticSeverity.Error:import_node11.DiagnosticSeverity.Warning,message=`Type '${typeName}' is not defined in the current document or standard library`;if(isMandatory){let multStr=symbol.multiplicity??"1";message+=` (feature '${symbol.name}' requires multiplicity [${multStr}])`}return[{severity,range:symbol.selectionRange,message,source:"sysml",code:"unresolved-type",data:{typeName}}]}checkInvalidMultiplicity(symbol){if(!symbol.multiplicityRange||!symbol.multiplicity)return[];let{lower,upper}=symbol.multiplicityRange;return typeof upper=="number"&&lower>upper?[{severity:import_node11.DiagnosticSeverity.Error,range:symbol.selectionRange,message:`Invalid multiplicity [${symbol.multiplicity}]: lower bound (${lower}) exceeds upper bound (${upper})`,source:"sysml",code:"invalid-multiplicity"}]:lower<0?[{severity:import_node11.DiagnosticSeverity.Error,range:symbol.selectionRange,message:`Invalid multiplicity [${symbol.multiplicity}]: lower bound cannot be negative`,source:"sysml",code:"invalid-multiplicity"}]:[]}checkEmptyEnum(symbol,allSymbols){return symbol.kind!=="enum def"?[]:allSymbols.filter(s=>s.parentQualifiedName===symbol.qualifiedName).some(c=>c.kind==="enum"||c.kind==="attribute")?[]:[{severity:import_node11.DiagnosticSeverity.Information,range:symbol.selectionRange,message:`Enumeration '${symbol.name}' has no enum values defined`,source:"sysml",code:"empty-enum"}]}checkNamingConvention(symbol){if(!symbol.name)return[];if(symbol.kind==="package"||symbol.kind==="import"||symbol.kind==="comment"||symbol.kind==="doc"||symbol.kind==="alias"||symbol.kind==="unknown")return[];if(isDefinition(symbol.kind)){let ch=symbol.name[0];if(ch===ch.toLowerCase()&&ch!==ch.toUpperCase())return[{severity:import_node11.DiagnosticSeverity.Hint,range:symbol.selectionRange,message:`Definition '${symbol.name}' should use PascalCase`,source:"sysml",code:"naming-convention",data:{name:symbol.name,convention:"PascalCase"}}]}else{let ch=symbol.name[0];if(ch===ch.toUpperCase()&&ch!==ch.toLowerCase())return[{severity:import_node11.DiagnosticSeverity.Hint,range:symbol.selectionRange,message:`Usage '${symbol.name}' should use camelCase`,source:"sysml",code:"naming-convention",data:{name:symbol.name,convention:"camelCase"}}]}return[]}checkMissingDocumentation(symbol){return isDefinition(symbol.kind)?symbol.documentation?[]:[{severity:import_node11.DiagnosticSeverity.Information,range:symbol.selectionRange,message:`Definition '${symbol.name}' has no documentation`,source:"sysml",code:"missing-doc",data:{name:symbol.name}}]:[]}checkUnusedDefinitions(symbols,targetUri){let defs=symbols.filter(s=>s.kind==="part def"||s.kind==="action def"),defsInScope=targetUri?defs.filter(def=>def.uri===targetUri):defs,referencedTypes=new Set(symbols.filter(s=>s.kind!=="package").flatMap(s=>s.typeNames));for(let s of symbols)if(s.exposeTargets)for(let target of s.exposeTargets){let simpleName=target.replace(/::\*{1,2}$/,"").split("::").pop();simpleName&&referencedTypes.add(simpleName)}let diagnostics=[];for(let def of defsInScope){let isReferenced=referencedTypes.has(def.name),hasBaseType=(def.typeNames?.length??0)>0;!isReferenced&&!hasBaseType&&diagnostics.push({severity:import_node11.DiagnosticSeverity.Warning,range:def.selectionRange,message:`Definition '${def.name}' is not referenced by any usage in the workspace`,source:"sysml",code:"unused-definition",data:{name:def.name}})}return diagnostics}static validateSymbols(symbolsInUri,allNames,opts){let diagnostics=[],instance=Object.create(_SemanticValidator.prototype),allSymbols=opts?.allSymbols??symbolsInUri,includeStyleRules=opts?.includeStyleRules??!0,indexes=instance.buildSymbolIndexes(allSymbols);for(let symbol of symbolsInUri)diagnostics.push(...instance.checkUnresolvedType(symbol,allNames,new Set),...instance.checkInvalidMultiplicity(symbol),...instance.checkEmptyEnum(symbol,symbolsInUri)),includeStyleRules&&diagnostics.push(...instance.checkNamingConvention(symbol),...instance.checkMissingDocumentation(symbol));return diagnostics.push(...instance.checkDuplicateDefinitions(symbolsInUri)),diagnostics.push(...instance.checkUnusedDefinitions(allSymbols)),diagnostics.push(...instance.checkRedefinitionMultiplicity(symbolsInUri,indexes,opts?.text)),diagnostics.push(...instance.checkCircularSpecialization(symbolsInUri,indexes)),diagnostics.push(...instance.checkUnsatisfiedRequirements(allSymbols,indexes,opts?.text?[opts.text]:[])),diagnostics.push(...instance.checkUnverifiedRequirements(allSymbols,indexes,opts?.text?[opts.text]:[])),opts?.text&&opts.uri&&(diagnostics.push(...instance.checkPortCompatibility(opts.text,opts.uri,indexes)),diagnostics.push(...instance.checkConstraintBodyReferences(opts.text,opts.uri,symbolsInUri,indexes))),instance.dedupeDiagnostics(diagnostics)}checkCircularSpecialization(symbolsInUri,indexes){let diagnostics=[],defsInFile=symbolsInUri.filter(s=>isDefinition(s.kind)&&s.typeNames.length>0);for(let def of defsInFile){let visited=new Set;visited.add(def.name);let cycle=this.followSpecializationChain(def.name,def.typeNames,visited,indexes);cycle&&diagnostics.push({severity:import_node11.DiagnosticSeverity.Error,range:def.selectionRange,message:`Circular specialization: ${cycle.join(" :> ")} :> ${cycle[0]}`,source:"sysml",code:"circular-specialization"})}return diagnostics}followSpecializationChain(originName,typeNames,visited,indexes){for(let tn of typeNames){if(visited.has(tn))return[...visited];let candidates=indexes.definitionsByName.get(tn);if(!candidates||candidates.length===0)continue;let target=candidates[0];if(target.typeNames.length===0)continue;visited.add(tn);let cycle=this.followSpecializationChain(originName,target.typeNames,visited,indexes);if(cycle)return cycle;visited.delete(tn)}}checkUnsatisfiedRequirements(allSymbols,indexes,workspaceTexts){let diagnostics=[],satisfiedNames,satisfyBlockRanges;if(workspaceTexts){satisfiedNames=new Set,satisfyBlockRanges=new Map;for(let text of workspaceTexts)this.extractSatisfyReferences(text,satisfiedNames),satisfyBlockRanges.set("__static__",this.extractSatisfyBlockRanges(text))}else if(this.documentManager){let uris=this.documentManager.getUris(),versionKey=uris.map(u=>u+":"+this.documentManager.getVersion(u)).join("|");if(this.satisfyCache&&this.satisfyCache.versionKey===versionKey)satisfiedNames=this.satisfyCache.satisfiedNames,satisfyBlockRanges=this.satisfyCache.satisfyBlockRanges;else{let relNames=this.collectWorkspaceRequirementRelationshipNames();satisfiedNames=relNames.satisfiedNames,satisfyBlockRanges=new Map;for(let uri of uris){let text=this.documentManager.getText(uri);text&&satisfyBlockRanges.set(uri,this.extractSatisfyBlockRanges(text))}this.satisfyCache={versionKey,satisfiedNames,satisfyBlockRanges},(!this.verifyCache||this.verifyCache.versionKey!==versionKey)&&(this.verifyCache={versionKey,verifiedNames:relNames.verifiedNames})}}else satisfiedNames=new Set,satisfyBlockRanges=new Map;let requirementUsages=allSymbols.filter(s=>s.kind==="requirement");for(let req of requirementUsages){if(req.parentQualifiedName&&indexes.byQualifiedName.get(req.parentQualifiedName)?.kind==="requirement")continue;let uriRanges=satisfyBlockRanges.get(req.uri)??satisfyBlockRanges.get("__static__")??[],reqLine=req.selectionRange.start.line;if(uriRanges.some(r=>reqLine>=r.startLine&&reqLine<=r.endLine))continue;satisfiedNames.has(req.name)||satisfiedNames.has(req.qualifiedName)||diagnostics.push({severity:import_node11.DiagnosticSeverity.Warning,range:req.selectionRange,message:`Requirement '${req.name}' is not satisfied by any element`,source:"sysml",code:"unsatisfied-requirement",data:{name:req.name,qualifiedName:req.qualifiedName}})}return diagnostics}extractSatisfyReferences(text,out){let stripped=stripComments(text),re=/\bsatisfy\s+(?:requirement\s+)?([\w]+(?:::[\w]+)*)\s+(?:by\b|;|:)/g,m2;for(;(m2=re.exec(stripped))!==null;){let ref=m2[1];out.add(ref);let lastSeg=ref.includes("::")?ref.split("::").pop():ref;out.add(lastSeg)}}extractSatisfyBlockRanges(text){let ranges=[],stripped=stripComments(text),re=/\bsatisfy\b[^;{]*\{/g,m2,lineOffsets;for(;(m2=re.exec(stripped))!==null;){let open=m2.index+m2[0].length-1,depth=1,i=open+1;for(;i<stripped.length&&depth>0;)stripped[i]==="{"&&depth++,stripped[i]==="}"&&depth--,i++;if(depth===0){if(!lineOffsets){lineOffsets=[0];for(let j=0;j<text.length;j++)text[j]===`
145
145
  `&&lineOffsets.push(j+1)}ranges.push({startLine:this.offsetToLine(lineOffsets,open),endLine:this.offsetToLine(lineOffsets,i-1)})}}return ranges}checkUnverifiedRequirements(allSymbols,indexes,workspaceTexts){let diagnostics=[],satisfiedNames,verifiedNames,satisfyBlockRanges;if(workspaceTexts){satisfiedNames=new Set,verifiedNames=new Set,satisfyBlockRanges=new Map;for(let text of workspaceTexts)this.extractSatisfyReferences(text,satisfiedNames),this.extractVerifyReferences(text,verifiedNames),satisfyBlockRanges.set("__static__",this.extractSatisfyBlockRanges(text))}else if(this.documentManager){let uris=this.documentManager.getUris(),versionKey=uris.map(u=>u+":"+this.documentManager.getVersion(u)).join("|"),satisfyCacheValid=this.satisfyCache&&this.satisfyCache.versionKey===versionKey,verifyCacheValid=this.verifyCache&&this.verifyCache.versionKey===versionKey;if(!satisfyCacheValid||!verifyCacheValid){let relNames=this.collectWorkspaceRequirementRelationshipNames();if(!satisfyCacheValid){satisfyBlockRanges=new Map;for(let uri of uris){let text=this.documentManager.getText(uri);text&&satisfyBlockRanges.set(uri,this.extractSatisfyBlockRanges(text))}this.satisfyCache={versionKey,satisfiedNames:relNames.satisfiedNames,satisfyBlockRanges}}verifyCacheValid||(this.verifyCache={versionKey,verifiedNames:relNames.verifiedNames})}satisfiedNames=this.satisfyCache.satisfiedNames,satisfyBlockRanges=this.satisfyCache.satisfyBlockRanges,verifiedNames=this.verifyCache.verifiedNames}else satisfiedNames=new Set,verifiedNames=new Set,satisfyBlockRanges=new Map;let requirementUsages=allSymbols.filter(s=>s.kind==="requirement");for(let req of requirementUsages){if(req.parentQualifiedName&&indexes.byQualifiedName.get(req.parentQualifiedName)?.kind==="requirement")continue;let uriRanges=satisfyBlockRanges.get(req.uri)??satisfyBlockRanges.get("__static__")??[],reqLine=req.selectionRange.start.line;if(uriRanges.some(r=>reqLine>=r.startLine&&reqLine<=r.endLine))continue;let isSatisfied=satisfiedNames.has(req.name)||satisfiedNames.has(req.qualifiedName);if(!(verifiedNames.has(req.name)||verifiedNames.has(req.qualifiedName))){let message=isSatisfied?`Requirement '${req.name}' is satisfied but has no verification case \u2014 consider adding: verify ${req.name} by <VerificationCase>;`:`Requirement '${req.name}' has no verification case \u2014 consider adding: verify ${req.name} by <VerificationCase>;`;diagnostics.push({severity:import_node11.DiagnosticSeverity.Warning,range:req.selectionRange,message,source:"sysml",code:"unverified-requirement",data:{name:req.name,qualifiedName:req.qualifiedName}})}}return diagnostics}extractVerifyReferences(text,out){let stripped=stripComments(text),re=/\bverify\s+(?:requirement\s+)?([\w]+(?:::[\w]+)*)\s*(?:by\b|;|:|\{)/g,m2;for(;(m2=re.exec(stripped))!==null;){let ref=m2[1];out.add(ref);let lastSeg=ref.includes("::")?ref.split("::").pop():ref;out.add(lastSeg)}}offsetToLine(lineOffsets,offset){let lo=0,hi=lineOffsets.length-1;for(;lo<hi;){let mid=lo+hi+1>>>1;lineOffsets[mid]<=offset?lo=mid:hi=mid-1}return lo}checkViewpointSatisfaction(symbols,_indexes){let diagnostics=[],views=symbols.filter(s=>s.kind==="view"),_viewpointNames=new Set(symbols.filter(s=>s.kind==="viewpoint def"||s.kind==="viewpoint").map(s=>s.name));for(let view of views){let hasExpose=view.exposeTargets&&view.exposeTargets.length>0,hasFilter=view.viewFilters&&view.viewFilters.length>0;!hasExpose&&!hasFilter&&diagnostics.push({severity:import_node11.DiagnosticSeverity.Information,range:view.selectionRange,message:`View '${view.name}' has no expose or filter directives \u2014 it will show all elements`,source:"sysml",code:"view-no-scope"})}return diagnostics}checkRedefinitionMultiplicity(symbolsInUri,indexes,text){let diagnostics=[],lines=text?.split(`
146
146
  `);for(let s of symbolsInUri){if(!s.typeName||!s.multiplicityRange)continue;let c0=s.typeName.charCodeAt(0);if(!(c0>=97&&c0<=122))continue;if(lines){let lineIdx=s.selectionRange.start.line,line=lines[lineIdx]||"";if(!/:>>/.test(line)&&!/\bredefines\b/.test(line))continue}let base=(indexes.byName.get(s.typeName)??[]).find(c=>!!c.multiplicityRange);if(!base?.multiplicityRange)continue;let baseLower=base.multiplicityRange.lower,baseUpper=base.multiplicityRange.upper,curLower=s.multiplicityRange.lower,curUpper=s.multiplicityRange.upper,lowerOk=curLower>=baseLower,upperOk=baseUpper==="*"||curUpper!=="*"&&curUpper<=baseUpper;lowerOk&&upperOk||diagnostics.push({severity:import_node11.DiagnosticSeverity.Error,range:s.selectionRange,message:`Redefinition multiplicity [${s.multiplicity??"?"}] is incompatible with base '${base.name}' multiplicity [${base.multiplicity??"?"}]`,source:"sysml",code:"invalid-redefinition-multiplicity"})}return diagnostics}checkPortCompatibility(text,uri,indexes){if(!text)return[];let diagnostics=[],lines=text.split(`
147
147
  `),re=/\bconnect\s+([A-Za-z_][\w.]*)\s+to\s+([A-Za-z_][\w.]*)/g,m2;for(;(m2=re.exec(text))!==null;){let left=m2[1].split(".").pop(),right=m2[2].split(".").pop(),lSym=(indexes.portsByName.get(left)??[])[0],rSym=(indexes.portsByName.get(right)??[])[0];if(!lSym||!rSym)continue;let lType=lSym.typeNames[0]??lSym.typeName,rType=rSym.typeNames[0]??rSym.typeName;if(!lType||!rType||lType===rType||lType==="~"+rType||rType==="~"+lType||lType.startsWith("~")&&lType.slice(1)===rType||rType.startsWith("~")&&rType.slice(1)===lType)continue;let matchLine=text.substring(0,m2.index).split(`
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "sysml-v2-lsp",
3
3
  "displayName": "SysML v2 Language Server",
4
4
  "description": "Language Server Protocol implementation for SysML v2, powered by ANTLR4",
5
- "version": "0.26.0",
5
+ "version": "0.27.0",
6
6
  "publisher": "JamieD",
7
7
  "license": "MIT",
8
8
  "repository": {